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, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17
18package tests.api.java.io;
19
20import java.io.File;
21import java.io.FileDescriptor;
22import java.io.FileInputStream;
23import java.io.FileNotFoundException;
24import java.io.FileOutputStream;
25import java.io.IOException;
26
27import dalvik.annotation.AndroidOnly;
28import dalvik.annotation.TestLevel;
29import dalvik.annotation.TestTargetClass;
30import dalvik.annotation.TestTargetNew;
31
32@TestTargetClass(
33        value = FileOutputStream.class,
34        untestedMethods = {
35            @TestTargetNew(
36                    method = "finalize",
37                    args = {},
38                    level = TestLevel.NOT_FEASIBLE,
39                    notes = "Hard to test since it requires that the " +
40                            "garbage collector runs; add test later."
41            )
42        }
43)
44public class FileOutputStreamTest extends junit.framework.TestCase {
45
46    public String fileName;
47
48    FileOutputStream fos;
49
50    FileInputStream fis;
51
52    File f;
53
54    String tmpDirName = System.getProperty("java.io.tmpdir");
55
56    File tmpDir = new File(tmpDirName);
57
58    byte[] ibuf = new byte[4096];
59
60    public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
61
62    /**
63     * @tests java.io.FileOutputStream#FileOutputStream(java.io.File)
64     */
65    @TestTargetNew(
66        level = TestLevel.PARTIAL_COMPLETE,
67        method = "FileOutputStream",
68        args = {java.io.File.class}
69    )
70    public void test_ConstructorLjava_io_File() throws Exception {
71        try {
72            fos = new FileOutputStream(tmpDir);
73            fail("Test 1: FileNotFoundException expected.");
74        } catch (FileNotFoundException e) {
75            // Expected.
76        }
77
78        f = new File(fileName = System.getProperty("java.io.tmpdir"), "fos.tst");
79        fos = new FileOutputStream(f);
80    }
81
82    /**
83     * @tests java.io.FileOutputStream#FileOutputStream(java.lang.String,
84     *        boolean)
85     */
86    @TestTargetNew(
87        level = TestLevel.PARTIAL_COMPLETE,
88        method = "FileOutputStream",
89        args = {java.io.File.class, boolean.class}
90    )
91    public void test_ConstructorLjava_io_FileZ() throws Exception {
92        try {
93            fos = new FileOutputStream(tmpDir, false);
94            fail("Test 1: FileNotFoundException expected.");
95        } catch (FileNotFoundException e) {
96            // Expected.
97        }
98
99        f = new File(tmpDirName, "fos.tst");
100        fos = new FileOutputStream(f, false);
101        fos.write("FZ1".getBytes(), 0, 3);
102        fos.close();
103        // Append data to existing file
104        fos = new FileOutputStream(f, true);
105        fos.write(fileString.getBytes());
106        fos.close();
107        byte[] buf = new byte[fileString.length() + 3];
108        fis = new FileInputStream(f);
109        fis.read(buf, 0, buf.length);
110        assertTrue("Test 2: Failed to create appending stream.", new String(buf, 0,
111                buf.length).equals("FZ1" + fileString));
112        fis.close();
113
114        // Check that the existing file is overwritten
115        fos = new FileOutputStream(f, false);
116        fos.write("FZ2".getBytes(), 0, 3);
117        fos.close();
118        fis = new FileInputStream(f);
119        int bytesRead = fis.read(buf, 0, buf.length);
120        assertTrue("Test 3: Failed to overwrite stream.", new String(buf, 0,
121                bytesRead).equals("FZ2"));
122    }
123
124    /**
125     * @tests java.io.FileOutputStream#FileOutputStream(java.io.FileDescriptor)
126     */
127    @TestTargetNew(
128        level = TestLevel.PARTIAL_COMPLETE,
129        method = "FileOutputStream",
130        args = {java.io.FileDescriptor.class}
131    )
132    public void test_ConstructorLjava_io_FileDescriptor() throws Exception {
133        // Test for method java.io.FileOutputStream(java.io.FileDescriptor)
134        f = new File(tmpDirName, "fos.tst");
135        fileName = f.getAbsolutePath();
136        fos = new FileOutputStream(fileName);
137        fos.write('l');
138        fos.close();
139        fis = new FileInputStream(fileName);
140        fos = new FileOutputStream(fis.getFD());
141        fos.close();
142        fis.close();
143    }
144
145    /**
146     * @tests java.io.FileOutputStream#FileOutputStream(java.lang.String)
147     */
148    @TestTargetNew(
149        level = TestLevel.PARTIAL_COMPLETE,
150        method = "FileOutputStream",
151        args = {java.lang.String.class}
152    )
153    public void test_ConstructorLjava_lang_String() throws Exception {
154        try {
155            fos = new FileOutputStream(tmpDirName);
156            fail("Test 1: FileNotFoundException expected.");
157        } catch (FileNotFoundException e) {
158            // Expected.
159        }
160
161        f = new File(tmpDirName, "fos.tst");
162        fileName = f.getAbsolutePath();
163        fos = new FileOutputStream(fileName);
164    }
165
166    /**
167     * @tests java.io.FileOutputStream#FileOutputStream(java.lang.String,
168     *        boolean)
169     */
170    @TestTargetNew(
171        level = TestLevel.PARTIAL_COMPLETE,
172        method = "FileOutputStream",
173        args = {java.lang.String.class, boolean.class}
174    )
175    public void test_ConstructorLjava_lang_StringZ() throws Exception {
176        try {
177            fos = new FileOutputStream(tmpDirName, true);
178            fail("Test 1: FileNotFoundException expected.");
179        } catch (FileNotFoundException e) {
180            // Expected.
181        }
182
183        f = new File(tmpDirName, "fos.tst");
184        fos = new FileOutputStream(f.getPath(), false);
185        fos.write("HI".getBytes(), 0, 2);
186        fos.close();
187        // Append data to existing file
188        fos = new FileOutputStream(f.getPath(), true);
189        fos.write(fileString.getBytes());
190        fos.close();
191        byte[] buf = new byte[fileString.length() + 2];
192        fis = new FileInputStream(f.getPath());
193        fis.read(buf, 0, buf.length);
194        assertTrue("Failed to create appending stream", new String(buf, 0,
195                buf.length).equals("HI" + fileString));
196        fis.close();
197
198        // Check that the existing file is overwritten
199        fos = new FileOutputStream(f.getPath(), false);
200        fos.write("HI".getBytes(), 0, 2);
201        fos.close();
202        fis = new FileInputStream(f.getPath());
203        int bytesRead = fis.read(buf, 0, buf.length);
204        assertTrue("Failed to overwrite stream", new String(buf, 0,
205                bytesRead).equals("HI"));
206    }
207
208    /**
209     * @tests java.io.FileOutputStream#close()
210     */
211    @TestTargetNew(
212        level = TestLevel.SUFFICIENT,
213        notes = "IOException not checked because it would be thrown" +
214                "by a native method.",
215        method = "close",
216        args = {}
217    )
218    public void test_close() throws Exception {
219        f = new File(System.getProperty("java.io.tmpdir"), "output.tst");
220        fos = new FileOutputStream(f.getPath());
221        fos.close();
222
223        try {
224            fos.write(fileString.getBytes());
225            fail("Test 1: IOException expected.");
226        } catch (java.io.IOException e) {
227            // Expected.
228        }
229    }
230
231    /**
232     * @tests java.io.FileOutputStream#getFD()
233     */
234    @TestTargetNew(
235        level = TestLevel.SUFFICIENT,
236        notes = "IOException not checked because it never gets thrown.",
237        method = "getFD",
238        args = {}
239    )
240    public void test_getFD() throws Exception {
241        // Test for method java.io.FileDescriptor
242        // java.io.FileOutputStream.getFD()
243        f = new File(fileName = System.getProperty("java.io.tmpdir"), "testfd");
244        fileName = f.getAbsolutePath();
245        fos = new FileOutputStream(f);
246        assertTrue("Returned invalid fd", fos.getFD().valid());
247        fos.close();
248        assertTrue("Returned invalid fd", !fos.getFD().valid());
249    }
250
251    /**
252     * @tests java.io.FileOutputStream#write(byte[])
253     */
254    @TestTargetNew(
255        level = TestLevel.COMPLETE,
256        method = "write",
257        args = {byte[].class}
258    )
259    public void test_write$B() throws Exception {
260        // Test for method void java.io.FileOutputStream.write(byte [])
261        f = new File(System.getProperty("java.io.tmpdir"), "output.tst");
262        fos = new FileOutputStream(f.getPath());
263        fos.write(fileString.getBytes());
264        fos.close();
265        try {
266            fos.write(fileString.getBytes());
267            fail("Test 1: IOException expected.");
268        } catch (IOException e) {
269            // Expected.
270        }
271
272        fis = new FileInputStream(f.getPath());
273        byte rbytes[] = new byte[4000];
274        fis.read(rbytes, 0, fileString.length());
275        assertTrue("Test 2: Incorrect string written or read.",
276                new String(rbytes, 0, fileString.length()).equals(fileString));
277    }
278
279    /**
280     * @tests java.io.FileOutputStream#write(byte[], int, int)
281     */
282    @TestTargetNew(
283        level = TestLevel.PARTIAL_COMPLETE,
284        method = "write",
285        args = {byte[].class, int.class, int.class}
286    )
287    public void test_write$BII() throws Exception {
288        // Test for method void java.io.FileOutputStream.write(byte [], int,
289        // int)
290        f = new File(System.getProperty("java.io.tmpdir"), "output.tst");
291        fos = new FileOutputStream(f.getPath());
292        fos.write(fileString.getBytes(), 0, fileString.length());
293        fis = new FileInputStream(f.getPath());
294        byte rbytes[] = new byte[4000];
295        fis.read(rbytes, 0, fileString.length());
296        assertTrue("Incorrect bytes written", new String(rbytes, 0, fileString
297                .length()).equals(fileString));
298    }
299
300    /**
301     * @tests java.io.FileOutputStream#write(int)
302     */
303    @TestTargetNew(
304        level = TestLevel.COMPLETE,
305        method = "write",
306        args = {int.class}
307    )
308    public void test_writeI() throws IOException {
309        // Test for method void java.io.FileOutputStream.write(int)
310        f = new File(System.getProperty("java.io.tmpdir"), "output.tst");
311        fos = new FileOutputStream(f.getPath());
312        fos.write('t');
313        fos.close();
314        try {
315            fos.write(42);
316            fail("Test: IOException expected.");
317        } catch (IOException e) {
318            // Expected.
319        }
320
321        fis = new FileInputStream(f.getPath());
322        assertEquals("Test 1: Incorrect char written or read.",
323                't', fis.read());
324    }
325
326    /**
327     * @tests java.io.FileOutputStream#write(byte[], int, int)
328     */
329    @TestTargetNew(
330        level = TestLevel.PARTIAL_COMPLETE,
331        notes = "Illegal argument and IOException checks.",
332        method = "write",
333        args = {byte[].class, int.class, int.class}
334    )
335    public void test_write$BII2() throws Exception {
336        f = new File(tmpDirName, "output.tst");
337        fos = new FileOutputStream(f.getPath());
338
339        try {
340            fos.write(null, 0, 0);
341            fail("Test 1: NullPointerException expected.");
342        } catch (NullPointerException e) {}
343
344        try {
345            fos.write(new byte[1], -1, 0);
346            fail("Test 2: IndexOutOfBoundsException expected.");
347        } catch (IndexOutOfBoundsException e) {
348            // Expected
349        }
350
351        try {
352            fos.write(new byte[1], 0, -1);
353            fail("Test 3: IndexOutOfBoundsException expected.");
354        } catch (IndexOutOfBoundsException e) {
355            // Expected
356        }
357
358        try {
359            fos.write(new byte[1], 0, 5);
360            fail("Test 4: IndexOutOfBoundsException expected.");
361        } catch (IndexOutOfBoundsException e) {
362            // Expected
363        }
364
365        try {
366            fos.write(new byte[10], Integer.MAX_VALUE, 5);
367            fail("Test 5: IndexOutOfBoundsException expected.");
368        } catch (IndexOutOfBoundsException e) {
369            // Expected
370        }
371
372        try {
373            fos.write(new byte[10], 5, Integer.MAX_VALUE);
374            fail("Test 6: IndexOutOfBoundsException expected.");
375        } catch (IndexOutOfBoundsException e) {
376            // Expected
377        }
378
379        fos.close();
380        try {
381            fos.write(new byte[10], 5, 4);
382            fail("Test 7: IOException expected.");
383        } catch (IOException e) {
384            // Expected.
385        }
386
387    }
388
389    /**
390     * @tests java.io.FileOutputStream#write(byte[], int, int)
391     */
392    @TestTargetNew(
393        level = TestLevel.PARTIAL_COMPLETE,
394        method = "write",
395        args = {byte[].class, int.class, int.class}
396    )
397    public void test_write$BII3() {
398        try {
399            new FileOutputStream(new FileDescriptor()).write(new byte[1], 0, 0);
400        } catch (Exception e) {
401            fail("Unexpected exception: " + e);
402        }
403    }
404
405    /**
406     * @tests java.io.FileOutputStream#getChannel()
407     */
408    @TestTargetNew(
409        level = TestLevel.COMPLETE,
410        notes = "Verifies getChannel() method.",
411        method = "getChannel",
412        args = {}
413    )
414    @AndroidOnly("The position of the FileChannel for a file opened in " +
415                 "append mode is 0 for the RI and corresponds to the " +
416                 "next position to write to on Android.")
417    public void test_getChannel() throws Exception {
418        // Make sure that system properties are set correctly
419        if (tmpDir == null) {
420            throw new Exception("System property java.io.tmpdir not defined.");
421        }
422        File tmpfile = File.createTempFile("FileOutputStream", "tmp");
423        tmpfile.deleteOnExit();
424        FileOutputStream fos = new FileOutputStream(tmpfile);
425        byte[] b = new byte[10];
426        for (int i = 10; i < b.length; i++) {
427            b[i] = (byte) i;
428        }
429        fos.write(b);
430        fos.flush();
431        fos.close();
432        FileOutputStream f = new FileOutputStream(tmpfile, true);
433        assertEquals(10, f.getChannel().position());
434    }
435
436    /**
437     * Tears down the fixture, for example, close a network connection. This
438     * method is called after a test is executed.
439     */
440    protected void tearDown() throws Exception {
441        super.tearDown();
442        try {
443            if (f != null)
444                f.delete();
445            if (fis != null)
446                fis.close();
447            if (fos != null)
448                fos.close();
449        } catch (Exception e) {}
450    }
451}
452