FileBackedOutputStreamTest.java revision 1d580d0f6ee4f21eb309ba7b509d2c6d671c4044
1ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org/*
248dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang * Copyright (C) 2008 The Guava Authors
3ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org *
4ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org * Licensed under the Apache License, Version 2.0 (the "License");
5ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org * you may not use this file except in compliance with the License.
6ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org * You may obtain a copy of the License at
7ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org *
8ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org * http://www.apache.org/licenses/LICENSE-2.0
9ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org *
10ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org * Unless required by applicable law or agreed to in writing, software
11ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org * distributed under the License is distributed on an "AS IS" BASIS,
12ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com * See the License for the specific language governing permissions and
14d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com * limitations under the License.
15a2ecfcccf1d1a85e6054a7314ce1f9de0648ac7fshannonwoods@chromium.org */
1615186aa7049f5b39916f93631a2de3f1c2e7545ddaniel@transgaming.com
17d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.compackage com.google.common.io;
18486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com
19c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jonesimport com.google.common.testing.GcFinalization;
20d8d72434e51896c79b117229624ffed341da89a6Brandon Jones
21ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.orgimport java.io.File;
220b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Langimport java.io.IOException;
230b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Langimport java.io.InputStream;
240b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Langimport java.io.OutputStream;
250b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Langimport java.util.Arrays;
260b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang
27bf9cce2e2bc354c07eed0f768e1f3e03278e5da4Jamie Madill/**
28bf9cce2e2bc354c07eed0f768e1f3e03278e5da4Jamie Madill * Unit tests for {@link FileBackedOutputStream}.
29bf9cce2e2bc354c07eed0f768e1f3e03278e5da4Jamie Madill *
30bf9cce2e2bc354c07eed0f768e1f3e03278e5da4Jamie Madill * @author Chris Nokleberg
31bf9cce2e2bc354c07eed0f768e1f3e03278e5da4Jamie Madill */
320b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Langpublic class FileBackedOutputStreamTest extends IoTestCase {
330b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang
340b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang  public void testThreshold() throws Exception {
350b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang    testThreshold(0, 100, true, false);
360b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang    testThreshold(10, 100, true, false);
370b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang    testThreshold(100, 100, true, false);
380b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang    testThreshold(1000, 100, true, false);
39d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com    testThreshold(0, 100, false, false);
40d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com    testThreshold(10, 100, false, false);
41d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com    testThreshold(100, 100, false, false);
42d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com    testThreshold(1000, 100, false, false);
430b60014ba3b6688614cdc8b7396b7d0a3db68db2shannon.woods@transgaming.com  }
448ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill
45d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com  public void testFinalizeDeletesFile() throws Exception {
46a9c7142435f100d43684a0efe8894cbe42ee8fccdaniel@transgaming.com    byte[] data = newPreFilledByteArray(100);
47ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    FileBackedOutputStream out = new FileBackedOutputStream(0, true);
48ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org
497162096ee6cfcb0fa797eb3503154f39ec53ef09Brandon Jones    write(out, data, 0, 100, true);
50d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com    final File file = out.getFile();
51d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com    assertEquals(100, file.length());
521bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org    assertTrue(file.exists());
5304fb89ad059cba1fbd14507fe58c9a700fe0de08Geoff Lang    out.close();
54ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org
55ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    // Make sure that finalize deletes the file
5663491eae7cce075afbbea3caed173bd234fa4cd9Jamie Madill    out = null;
57ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org
5863491eae7cce075afbbea3caed173bd234fa4cd9Jamie Madill    // times out and throws RuntimeException on failure
5990080e3b703883b871f862d5ceafa44d2d815b6aapatrick@chromium.org    GcFinalization.awaitDone(new GcFinalization.FinalizationPredicate() {
6090080e3b703883b871f862d5ceafa44d2d815b6aapatrick@chromium.org      @Override
6190080e3b703883b871f862d5ceafa44d2d815b6aapatrick@chromium.org      public boolean isDone() {
6263491eae7cce075afbbea3caed173bd234fa4cd9Jamie Madill        return !file.exists();
63ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org      }
64ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    });
65ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org  }
66ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org
67ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org  public void testThreshold_resetOnFinalize() throws Exception {
68ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    testThreshold(0, 100, true, true);
6948dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    testThreshold(10, 100, true, true);
7048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    testThreshold(100, 100, true, true);
7148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    testThreshold(1000, 100, true, true);
7248dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    testThreshold(0, 100, false, true);
7348dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    testThreshold(10, 100, false, true);
7448dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    testThreshold(100, 100, false, true);
7548dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    testThreshold(1000, 100, false, true);
7648dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang  }
7748dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang
7848dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang  private void testThreshold(int fileThreshold, int dataSize, boolean singleByte,
7948dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang      boolean resetOnFinalize) throws IOException {
8048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    byte[] data = newPreFilledByteArray(dataSize);
8148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    FileBackedOutputStream out = new FileBackedOutputStream(fileThreshold, resetOnFinalize);
8248dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    InputSupplier<InputStream> supplier = out.getSupplier();
8348dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    int chunk1 = Math.min(dataSize, fileThreshold);
8448dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    int chunk2 = dataSize - chunk1;
8548dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang
8648dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    // Write just enough to not trip the threshold
87ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    if (chunk1 > 0) {
88989c1c85b82277de2b080c0ce2174a668e1b96badaniel@transgaming.com      write(out, data, 0, chunk1, singleByte);
89ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org      assertTrue(ByteStreams.equal(
90ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org          ByteStreams.newInputStreamSupplier(data, 0, chunk1), supplier));
9170062c98f7c62744f398dc0ba7a87c76e723cc48daniel@transgaming.com    }
92ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    File file = out.getFile();
93ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    assertNull(file);
9404fb89ad059cba1fbd14507fe58c9a700fe0de08Geoff Lang
9504fb89ad059cba1fbd14507fe58c9a700fe0de08Geoff Lang    // Write data to go over the threshold
96834e8b7715c25e299c07c9d63f5be0a0ee6c5856Jamie Madill    if (chunk2 > 0) {
978ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill      write(out, data, chunk1, chunk2, singleByte);
98ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org      file = out.getFile();
99ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org      assertEquals(dataSize, file.length());
100ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org      assertTrue(file.exists());
101ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    }
102ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    out.close();
103ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org
104ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    // Check that supplier returns the right data
105087e57890abbf89bc36e8769abdb1354ba6aeb06daniel@transgaming.com    assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier)));
1063e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com
1073e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com    // Make sure that reset deleted the file
108ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    out.reset();
109ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    if (file != null) {
110c2ed991c7d844ff347ab4ce5945843a39f3bea47shannonwoods@chromium.org      assertFalse(file.exists());
1114276625286ffa9f4f481e721e8df51844036ea76shannonwoods@chromium.org    }
1123639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill  }
1133639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill
1143639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill  private static void write(
1153639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill      OutputStream out, byte[] b, int off, int len, boolean singleByte)
1163639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill      throws IOException {
1173639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    if (singleByte) {
1183639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill      for (int i = off; i < off + len; i++) {
1193639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill        out.write(b[i]);
1203639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill      }
1213639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    } else {
1223639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill      out.write(b, off, len);
1233639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    }
1243639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    out.flush(); // for coverage
1253639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill  }
1263639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill
1273639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill  // TODO(chrisn): only works if we ensure we have crossed file threshold
1283639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill
1293639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill  public void testWriteErrorAfterClose() throws Exception {
1303639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    byte[] data = newPreFilledByteArray(100);
1313639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    FileBackedOutputStream out = new FileBackedOutputStream(50);
1323639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    InputSupplier<InputStream> supplier = out.getSupplier();
133ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org
13499a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill    out.write(data);
13599a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill    assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier)));
13699a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill
137ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    out.close();
138ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    try {
139ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org      out.write(42);
140834e8b7715c25e299c07c9d63f5be0a0ee6c5856Jamie Madill      fail("expected exception");
141ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    } catch (IOException expected) {
142900013cd6b1d0ed2cdc5ee5ca0f4210624b0d8efGeoff Lang      // expected
143900013cd6b1d0ed2cdc5ee5ca0f4210624b0d8efGeoff Lang    }
14490080e3b703883b871f862d5ceafa44d2d815b6aapatrick@chromium.org
14590080e3b703883b871f862d5ceafa44d2d815b6aapatrick@chromium.org    // Verify that write had no effect
1467162096ee6cfcb0fa797eb3503154f39ec53ef09Brandon Jones    assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier)));
14748dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    out.reset();
148ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org  }
149ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org
1504f4215f7d79cc4db6beecd49995ffbd6e9dd490ashannon.woods@transgaming.com  public void testReset() throws Exception {
1514f4215f7d79cc4db6beecd49995ffbd6e9dd490ashannon.woods@transgaming.com    byte[] data = newPreFilledByteArray(100);
1524f4215f7d79cc4db6beecd49995ffbd6e9dd490ashannon.woods@transgaming.com    FileBackedOutputStream out = new FileBackedOutputStream(Integer.MAX_VALUE);
153ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    InputSupplier<InputStream> supplier = out.getSupplier();
1544f4215f7d79cc4db6beecd49995ffbd6e9dd490ashannon.woods@transgaming.com
1554f4215f7d79cc4db6beecd49995ffbd6e9dd490ashannon.woods@transgaming.com    out.write(data);
1564f4215f7d79cc4db6beecd49995ffbd6e9dd490ashannon.woods@transgaming.com    assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier)));
1572a9a9d232cee3c1d75384de834c0508c9cf2ab99shannonwoods@chromium.org
1583639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    out.reset();
1593639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    assertTrue(Arrays.equals(new byte[0], ByteStreams.toByteArray(supplier)));
16066d43d24c7560d5812e1adc3491578a783379c9fJamie Madill
161ea09f9b400d2ef6d2761e0a81471ee5221995a13apatrick@chromium.org    out.write(data);
162beb027831595253a2eeadebb3e577f10e62f73f7shannonwoods@chromium.org    assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier)));
163e7317ca8472c363510025c4c8c57682fcbc7f7d6shannonwoods@chromium.org
16470eb1ea25dbb03783fcee104314df6f2ba6a2dccshannonwoods@chromium.org    out.close();
165e684b58a3d326fceb649ef5304a293dbfd643dbashannonwoods@chromium.org  }
1661bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org}
16770eb1ea25dbb03783fcee104314df6f2ba6a2dccshannonwoods@chromium.org