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.OutputStream;
     24 import java.util.Arrays;
     25 
     26 /**
     27  * Unit tests for {@link FileBackedOutputStream}.
     28  *
     29  * @author Chris Nokleberg
     30  */
     31 public class FileBackedOutputStreamTest extends IoTestCase {
     32 
     33   public void testThreshold() throws Exception {
     34     testThreshold(0, 100, true, false);
     35     testThreshold(10, 100, true, false);
     36     testThreshold(100, 100, true, false);
     37     testThreshold(1000, 100, true, false);
     38     testThreshold(0, 100, false, false);
     39     testThreshold(10, 100, false, false);
     40     testThreshold(100, 100, false, false);
     41     testThreshold(1000, 100, false, false);
     42   }
     43 
     44   public void testFinalizeDeletesFile() throws Exception {
     45     byte[] data = newPreFilledByteArray(100);
     46     FileBackedOutputStream out = new FileBackedOutputStream(0, true);
     47 
     48     write(out, data, 0, 100, true);
     49     final File file = out.getFile();
     50     assertEquals(100, file.length());
     51     assertTrue(file.exists());
     52     out.close();
     53 
     54     // Make sure that finalize deletes the file
     55     out = null;
     56 
     57     // times out and throws RuntimeException on failure
     58     GcFinalization.awaitDone(new GcFinalization.FinalizationPredicate() {
     59       @Override
     60       public boolean isDone() {
     61         return !file.exists();
     62       }
     63     });
     64   }
     65 
     66   public void testThreshold_resetOnFinalize() throws Exception {
     67     testThreshold(0, 100, true, true);
     68     testThreshold(10, 100, true, true);
     69     testThreshold(100, 100, true, true);
     70     testThreshold(1000, 100, true, true);
     71     testThreshold(0, 100, false, true);
     72     testThreshold(10, 100, false, true);
     73     testThreshold(100, 100, false, true);
     74     testThreshold(1000, 100, false, true);
     75   }
     76 
     77   private void testThreshold(int fileThreshold, int dataSize, boolean singleByte,
     78       boolean resetOnFinalize) throws IOException {
     79     byte[] data = newPreFilledByteArray(dataSize);
     80     FileBackedOutputStream out = new FileBackedOutputStream(fileThreshold, resetOnFinalize);
     81     ByteSource source = out.asByteSource();
     82     int chunk1 = Math.min(dataSize, fileThreshold);
     83     int chunk2 = dataSize - chunk1;
     84 
     85     // Write just enough to not trip the threshold
     86     if (chunk1 > 0) {
     87       write(out, data, 0, chunk1, singleByte);
     88       assertTrue(ByteSource.wrap(data).slice(0, chunk1).contentEquals(source));
     89     }
     90     File file = out.getFile();
     91     assertNull(file);
     92 
     93     // Write data to go over the threshold
     94     if (chunk2 > 0) {
     95       write(out, data, chunk1, chunk2, singleByte);
     96       file = out.getFile();
     97       assertEquals(dataSize, file.length());
     98       assertTrue(file.exists());
     99     }
    100     out.close();
    101 
    102     // Check that source returns the right data
    103     assertTrue(Arrays.equals(data, source.read()));
    104 
    105     // Make sure that reset deleted the file
    106     out.reset();
    107     if (file != null) {
    108       assertFalse(file.exists());
    109     }
    110   }
    111 
    112   private static void write(
    113       OutputStream out, byte[] b, int off, int len, boolean singleByte)
    114       throws IOException {
    115     if (singleByte) {
    116       for (int i = off; i < off + len; i++) {
    117         out.write(b[i]);
    118       }
    119     } else {
    120       out.write(b, off, len);
    121     }
    122     out.flush(); // for coverage
    123   }
    124 
    125   // TODO(chrisn): only works if we ensure we have crossed file threshold
    126 
    127   public void testWriteErrorAfterClose() throws Exception {
    128     byte[] data = newPreFilledByteArray(100);
    129     FileBackedOutputStream out = new FileBackedOutputStream(50);
    130     ByteSource source = out.asByteSource();
    131 
    132     out.write(data);
    133     assertTrue(Arrays.equals(data, source.read()));
    134 
    135     out.close();
    136     try {
    137       out.write(42);
    138       fail("expected exception");
    139     } catch (IOException expected) {
    140       // expected
    141     }
    142 
    143     // Verify that write had no effect
    144     assertTrue(Arrays.equals(data, source.read()));
    145     out.reset();
    146   }
    147 
    148   public void testReset() throws Exception {
    149     byte[] data = newPreFilledByteArray(100);
    150     FileBackedOutputStream out = new FileBackedOutputStream(Integer.MAX_VALUE);
    151     ByteSource source = out.asByteSource();
    152 
    153     out.write(data);
    154     assertTrue(Arrays.equals(data, source.read()));
    155 
    156     out.reset();
    157     assertTrue(Arrays.equals(new byte[0], source.read()));
    158 
    159     out.write(data);
    160     assertTrue(Arrays.equals(data, source.read()));
    161 
    162     out.close();
    163   }
    164 }
    165