ClipStorageTest.java revision 9666ce691a4d45344460f17cec3577dbe075235a
184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay/*
284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay * Copyright (C) 2016 The Android Open Source Project
384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay *
484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay * Licensed under the Apache License, Version 2.0 (the "License");
584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay * you may not use this file except in compliance with the License.
684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay * You may obtain a copy of the License at
784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay *
884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay *      http://www.apache.org/licenses/LICENSE-2.0
984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay *
1084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay * Unless required by applicable law or agreed to in writing, software
1184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay * distributed under the License is distributed on an "AS IS" BASIS,
1284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay * See the License for the specific language governing permissions and
1484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay * limitations under the License.
1584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay */
1684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
179666ce691a4d45344460f17cec3577dbe075235aGarfield, Tanpackage com.android.documentsui.clipping;
1884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
199666ce691a4d45344460f17cec3577dbe075235aGarfield, Tanimport static com.android.documentsui.clipping.ClipStorage.NUM_OF_SLOTS;
20b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan
2184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport static org.junit.Assert.assertEquals;
2284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport static org.junit.Assert.assertFalse;
2384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport static org.junit.Assert.assertTrue;
2484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
25b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tanimport android.content.SharedPreferences;
2684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport android.net.Uri;
27edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport android.os.AsyncTask;
28b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tanimport android.support.test.InstrumentationRegistry;
2984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport android.support.test.filters.SmallTest;
3084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport android.support.test.runner.AndroidJUnit4;
3184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
32edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport com.android.documentsui.testing.TestScheduledExecutorService;
3384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
34edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport org.junit.AfterClass;
3584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport org.junit.Before;
3684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport org.junit.Rule;
3784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport org.junit.Test;
3884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport org.junit.rules.TemporaryFolder;
3984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport org.junit.runner.RunWith;
4084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
41edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport java.io.File;
42edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport java.util.ArrayList;
43b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tanimport java.util.Iterator;
44edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport java.util.List;
45edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan
4684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay@RunWith(AndroidJUnit4.class)
4784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay@SmallTest
4884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKaypublic class ClipStorageTest {
49b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan    private static final String PREF_NAME = "pref";
5084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    private static final List<Uri> TEST_URIS = createList(
5184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay            "content://ham/fancy",
5284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay            "content://poodle/monkey/giraffe");
5384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
5484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    @Rule
5584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    public TemporaryFolder folder = new TemporaryFolder();
5684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
57b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan    private SharedPreferences mPref;
58edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan    private TestScheduledExecutorService mExecutor;
5984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    private ClipStorage mStorage;
6084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
61b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan    private int mTag;
62edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan
6384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    @Before
6484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    public void setUp() {
65b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        mPref = InstrumentationRegistry.getContext().getSharedPreferences(PREF_NAME, 0);
6684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay        File clipDir = ClipStorage.prepareStorage(folder.getRoot());
67b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        mStorage = new ClipStorage(clipDir, mPref);
68edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan
69edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan        mExecutor = new TestScheduledExecutorService();
70edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan        AsyncTask.setDefaultExecutor(mExecutor);
71edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan
72b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        mTag = mStorage.claimStorageSlot();
73edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan    }
74edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan
75edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan    @AfterClass
76edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan    public static void tearDownOnce() {
77edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan        AsyncTask.setDefaultExecutor(AsyncTask.SERIAL_EXECUTOR);
7884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    }
7984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
8084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    @Test
81edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan    public void testWrite() throws Exception {
82edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan        writeAll(mTag, TEST_URIS);
8384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    }
8484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
8584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    @Test
8684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    public void testRead() throws Exception {
87edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan        writeAll(mTag, TEST_URIS);
88edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan        List<Uri> uris = new ArrayList<>();
89b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan
90b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        File copy = mStorage.getFile(mTag);
919666ce691a4d45344460f17cec3577dbe075235aGarfield, Tan        try(ClipStorageReader provider = mStorage.createReader(copy)) {
92edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan            for (Uri uri : provider) {
93edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan                uris.add(uri);
94edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan            }
95edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan        }
9684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay        assertEquals(TEST_URIS, uris);
9784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    }
9884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
9984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    @Test
1009666ce691a4d45344460f17cec3577dbe075235aGarfield, Tan    public void testClaimStorageSlot_NoAvailableSlot() throws Exception {
101b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        int firstTag = mStorage.claimStorageSlot();
102b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        writeAll(firstTag, TEST_URIS);
103b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        mStorage.getFile(firstTag);
104b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        for (int i = 0; i < NUM_OF_SLOTS - 1; ++i) {
105b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan            int tag = mStorage.claimStorageSlot();
106b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan            writeAll(tag, TEST_URIS);
107b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan            mStorage.getFile(tag);
108b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        }
109b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan
110b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        assertEquals(firstTag, mStorage.claimStorageSlot());
111b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan    }
112b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan
113b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan    @Test
114b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan    public void testReadConcurrently() throws Exception {
115edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan        writeAll(mTag, TEST_URIS);
116b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        List<Uri> uris = new ArrayList<>();
117b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        List<Uri> uris2 = new ArrayList<>();
118b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan
119b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        File copy = mStorage.getFile(mTag);
120b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        File copy2 = mStorage.getFile(mTag);
1219666ce691a4d45344460f17cec3577dbe075235aGarfield, Tan        try(ClipStorageReader reader = mStorage.createReader(copy)) {
1229666ce691a4d45344460f17cec3577dbe075235aGarfield, Tan            try(ClipStorageReader reader2 = mStorage.createReader(copy2)){
123b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan                Iterator<Uri> iter = reader.iterator();
124b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan                Iterator<Uri> iter2 = reader2.iterator();
125b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan
126b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan                while (iter.hasNext() && iter2.hasNext()) {
127b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan                    uris.add(iter.next());
128b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan                    uris2.add(iter2.next());
129b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan                }
130b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan
131b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan                assertFalse(iter.hasNext());
132b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan                assertFalse(iter2.hasNext());
133b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan            }
134b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        }
135b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        assertEquals(TEST_URIS, uris);
136b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan        assertEquals(TEST_URIS, uris2);
13784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    }
13884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
13984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    @Test
14084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    public void testPrepareStorage_CreatesDir() throws Exception {
14184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay        File clipDir = ClipStorage.prepareStorage(folder.getRoot());
14284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay        assertTrue(clipDir.exists());
14384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay        assertTrue(clipDir.isDirectory());
14484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay        assertFalse(clipDir.equals(folder.getRoot()));
14584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    }
14684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
147b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan    private void writeAll(int tag, List<Uri> uris) {
148edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan        new ClipStorage.PersistTask(mStorage, uris, tag).execute();
149edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan        mExecutor.runAll();
15084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    }
15184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay
15284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    private static List<Uri> createList(String... values) {
15384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay        List<Uri> uris = new ArrayList<>(values.length);
15484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay        for (int i = 0; i < values.length; i++) {
15584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay            uris.add(i, Uri.parse(values[i]));
15684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay        }
15784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay        return uris;
15884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay    }
15984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay}
160