OSDN Git Service

AI 144830: Bringing luni down to 15 broken tests. Not perfect,
[android-x86/dalvik.git] / libcore / luni / src / test / java / tests / api / java / io / PipedInputStreamTest.java
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 package tests.api.java.io;
18
19 import java.io.IOException;
20 import java.io.PipedInputStream;
21 import java.io.PipedOutputStream;
22
23 import dalvik.annotation.TestLevel;
24 import dalvik.annotation.TestTargetClass;
25 import dalvik.annotation.TestTargetNew;
26
27 @TestTargetClass(PipedInputStream.class) 
28 public class PipedInputStreamTest extends junit.framework.TestCase {
29
30     static class PWriter implements Runnable {
31         PipedOutputStream pos;
32
33         public byte bytes[];
34
35         public void run() {
36             try {
37                 pos.write(bytes);   
38                 synchronized (this) {
39                     notify();
40                 }
41             } catch (Exception e) {
42                 e.printStackTrace(System.out);
43                 System.out.println("Error while running the writer thread.");
44             }
45         }
46
47         public PWriter(PipedOutputStream pout, int nbytes) {
48             pos = pout;
49             bytes = new byte[nbytes];
50             for (int i = 0; i < bytes.length; i++)
51                 bytes[i] = (byte) (System.currentTimeMillis() % 9);
52         }
53     }
54
55     static class PWriter2 implements Runnable {
56         PipedOutputStream pos;
57
58         public boolean keepRunning = true;
59
60         public void run() {
61             try {
62                 pos.write(42);
63                 pos.close();
64                 while (keepRunning) {
65                     Thread.sleep(1000);
66                 }
67             } catch (Exception e) {
68                 e.printStackTrace(System.out);
69                 System.out.println("Error while running the writer thread.");
70             }
71         }
72
73         public PWriter2(PipedOutputStream pout) {
74             pos = pout;
75         }
76     }
77
78     Thread t;
79
80     PWriter pw;
81
82     PipedInputStream pis;
83
84     PipedOutputStream pos;
85
86     /**
87      * @tests java.io.PipedInputStream#PipedInputStream()
88      */
89     @TestTargetNew(
90         level = TestLevel.COMPLETE,
91         notes = "",
92         method = "PipedInputStream",
93         args = {}
94     )
95     public void test_Constructor() throws IOException {
96         pis = new PipedInputStream();
97         assertEquals("There should not be any bytes available. ", 0, pis.available());
98         pis.close();
99     }
100
101     /**
102      * @tests java.io.PipedInputStream#PipedInputStream(java.io.PipedOutputStream)
103      */
104     @TestTargetNew(
105         level = TestLevel.COMPLETE,
106         notes = "",
107         method = "PipedInputStream",
108         args = {java.io.PipedOutputStream.class}
109     )
110     public void test_ConstructorLjava_io_PipedOutputStream() throws IOException {
111         pos = new PipedOutputStream(new PipedInputStream());
112         
113         try {
114             pis = new PipedInputStream(pos);
115             fail("IOException expected since the output stream is already connected.");
116         } catch (IOException e) {
117             // Expected.
118         }
119         
120         pis = new PipedInputStream(new PipedOutputStream());
121         assertEquals("There should not be any bytes available. ", 0, pis.available());
122         
123         pis.close();
124         pos.close();
125     }
126
127     /**
128      * @tests java.io.PipedInputStream#available()
129      */
130     @TestTargetNew(
131         level = TestLevel.COMPLETE,
132         notes = "No IOException checking because it is never thrown in the source code.",
133         method = "available",
134         args = {}
135     )
136     public void test_available() throws Exception {
137         // Test for method int java.io.PipedInputStream.available()
138         pis = new PipedInputStream();
139         pos = new PipedOutputStream();
140
141         pis.connect(pos);
142         t = new Thread(pw = new PWriter(pos, 1000));
143         t.start();
144
145         synchronized (pw) {
146             pw.wait(10000);
147         }
148         assertEquals("Test 1: Incorrect number of bytes available. ",
149                      1000, pis.available());
150
151         PipedInputStream pin = new PipedInputStream();
152         PipedOutputStream pout = new PipedOutputStream(pin);
153         // We know the PipedInputStream buffer size is 1024.
154         // Writing another byte would cause the write to wait
155         // for a read before returning
156         for (int i = 0; i < 1024; i++)
157             pout.write(i);
158         assertEquals("Test 2: Incorrect number of bytes available. ", 
159                      1024 , pin.available());
160     }
161
162     /**
163      * @tests java.io.PipedInputStream#close()
164      */
165     @TestTargetNew(
166         level = TestLevel.COMPLETE,
167         notes = "No IOException checking because it is never thrown in the source code.",
168         method = "close",
169         args = {}
170     )
171     public void test_close() throws IOException {
172         // Test for method void java.io.PipedInputStream.close()
173         pis = new PipedInputStream();
174         pos = new PipedOutputStream();
175         pis.connect(pos);
176         pis.close();
177         try {
178             pos.write((byte) 127);
179             fail("IOException expected.");
180         } catch (IOException e) {
181             // The spec for PipedInput says an exception should be thrown if
182             // a write is attempted to a closed input. The PipedOuput spec
183             // indicates that an exception should be thrown only when the
184             // piped input thread is terminated without closing
185             return;
186         }
187     }
188
189     /**
190      * @tests java.io.PipedInputStream#connect(java.io.PipedOutputStream)
191      */
192     @TestTargetNew(
193         level = TestLevel.COMPLETE,
194         notes = "",
195         method = "connect",
196         args = {java.io.PipedOutputStream.class}
197     )
198     public void test_connectLjava_io_PipedOutputStream() throws Exception {
199         // Test for method void
200         // java.io.PipedInputStream.connect(java.io.PipedOutputStream)
201         pis = new PipedInputStream();
202         pos = new PipedOutputStream();
203         assertEquals("Test 1: Not-connected pipe returned more than zero available bytes. ", 
204                      0, pis.available());
205
206         pis.connect(pos);
207         t = new Thread(pw = new PWriter(pos, 1000));
208         t.start();
209
210         synchronized (pw) {
211             pw.wait(10000);
212         }
213         assertEquals("Test 2: Unexpected number of bytes available. ", 
214                      1000, pis.available());
215
216         try {
217             pis.connect(pos);
218             fail("Test 3: IOException expected when reconnecting the pipe.");
219         } catch (IOException e) {
220             // Expected.
221         }
222         
223         pis.close();
224         pos.close();
225     }
226
227     /**
228      * @tests java.io.PipedInputStream#read()
229      */
230     @TestTargetNew(
231         level = TestLevel.PARTIAL_COMPLETE,
232         notes = "",
233         method = "read",
234         args = {}
235     )
236     public void test_read() throws Exception {
237         pis = new PipedInputStream();
238         pos = new PipedOutputStream();
239
240         try {
241             pis.read();
242             fail("Test 1: IOException expected since the stream is not connected.");
243         } catch (IOException e) {
244             // Expected.
245         }
246         
247         pis.connect(pos);
248         t = new Thread(pw = new PWriter(pos, 100));
249         t.start();
250
251         synchronized (pw) {
252             pw.wait(5000);
253         }
254         assertEquals("Test 2: Unexpected number of bytes available. ", 
255                      100, pis.available());
256         
257         for (int i = 0; i < 100; i++) {
258             assertEquals("Test 3: read() returned incorrect byte. ", 
259                          pw.bytes[i], (byte) pis.read());
260         }
261
262         try {
263             pis.read();
264             fail("Test 4: IOException expected since the thread that has " +
265                  "written to the pipe is no longer alive.");
266         } catch (IOException e) {
267             // Expected.
268         }
269
270         pis.close();
271         try {
272             pis.read();
273             fail("Test 5: IOException expected since the stream is closed.");
274         } catch (IOException e) {
275             // Expected.
276         }
277     }
278
279     /**
280      * @tests java.io.PipedInputStream#read()
281      */
282     @TestTargetNew(
283         level = TestLevel.PARTIAL_COMPLETE,
284         notes = "Checks that read returns -1 if the PipedOutputStream connected to this PipedInputStream is closed.",
285         method = "read",
286         args = {}
287     )
288     public void test_read_2() throws Exception {
289         Thread writerThread;
290         PWriter2 pwriter;
291         
292         pos = new PipedOutputStream(); 
293         pis = new PipedInputStream(pos);
294         writerThread = new Thread(pwriter = new PWriter2(pos));
295         writerThread.start();
296
297         synchronized (pwriter) {
298             pwriter.wait(5000);
299         }
300         pis.read();
301         assertEquals("Test 1: No more data indication expected. ", -1, pis.read());
302         pwriter.keepRunning = false;
303         
304         pis.close();
305     }
306
307     /**
308      * @tests java.io.PipedInputStream#read(byte[], int, int)
309      */
310     @TestTargetNew(
311         level = TestLevel.PARTIAL_COMPLETE,
312         notes = "Tests read from unconnected, connected and closed pipe.",
313         method = "read",
314         args = {byte[].class, int.class, int.class}
315     )
316     public void test_read$BII() throws Exception {
317         byte[] buf = new byte[400];
318         pis = new PipedInputStream();
319         pos = new PipedOutputStream();
320
321         try {
322             pis.read(buf, 0, 10);
323             fail("Test 1: IOException expected since the stream is not connected.");
324         } catch (IOException e) {
325             // Expected.
326         }
327         
328         pis.connect(pos);
329         t = new Thread(pw = new PWriter(pos, 1000));
330         t.start();
331
332         synchronized (pw) {
333             pw.wait(10000);
334         }
335         assertEquals("Test 2: Unexpected number of bytes available. ",
336                      1000, pis.available());
337         pis.read(buf, 0, 400);
338         for (int i = 0; i < 400; i++) {
339             assertEquals("Test 3: read() returned incorrect byte. ", 
340                          pw.bytes[i], buf[i]);
341         }
342         
343         pis.close();
344         try {
345             pis.read(buf, 0, 10);
346             fail("Test 4: IOException expected since the stream is closed.");
347         } catch (IOException e) {
348             // Expected.
349         }
350     }
351
352     /**
353      * @tests java.io.PipedInputStream#read(byte[], int, int)
354      * Regression for HARMONY-387
355      */
356     @TestTargetNew(
357         level = TestLevel.PARTIAL_COMPLETE,
358         notes = "Tests illegal length argument.",
359         method = "read",
360         args = {byte[].class, int.class, int.class}
361     )
362     public void test_read$BII_2() throws IOException {
363         PipedInputStream obj = new PipedInputStream();
364         try {
365             obj.read(new byte[0], 0, -1);
366             fail("IndexOutOfBoundsException expected.");
367         } catch (IndexOutOfBoundsException t) {
368             assertEquals(
369                     "IndexOutOfBoundsException rather than a subclass expected.",
370                     IndexOutOfBoundsException.class, t.getClass());
371         }
372     }
373
374     /**
375      * @tests java.io.PipedInputStream#read(byte[], int, int)
376      */
377     @TestTargetNew(
378         level = TestLevel.PARTIAL_COMPLETE,
379         notes = "Tests illegal offset argument.",
380         method = "read",
381         args = {byte[].class, int.class, int.class}
382     )
383     public void test_read$BII_3() throws IOException {
384         PipedInputStream obj = new PipedInputStream();
385         try {
386             obj.read(new byte[10], -1, 1);
387             fail("IndexOutOfBoundsException expected.");
388         } catch (IndexOutOfBoundsException e) {
389             // Expected
390             assertTrue(e.getClass().equals(IndexOutOfBoundsException.class));
391         }
392         try {
393             obj.read(new byte[10], 0, -1);
394             fail("IndexOutOfBoundsException expected.");
395         } catch (IndexOutOfBoundsException e) {
396             // Expected
397             assertTrue(e.getClass().equals(IndexOutOfBoundsException.class));
398         }
399         try {
400             obj.read(new byte[10], 9, 2);
401             fail("IndexOutOfBoundsException expected.");
402         } catch (IndexOutOfBoundsException e) {
403             // Expected
404             assertTrue(e.getClass().equals(IndexOutOfBoundsException.class));
405         }
406     }
407
408     /**
409      * @tests java.io.PipedInputStream#receive(int)
410      */
411     @TestTargetNew(
412         level = TestLevel.COMPLETE,
413         notes = "",
414         method = "receive",
415         args = {int.class}
416     )
417     public void test_receive() throws IOException {
418         pis = new PipedInputStream();
419         pos = new PipedOutputStream();
420
421         // test if writer recognizes dead reader
422         pis.connect(pos);
423         class WriteRunnable implements Runnable {
424
425             boolean pass = false;
426
427             boolean readerAlive = true;
428
429             public void run() {
430                 try {
431                     pos.write(1);
432                     while (readerAlive) {
433                         Thread.sleep(100);
434                     }
435                     try {
436                         // should throw exception since reader thread
437                         // is now dead
438                         pos.write(1);
439                     } catch (IOException e) {
440                         pass = true;
441                     }
442                 } catch (IOException e) {
443                     // ignore
444                 } catch (InterruptedException e) {
445                     // ignore
446                 }
447             }
448         }
449         WriteRunnable writeRunnable = new WriteRunnable();
450         Thread writeThread = new Thread(writeRunnable);
451         class ReadRunnable implements Runnable {
452
453             boolean pass;
454
455             public void run() {
456                 try {
457                     pis.read();
458                     pass = true;
459                 } catch (IOException e) {}
460             }
461         }
462         ;
463         ReadRunnable readRunnable = new ReadRunnable();
464         Thread readThread = new Thread(readRunnable);
465         writeThread.start();
466         readThread.start();
467         while (readThread.isAlive())
468             ;
469         writeRunnable.readerAlive = false;
470         assertTrue("reader thread failed to read", readRunnable.pass);
471         while (writeThread.isAlive())
472             ;
473         assertTrue("writer thread failed to recognize dead reader",
474                 writeRunnable.pass);
475
476         // attempt to write to stream after writer closed
477         pis = new PipedInputStream();
478         pos = new PipedOutputStream();
479
480         pis.connect(pos);
481         class MyRunnable implements Runnable {
482
483             boolean pass;
484
485             public void run() {
486                 try {
487                     pos.write(1);
488                 } catch (IOException e) {
489                     pass = true;
490                 }
491             }
492         }
493         MyRunnable myRun = new MyRunnable();
494         synchronized (pis) {
495             t = new Thread(myRun);
496             // thread t will be blocked inside pos.write(1)
497             // when it tries to call the synchronized method pis.receive
498             // because we hold the monitor for object pis
499             t.start();
500             try {
501                 // wait for thread t to get to the call to pis.receive
502                 Thread.sleep(100);
503             } catch (InterruptedException e) {}
504             // now we close
505             pos.close();
506         }
507         // we have exited the synchronized block, so now thread t will make
508         // a call to pis.receive AFTER the output stream was closed,
509         // in which case an IOException should be thrown
510         while (t.isAlive()) {
511             ;
512         }
513         assertTrue(
514                 "write failed to throw IOException on closed PipedOutputStream",
515                 myRun.pass);
516     }
517
518     /**
519      * Tears down the fixture, for example, close a network connection. This
520      * method is called after a test is executed.
521      */
522     protected void tearDown() throws Exception {
523         try {
524             if (t != null) {
525                 t.interrupt();
526             }
527         } catch (Exception ignore) {
528         }
529         super.tearDown();
530     }
531 }