Home | History | Annotate | Download | only in io
      1 /*
      2  * Copyright (C) 2008 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.io;
     18 
     19 import com.google.common.testing.GcFinalization;
     20 
     21 import java.io.File;
     22 import java.io.IOException;
     23 import java.io.InputStream;
     24 import java.io.OutputStream;
     25 import java.util.Arrays;
     26 
     27 /**
     28  * Unit tests for {@link FileBackedOutputStream}.
     29  *
     30  * @author Chris Nokleberg
     31  */
     32 public class FileBackedOutputStreamTest extends IoTestCase {
     33 
     34   public void testThreshold() throws Exception {
     35     testThreshold(0, 100, true, false);
     36     testThreshold(10, 100, true, false);
     37     testThreshold(100, 100, true, false);
     38     testThreshold(1000, 100, true, false);
     39     testThreshold(0, 100, false, false);
     40     testThreshold(10, 100, false, false);
     41     testThreshold(100, 100, false, false);
     42     testThreshold(1000, 100, false, false);
     43   }
     44 
     45   public void testFinalizeDeletesFile() throws Exception {
     46     byte[] data = newPreFilledByteArray(100);
     47     FileBackedOutputStream out = new FileBackedOutputStream(0, true);
     48 
     49     write(out, data, 0, 100, true);
     50     final File file = out.getFile();
     51     assertEquals(100, file.length());
     52     assertTrue(file.exists());
     53     out.close();
     54 
     55     // Make sure that finalize deletes the file
     56     out = null;
     57 
     58     // times out and throws RuntimeException on failure
     59     GcFinalization.awaitDone(new GcFinalization.FinalizationPredicate() {
     60       @Override
     61       public boolean isDone() {
     62         return !file.exists();
     63       }
     64     });
     65   }
     66 
     67   public void testThreshold_resetOnFinalize() throws Exception {
     68     testThreshold(0, 100, true, true);
     69     testThreshold(10, 100, true, true);
     70     testThreshold(100, 100, true, true);
     71     testThreshold(1000, 100, true, true);
     72     testThreshold(0, 100, false, true);
     73     testThreshold(10, 100, false, true);
     74     testThreshold(100, 100, false, true);
     75     testThreshold(1000, 100, false, true);
     76   }
     77 
     78   private void testThreshold(int fileThreshold, int dataSize, boolean singleByte,
     79       boolean resetOnFinalize) throws IOException {
     80     byte[] data = newPreFilledByteArray(dataSize);
     81     FileBackedOutputStream out = new FileBackedOutputStream(fileThreshold, resetOnFinalize);
     82     InputSupplier<InputStream> supplier = out.getSupplier();
     83     int chunk1 = Math.min(dataSize, fileThreshold);
     84     int chunk2 = dataSize - chunk1;
     85 
     86     // Write just enough to not trip the threshold
     87     if (chunk1 > 0) {
     88       write(out, data, 0, chunk1, singleByte);
     89       assertTrue(ByteStreams.equal(
     90           ByteStreams.newInputStreamSupplier(data, 0, chunk1), supplier));
     91     }
     92     File file = out.getFile();
     93     assertNull(file);
     94 
     95     // Write data to go over the threshold
     96     if (chunk2 > 0) {
     97       write(out, data, chunk1, chunk2, singleByte);
     98       file = out.getFile();
     99       assertEquals(dataSize, file.length());
    100       assertTrue(file.exists());
    101     }
    102     out.close();
    103 
    104     // Check that supplier returns the right data
    105     assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier)));
    106 
    107     // Make sure that reset deleted the file
    108     out.reset();
    109     if (file != null) {
    110       assertFalse(file.exists());
    111     }
    112   }
    113 
    114   private static void write(
    115       OutputStream out, byte[] b, int off, int len, boolean singleByte)
    116       throws IOException {
    117     if (singleByte) {
    118       for (int i = off; i < off + len; i++) {
    119         out.write(b[i]);
    120       }
    121     } else {
    122       out.write(b, off, len);
    123     }
    124     out.flush(); // for coverage
    125   }
    126 
    127   // TODO(chrisn): only works if we ensure we have crossed file threshold
    128 
    129   public void testWriteErrorAfterClose() throws Exception {
    130     byte[] data = newPreFilledByteArray(100);
    131     FileBackedOutputStream out = new FileBackedOutputStream(50);
    132     InputSupplier<InputStream> supplier = out.getSupplier();
    133 
    134     out.write(data);
    135     assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier)));
    136 
    137     out.close();
    138     try {
    139       out.write(42);
    140       fail("expected exception");
    141     } catch (IOException expected) {
    142       // expected
    143     }
    144 
    145     // Verify that write had no effect
    146     assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier)));
    147     out.reset();
    148   }
    149 
    150   public void testReset() throws Exception {
    151     byte[] data = newPreFilledByteArray(100);
    152     FileBackedOutputStream out = new FileBackedOutputStream(Integer.MAX_VALUE);
    153     InputSupplier<InputStream> supplier = out.getSupplier();
    154 
    155     out.write(data);
    156     assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier)));
    157 
    158     out.reset();
    159     assertTrue(Arrays.equals(new byte[0], ByteStreams.toByteArray(supplier)));
    160 
    161     out.write(data);
    162     assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier)));
    163 
    164     out.close();
    165   }
    166 }
    167