1 /* 2 * Copyright (C) 2010 The Android Open Source Project 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 libcore.java.io; 18 19 import java.io.File; 20 import java.io.FileDescriptor; 21 import java.io.FileInputStream; 22 import java.io.FileNotFoundException; 23 import java.io.FileOutputStream; 24 import java.io.IOException; 25 import junit.framework.TestCase; 26 27 import libcore.io.IoUtils; 28 import libcore.io.Libcore; 29 30 public final class FileInputStreamTest extends TestCase { 31 private static final int TOTAL_SIZE = 1024; 32 private static final int SKIP_SIZE = 100; 33 34 private static class DataFeeder extends Thread { 35 private FileDescriptor mOutFd; 36 37 public DataFeeder(FileDescriptor fd) { 38 mOutFd = fd; 39 } 40 41 @Override 42 public void run() { 43 try { 44 FileOutputStream fos = new FileOutputStream(mOutFd); 45 try { 46 byte[] buffer = new byte[TOTAL_SIZE]; 47 for (int i = 0; i < buffer.length; ++i) { 48 buffer[i] = (byte) i; 49 } 50 fos.write(buffer); 51 } finally { 52 IoUtils.closeQuietly(fos); 53 IoUtils.close(mOutFd); 54 } 55 } catch (IOException e) { 56 throw new RuntimeException(e); 57 } 58 } 59 } 60 61 private void verifyData(FileInputStream is, int start, int count) throws IOException { 62 byte buffer[] = new byte[count]; 63 assertEquals(count, is.read(buffer)); 64 for (int i = 0; i < count; ++i) { 65 assertEquals((byte) (i + start), buffer[i]); 66 } 67 } 68 69 public void testSkipInPipes() throws Exception { 70 FileDescriptor[] pipe = Libcore.os.pipe(); 71 DataFeeder feeder = new DataFeeder(pipe[1]); 72 try { 73 feeder.start(); 74 FileInputStream fis = new FileInputStream(pipe[0]); 75 fis.skip(SKIP_SIZE); 76 verifyData(fis, SKIP_SIZE, TOTAL_SIZE - SKIP_SIZE); 77 assertEquals(-1, fis.read()); 78 feeder.join(1000); 79 assertFalse(feeder.isAlive()); 80 } finally { 81 IoUtils.closeQuietly(pipe[0]); 82 } 83 } 84 85 public void testDirectories() throws Exception { 86 try { 87 new FileInputStream("."); 88 fail(); 89 } catch (FileNotFoundException expected) { 90 } 91 } 92 93 private File makeFile() throws Exception { 94 File tmp = File.createTempFile("FileOutputStreamTest", "tmp"); 95 FileOutputStream fos = new FileOutputStream(tmp); 96 fos.write(1); 97 fos.write(1); 98 fos.close(); 99 return tmp; 100 } 101 102 public void testFileDescriptorOwnership() throws Exception { 103 File tmp = makeFile(); 104 105 FileInputStream fis1 = new FileInputStream(tmp); 106 FileInputStream fis2 = new FileInputStream(fis1.getFD()); 107 108 // Close the second FileDescriptor and check we can't use it... 109 fis2.close(); 110 try { 111 fis2.available(); 112 fail(); 113 } catch (IOException expected) { 114 } 115 try { 116 fis2.read(); 117 fail(); 118 } catch (IOException expected) { 119 } 120 try { 121 fis2.read(new byte[1], 0, 1); 122 fail(); 123 } catch (IOException expected) { 124 } 125 try { 126 fis2.skip(1); 127 fail(); 128 } catch (IOException expected) { 129 } 130 // ...but that we can still use the first. 131 assertFalse(fis1.read() == -1); 132 133 // Close the first FileDescriptor and check we can't use it... 134 fis1.close(); 135 try { 136 fis1.available(); 137 fail(); 138 } catch (IOException expected) { 139 } 140 try { 141 fis1.read(); 142 fail(); 143 } catch (IOException expected) { 144 } 145 try { 146 fis1.read(new byte[1], 0, 1); 147 fail(); 148 } catch (IOException expected) { 149 } 150 try { 151 fis1.skip(1); 152 fail(); 153 } catch (IOException expected) { 154 } 155 } 156 157 public void testClose() throws Exception { 158 File tmp = makeFile(); 159 FileInputStream fis = new FileInputStream(tmp); 160 161 // Closing an already-closed stream is a no-op... 162 fis.close(); 163 fis.close(); 164 165 // But any explicit activity is an error. 166 try { 167 fis.available(); 168 fail(); 169 } catch (IOException expected) { 170 } 171 try { 172 fis.read(); 173 fail(); 174 } catch (IOException expected) { 175 } 176 try { 177 fis.read(new byte[1], 0, 1); 178 fail(); 179 } catch (IOException expected) { 180 } 181 try { 182 fis.skip(1); 183 fail(); 184 } catch (IOException expected) { 185 } 186 // Including 0-byte skips... 187 try { 188 fis.skip(0); 189 fail(); 190 } catch (IOException expected) { 191 } 192 // ...but not 0-byte reads... 193 fis.read(new byte[0], 0, 0); 194 } 195 } 196