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