178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey/*
278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey * Copyright (C) 2014 The Android Open Source Project
378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey *
478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey * you may not use this file except in compliance with the License.
678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey * You may obtain a copy of the License at
778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey *
878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey *
1078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey * Unless required by applicable law or agreed to in writing, software
1178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
1278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey * See the License for the specific language governing permissions and
1478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey * limitations under the License.
1578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey */
1678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
1778cc340c2de873d6995c283b777476f7237d690fJeff Sharkeypackage android.os;
1878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
1978cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport android.os.FileBridge.FileBridgeOutputStream;
2078cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport android.test.AndroidTestCase;
2178cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport android.test.MoreAsserts;
2278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
2378cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport libcore.io.Streams;
2478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
2578cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport java.io.ByteArrayOutputStream;
2678cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport java.io.File;
2778cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport java.io.FileInputStream;
2878cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport java.io.FileOutputStream;
2978cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport java.io.IOException;
3078cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport java.nio.charset.StandardCharsets;
3178cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport java.util.Random;
3278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
3378cc340c2de873d6995c283b777476f7237d690fJeff Sharkeypublic class FileBridgeTest extends AndroidTestCase {
3478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
3578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    private File file;
3678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    private FileOutputStream fileOs;
3778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    private FileBridge bridge;
3878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    private FileBridgeOutputStream client;
3978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
4078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    @Override
4178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    protected void setUp() throws Exception {
4278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        super.setUp();
4378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
4478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        file = getContext().getFileStreamPath("meow.dat");
4578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        file.delete();
4678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
4778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        fileOs = new FileOutputStream(file);
4878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
4978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        bridge = new FileBridge();
5078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        bridge.setTargetFile(fileOs.getFD());
5178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        bridge.start();
5278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client = new FileBridgeOutputStream(bridge.getClientSocket());
5378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
5478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
5578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    @Override
5678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    protected void tearDown() throws Exception {
5778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        fileOs.close();
5878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        file.delete();
5978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
6078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
6178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    private void assertOpen() throws Exception {
6278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertFalse("expected open", bridge.isClosed());
6378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
6478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
6578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    private void closeAndAssertClosed() throws Exception {
6678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.close();
6778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
6878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        // Wait a beat for things to settle down
6978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        SystemClock.sleep(200);
7078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertTrue("expected closed", bridge.isClosed());
7178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
7278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
7378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    private void assertContents(byte[] expected) throws Exception {
7478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        MoreAsserts.assertEquals(expected, Streams.readFully(new FileInputStream(file)));
7578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
7678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
7778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    public void testNoWriteNoSync() throws Exception {
7878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertOpen();
7978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        closeAndAssertClosed();
8078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
8178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
8278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    public void testNoWriteSync() throws Exception {
8378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertOpen();
8478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.flush();
8578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        closeAndAssertClosed();
8678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
8778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
8878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    public void testWriteNoSync() throws Exception {
8978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertOpen();
9078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.write("meow".getBytes(StandardCharsets.UTF_8));
9178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        closeAndAssertClosed();
9278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertContents("meow".getBytes(StandardCharsets.UTF_8));
9378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
9478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
9578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    public void testWriteSync() throws Exception {
9678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertOpen();
9778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.write("cake".getBytes(StandardCharsets.UTF_8));
9878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.flush();
9978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        closeAndAssertClosed();
10078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertContents("cake".getBytes(StandardCharsets.UTF_8));
10178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
10278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
10378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    public void testWriteSyncWrite() throws Exception {
10478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertOpen();
10578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.write("meow".getBytes(StandardCharsets.UTF_8));
10678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.flush();
10778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.write("cake".getBytes(StandardCharsets.UTF_8));
10878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        closeAndAssertClosed();
10978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertContents("meowcake".getBytes(StandardCharsets.UTF_8));
11078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
11178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
11278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    public void testEmptyWrite() throws Exception {
11378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertOpen();
11478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.write(new byte[0]);
11578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        closeAndAssertClosed();
11678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertContents(new byte[0]);
11778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
11878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
11978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    public void testWriteAfterClose() throws Exception {
12078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertOpen();
12178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.write("meow".getBytes(StandardCharsets.UTF_8));
12278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        closeAndAssertClosed();
12378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        try {
12478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey            client.write("cake".getBytes(StandardCharsets.UTF_8));
12578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey            fail("wrote after close!");
12678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        } catch (IOException expected) {
12778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        }
12878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertContents("meow".getBytes(StandardCharsets.UTF_8));
12978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
13078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
13178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    public void testRandomWrite() throws Exception {
13278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        final Random r = new Random();
13378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        final ByteArrayOutputStream result = new ByteArrayOutputStream();
13478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
13578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        for (int i = 0; i < 512; i++) {
13678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey            final byte[] test = new byte[r.nextInt(24169)];
13778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey            r.nextBytes(test);
13878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey            result.write(test);
13978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey            client.write(test);
14078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey            client.flush();
14178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        }
14278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
14378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        closeAndAssertClosed();
14478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertContents(result.toByteArray());
14578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
14678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
14778cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    public void testGiantWrite() throws Exception {
14878cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        final byte[] test = new byte[263401];
14978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        new Random().nextBytes(test);
15078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
15178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertOpen();
15278cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        client.write(test);
15378cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        closeAndAssertClosed();
15478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        assertContents(test);
15578cc340c2de873d6995c283b777476f7237d690fJeff Sharkey    }
15678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey}
157