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