Home | History | Annotate | Download | only in io
      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