PipedWriterTest.java revision 5d709784bbf5001012d7f25172927d46f6c1abe1
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
18package tests.api.java.io;
19
20import dalvik.annotation.BrokenTest;
21import dalvik.annotation.TestTargets;
22import dalvik.annotation.TestLevel;
23import dalvik.annotation.TestTargetNew;
24import dalvik.annotation.TestTargetClass;
25
26import java.io.IOException;
27import java.io.PipedReader;
28import java.io.PipedWriter;
29
30import java.util.Arrays;
31
32@TestTargetClass(PipedWriter.class)
33public class PipedWriterTest extends junit.framework.TestCase {
34
35    static final String testString = "Lorem ipsum...";
36    static final int testLength = testString.length();
37
38    static class PReader implements Runnable {
39        public PipedReader pr;
40
41        public char[] buf;
42
43        public PReader(PipedWriter pw) {
44            try {
45                pr = new PipedReader(pw);
46            } catch (IOException e) {
47                System.out.println("Exception setting up reader: "
48                        + e.toString());
49            }
50        }
51
52        public PReader(PipedReader pr) {
53            this.pr = pr;
54        }
55
56/*        public void run() {
57            try {
58                int r = 0;
59                for (int i = 0; i < buf.length; i++) {
60                    r = pr.read();
61                    if (r == -1)
62                        break;
63                    buf[i] = (char) r;
64                }
65            } catch (Exception e) {
66                System.out.println("Exception reading ("
67                        + Thread.currentThread().getName() + "): "
68                        + e.toString());
69            }
70        } */
71
72        public void run() {
73            try {
74                while (true) {
75                    Thread.sleep(1000);
76                    Thread.yield();
77                }
78            } catch (InterruptedException e) {
79            }
80        }
81
82        public String read(int nbytes) {
83            buf = new char[nbytes];
84            try {
85                pr.read(buf, 0, nbytes);
86                return new String(buf);
87            } catch (IOException e) {
88                System.out.println("Exception reading ("
89                        + Thread.currentThread().getName() + "): "
90                        + e.toString());
91                return "ERROR";
92            }
93        }
94    }
95
96    Thread readerThread;
97    PReader reader;
98    PipedWriter pw;
99    char[] testBuf;
100
101    /**
102     * @tests java.io.PipedWriter#PipedWriter()
103     */
104    @TestTargetNew(
105        level = TestLevel.COMPLETE,
106        notes = "",
107        method = "PipedWriter",
108        args = {}
109    )
110    public void test_Constructor() {
111        pw = new PipedWriter();
112        assertNotNull(pw);
113        try {
114            pw.close();
115        } catch (IOException e) {
116            fail("Unexpeceted IOException.");
117        }
118    }
119
120    /**
121     * @tests java.io.PipedWriter#PipedWriter(java.io.PipedReader)
122     */
123    @TestTargetNew(
124        level = TestLevel.COMPLETE,
125        notes = "",
126        method = "PipedWriter",
127        args = {java.io.PipedReader.class}
128    )
129    public void test_ConstructorLjava_io_PipedReader() throws Exception {
130        PipedReader rd = new PipedReader();
131
132        try {
133            pw = new PipedWriter(rd);
134        } catch (Exception e) {
135            fail("Test 1: Construtor failed:" + e.getMessage());
136        }
137
138        readerThread = new Thread(reader = new PReader(rd), "Constructor(Reader)");
139        readerThread.start();
140        try {
141            pw.write(testBuf);
142        } catch (Exception e) {
143            fail("Test 2: Could not write to the constructed writer: "
144                    + e.getMessage());
145        }
146        pw.close();
147        assertEquals("Test 3: Incorrect character string received.", testString,
148                reader.read(testLength));
149
150        rd = new PipedReader(new PipedWriter());
151        try {
152            pw = new PipedWriter(rd);
153            fail("Test 4: IOException expected because the reader is already connected.");
154        } catch (IOException e) {
155            // Expected.
156        }
157    }
158
159    /**
160     * @tests java.io.PipedWriter#close()
161     */
162    @TestTargetNew(
163        level = TestLevel.COMPLETE,
164        notes = "",
165        method = "close",
166        args = {}
167    )
168    public void test_close() throws Exception {
169        PipedReader rd = new PipedReader();
170        pw = new PipedWriter(rd);
171        reader = new PReader(rd);
172        try {
173            pw.close();
174        } catch (IOException e) {
175            fail("Test 1: Unexpected IOException: " + e.getMessage());
176        }
177    }
178
179    /**
180     * @tests java.io.PipedWriter#connect(java.io.PipedReader)
181     */
182    @TestTargetNew(
183        level = TestLevel.COMPLETE,
184        notes = "",
185        method = "connect",
186        args = {java.io.PipedReader.class}
187    )
188    public void test_connectLjava_io_PipedReader() throws Exception {
189        PipedReader rd = new PipedReader();
190        pw = new PipedWriter();
191
192        try {
193            pw.connect(rd);
194        } catch (Exception e) {
195            fail("Test 1: Unexpected exception when connecting: " +
196                    e.getLocalizedMessage());
197        }
198
199        readerThread = new Thread(reader = new PReader(rd), "connect");
200        readerThread.start();
201
202        try {
203            pw.write(testBuf);
204        } catch (IOException e) {
205            fail("Test 2: Unexpected IOException when writing after connecting.");
206        }
207        assertEquals("Test 3: Incorrect character string received.", testString,
208                reader.read(testLength));
209
210        try {
211            pw.connect(new PipedReader());
212            fail("Test 4: IOException expected when reconnecting the writer.");
213        } catch (IOException e) {
214            // Expected.
215        }
216    }
217
218    /**
219     * @tests java.io.PipedWriter#flush()
220     */
221    @TestTargetNew(
222        level = TestLevel.SUFFICIENT,
223        notes = "No IOException checking because it is never thrown in the source code.",
224        method = "flush",
225        args = {}
226    )
227    public void test_flush() throws Exception {
228        // Test for method void java.io.PipedWriter.flush()
229        pw = new PipedWriter();
230        readerThread = new Thread(reader = new PReader(pw), "flush");
231        readerThread.start();
232        pw.write(testBuf);
233        pw.flush();
234        assertEquals("Test 1: Flush failed. ", testString,
235                reader.read(testLength));
236    }
237
238    /**
239     * @tests java.io.PipedWriter#write(char[], int, int)
240     */
241    @TestTargetNew(
242        level = TestLevel.PARTIAL_COMPLETE,
243        notes = "",
244        method = "write",
245        args = {char[].class, int.class, int.class}
246    )
247    public void test_write$CII() throws Exception {
248        pw = new PipedWriter();
249
250        try {
251            pw.write(testBuf, 0, 5);
252            fail("Test 1: IOException expected.");
253        } catch (IOException e) {
254            // Expected.
255        }
256
257        pw = new PipedWriter(new PipedReader());
258
259        try {
260            pw.write(testBuf, -1, 1);
261            fail("Test 2: IndexOutOfBoundsException expected.");
262        } catch (IndexOutOfBoundsException e) {
263            // Expected.
264        }
265
266        try {
267            pw.write(testBuf, 0, -1);
268            fail("Test 3: IndexOutOfBoundsException expected.");
269        } catch (IndexOutOfBoundsException e) {
270            // Expected.
271        }
272
273        try {
274            pw.write(testBuf, 5, testString.length());
275            fail("Test 4: IndexOutOfBoundsException expected.");
276        } catch (IndexOutOfBoundsException e) {
277            // Expected.
278        }
279
280        pw.close();
281        pw = new PipedWriter();
282        try {
283            readerThread = new Thread(reader = new PReader(pw), "writeCII");
284            readerThread.start();
285            pw.write(testBuf, 0, testLength);
286            pw.close();
287            reader.read(testLength);
288            assertTrue("Test 5: Characters read do not match the characters written.",
289                    Arrays.equals( testBuf, reader.buf));
290        } catch (IOException e) {
291            fail("Test 5: Unexpected IOException: " + e.getMessage());
292        }
293
294        readerThread.interrupt();
295
296        try {
297            pw.write(testBuf, 0, 5);
298            fail("Test 6: IOException expected.");
299        } catch (IOException e) {
300            // Expected.
301        }
302
303        reader.pr.close();
304        try {
305            pw.write(testBuf, 0, 5);
306            fail("Test 7: IOException expected.");
307        } catch (IOException e) {
308            // Expected.
309        }
310    }
311
312    /**
313     * @tests java.io.PipedWriter#write(char[],int,int)
314     */
315    @TestTargetNew(
316        level = TestLevel.PARTIAL_COMPLETE,
317        notes = "",
318        method = "write",
319        args = {char[].class, int.class, int.class}
320    )
321    @BrokenTest("Hangs on RI")
322    public void test_write$CII_MultiThread() throws Exception {
323        final PipedReader pr = new PipedReader();
324        final PipedWriter pw = new PipedWriter();
325
326        // test if writer recognizes dead reader
327        pr.connect(pw);
328
329        class WriteRunnable implements Runnable {
330            boolean pass = false;
331
332            boolean readerAlive = true;
333
334            public void run() {
335                try {
336                    pw.write(1);
337                    while (readerAlive) {
338                    // wait the reader thread dead
339                    }
340                    try {
341                        // should throw exception since reader thread
342                        // is now dead
343                        char[] buf = new char[10];
344                        pw.write(buf, 0, 10);
345                    } catch (IOException e) {
346                        pass = true;
347                    }
348                } catch (IOException e) {
349                  //ignore
350                }
351            }
352        }
353        WriteRunnable writeRunnable = new WriteRunnable();
354        Thread writeThread = new Thread(writeRunnable);
355        class ReadRunnable implements Runnable {
356            boolean pass;
357
358            public void run() {
359                try {
360                    pr.read();
361                    pass = true;
362                } catch (IOException e) {
363                  //ignore
364                }
365            }
366        }
367        ReadRunnable readRunnable = new ReadRunnable();
368        Thread readThread = new Thread(readRunnable);
369        writeThread.start();
370        readThread.start();
371        while (readThread.isAlive()) {
372            //wait the reader thread dead
373        }
374        writeRunnable.readerAlive = false;
375        assertTrue("reader thread failed to read", readRunnable.pass);
376        while (writeThread.isAlive()) {
377            //wait the writer thread dead
378        }
379        assertTrue("writer thread failed to recognize dead reader",
380                writeRunnable.pass);
381    }
382
383    /**
384     * @tests java.io.PipedWriter#write(int)
385     */
386    @TestTargetNew(
387        level = TestLevel.PARTIAL_COMPLETE,
388        notes = "",
389        method = "write",
390        args = {int.class}
391    )
392    public void test_writeI() throws Exception {
393        // Test for method void java.io.PipedWriter.write(int)
394
395        pw = new PipedWriter();
396
397        try {
398            pw.write(42);
399            fail("Test 1: IOException expected.");
400        } catch (IOException e) {
401            // Expected.
402        }
403
404        readerThread = new Thread(reader = new PReader(pw), "writeI");
405        readerThread.start();
406        pw.write(1);
407        pw.write(2);
408        pw.write(3);
409        pw.close();
410        reader.read(3);
411        assertTrue("Test 2: The charaacters read do not match the characters written: " +
412                (int) reader.buf[0] + " " + (int) reader.buf[1] + " " + (int) reader.buf[2],
413                reader.buf[0] == 1 && reader.buf[1] == 2 && reader.buf[2] == 3);
414    }
415
416    /**
417     * @tests java.io.PipedWriter#write(int)
418     */
419    @TestTargetNew(
420        level = TestLevel.PARTIAL_COMPLETE,
421        notes = "",
422        method = "write",
423        args = {int.class}
424    )
425    @BrokenTest("Hangs on RI")
426    public void test_writeI_MultiThread() throws IOException {
427        final PipedReader pr = new PipedReader();
428        final PipedWriter pw = new PipedWriter();
429        // test if writer recognizes dead reader
430        pr.connect(pw);
431
432        class WriteRunnable implements Runnable {
433            boolean pass = false;
434            boolean readerAlive = true;
435            public void run() {
436                try {
437                    pw.write(1);
438                    while (readerAlive) {
439                    // wait the reader thread dead
440                    }
441                    try {
442                        // should throw exception since reader thread
443                        // is now dead
444                        pw.write(1);
445                    } catch (IOException e) {
446                        pass = true;
447                    }
448                } catch (IOException e) {
449                  //ignore
450                }
451            }
452        }
453        WriteRunnable writeRunnable = new WriteRunnable();
454        Thread writeThread = new Thread(writeRunnable);
455        class ReadRunnable implements Runnable {
456            boolean pass;
457            public void run() {
458                try {
459                    pr.read();
460                    pass = true;
461                } catch (IOException e) {
462                  //ignore
463                }
464            }
465        }
466        ReadRunnable readRunnable = new ReadRunnable();
467        Thread readThread = new Thread(readRunnable);
468        writeThread.start();
469        readThread.start();
470        while (readThread.isAlive()) {
471           //wait the reader thread dead
472        }
473        writeRunnable.readerAlive = false;
474        assertTrue("reader thread failed to read", readRunnable.pass);
475        while (writeThread.isAlive()) {
476           //wait the writer thread dead
477        }
478        assertTrue("writer thread failed to recognize dead reader",
479                writeRunnable.pass);
480    }
481
482    protected void setUp() throws Exception {
483        super.setUp();
484        testBuf = new char[testLength];
485        testString.getChars(0, testLength, testBuf, 0);
486    }
487
488    protected void tearDown() throws Exception {
489        try {
490            if (readerThread != null) {
491                readerThread.interrupt();
492            }
493        } catch (Exception ignore) {}
494        try {
495            if (pw != null) {
496                pw.close();
497            }
498        } catch (Exception ignore) {}
499        super.tearDown();
500    }
501}
502