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