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