1 /*
2  * Copyright (C) 2014 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 android.os;
18 
19 import static android.os.ParcelFileDescriptor.MODE_CREATE;
20 import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
21 
22 import android.os.FileBridge.FileBridgeOutputStream;
23 import android.test.AndroidTestCase;
24 import android.test.MoreAsserts;
25 
26 import libcore.io.Streams;
27 
28 import java.io.ByteArrayOutputStream;
29 import java.io.File;
30 import java.io.FileInputStream;
31 import java.io.IOException;
32 import java.nio.charset.StandardCharsets;
33 import java.util.Random;
34 
35 public class FileBridgeTest extends AndroidTestCase {
36 
37     private File file;
38     private ParcelFileDescriptor outputFile;
39     private FileBridge bridge;
40     private FileBridgeOutputStream client;
41 
42     @Override
setUp()43     protected void setUp() throws Exception {
44         super.setUp();
45 
46         file = getContext().getFileStreamPath("meow.dat");
47         file.delete();
48 
49         outputFile = ParcelFileDescriptor.open(file, MODE_CREATE | MODE_READ_WRITE);
50 
51         bridge = new FileBridge();
52         bridge.setTargetFile(outputFile);
53         bridge.start();
54         client = new FileBridgeOutputStream(bridge.getClientSocket());
55     }
56 
57     @Override
tearDown()58     protected void tearDown() throws Exception {
59         outputFile.close();
60         file.delete();
61     }
62 
assertOpen()63     private void assertOpen() throws Exception {
64         assertFalse("expected open", bridge.isClosed());
65     }
66 
closeAndAssertClosed()67     private void closeAndAssertClosed() throws Exception {
68         client.close();
69 
70         // Wait a beat for things to settle down
71         SystemClock.sleep(200);
72         assertTrue("expected closed", bridge.isClosed());
73     }
74 
assertContents(byte[] expected)75     private void assertContents(byte[] expected) throws Exception {
76         MoreAsserts.assertEquals(expected, Streams.readFully(new FileInputStream(file)));
77     }
78 
testNoWriteNoSync()79     public void testNoWriteNoSync() throws Exception {
80         assertOpen();
81         closeAndAssertClosed();
82     }
83 
testNoWriteSync()84     public void testNoWriteSync() throws Exception {
85         assertOpen();
86         client.flush();
87         closeAndAssertClosed();
88     }
89 
testWriteNoSync()90     public void testWriteNoSync() throws Exception {
91         assertOpen();
92         client.write("meow".getBytes(StandardCharsets.UTF_8));
93         closeAndAssertClosed();
94         assertContents("meow".getBytes(StandardCharsets.UTF_8));
95     }
96 
testWriteSync()97     public void testWriteSync() throws Exception {
98         assertOpen();
99         client.write("cake".getBytes(StandardCharsets.UTF_8));
100         client.flush();
101         closeAndAssertClosed();
102         assertContents("cake".getBytes(StandardCharsets.UTF_8));
103     }
104 
testWriteSyncWrite()105     public void testWriteSyncWrite() throws Exception {
106         assertOpen();
107         client.write("meow".getBytes(StandardCharsets.UTF_8));
108         client.flush();
109         client.write("cake".getBytes(StandardCharsets.UTF_8));
110         closeAndAssertClosed();
111         assertContents("meowcake".getBytes(StandardCharsets.UTF_8));
112     }
113 
testEmptyWrite()114     public void testEmptyWrite() throws Exception {
115         assertOpen();
116         client.write(new byte[0]);
117         closeAndAssertClosed();
118         assertContents(new byte[0]);
119     }
120 
testWriteAfterClose()121     public void testWriteAfterClose() throws Exception {
122         assertOpen();
123         client.write("meow".getBytes(StandardCharsets.UTF_8));
124         closeAndAssertClosed();
125         try {
126             client.write("cake".getBytes(StandardCharsets.UTF_8));
127             fail("wrote after close!");
128         } catch (IOException expected) {
129         }
130         assertContents("meow".getBytes(StandardCharsets.UTF_8));
131     }
132 
testRandomWrite()133     public void testRandomWrite() throws Exception {
134         final Random r = new Random();
135         final ByteArrayOutputStream result = new ByteArrayOutputStream();
136 
137         for (int i = 0; i < 512; i++) {
138             final byte[] test = new byte[r.nextInt(24169)];
139             r.nextBytes(test);
140             result.write(test);
141             client.write(test);
142             client.flush();
143         }
144 
145         closeAndAssertClosed();
146         assertContents(result.toByteArray());
147     }
148 
testGiantWrite()149     public void testGiantWrite() throws Exception {
150         final byte[] test = new byte[263401];
151         new Random().nextBytes(test);
152 
153         assertOpen();
154         client.write(test);
155         closeAndAssertClosed();
156         assertContents(test);
157     }
158 }
159