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; 2084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport static org.junit.Assert.assertEquals; 2184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport static org.junit.Assert.assertFalse; 2284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport static org.junit.Assert.assertTrue; 2384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 24b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tanimport android.content.SharedPreferences; 2584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport android.net.Uri; 26edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport android.os.AsyncTask; 27b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tanimport android.support.test.InstrumentationRegistry; 2884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport android.support.test.filters.SmallTest; 2984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport android.support.test.runner.AndroidJUnit4; 3084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 31edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport com.android.documentsui.testing.TestScheduledExecutorService; 3284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 33edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport org.junit.AfterClass; 3484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport org.junit.Before; 3584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport org.junit.Rule; 3684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport org.junit.Test; 3784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport org.junit.rules.TemporaryFolder; 3884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKayimport org.junit.runner.RunWith; 3984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 40edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport java.io.File; 41edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport java.util.ArrayList; 42b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tanimport java.util.Iterator; 43edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanimport java.util.List; 44edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan 4584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay@RunWith(AndroidJUnit4.class) 4684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay@SmallTest 4784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKaypublic class ClipStorageTest { 48b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan private static final String PREF_NAME = "pref"; 4984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay private static final List<Uri> TEST_URIS = createList( 5084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay "content://ham/fancy", 5184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay "content://poodle/monkey/giraffe"); 5284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 5384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay @Rule 5484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay public TemporaryFolder folder = new TemporaryFolder(); 5584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 56b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan private SharedPreferences mPref; 57edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan private TestScheduledExecutorService mExecutor; 5884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay private ClipStorage mStorage; 5984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 60c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay private int mSlot; 61edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan 6284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay @Before 6384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay public void setUp() { 64b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan mPref = InstrumentationRegistry.getContext().getSharedPreferences(PREF_NAME, 0); 6584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay File clipDir = ClipStorage.prepareStorage(folder.getRoot()); 66b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan mStorage = new ClipStorage(clipDir, mPref); 67edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan 68edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan mExecutor = new TestScheduledExecutorService(); 69edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan AsyncTask.setDefaultExecutor(mExecutor); 70edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan 71c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay mSlot = mStorage.claimStorageSlot(); 72edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan } 73edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan 74edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan @AfterClass 75edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan public static void tearDownOnce() { 76edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan AsyncTask.setDefaultExecutor(AsyncTask.SERIAL_EXECUTOR); 7784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay } 7884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 7984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay @Test 80edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan public void testWrite() throws Exception { 81c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay writeAll(mSlot, TEST_URIS); 8284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay } 8384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 8484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay @Test 8584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay public void testRead() throws Exception { 86c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay writeAll(mSlot, TEST_URIS); 87edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan List<Uri> uris = new ArrayList<>(); 88b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan 89c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay File copy = mStorage.getFile(mSlot); 909666ce691a4d45344460f17cec3577dbe075235aGarfield, Tan try(ClipStorageReader provider = mStorage.createReader(copy)) { 91edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan for (Uri uri : provider) { 92edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan uris.add(uri); 93edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan } 94edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan } 9584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay assertEquals(TEST_URIS, uris); 9684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay } 9784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 9884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay @Test 999666ce691a4d45344460f17cec3577dbe075235aGarfield, Tan public void testClaimStorageSlot_NoAvailableSlot() throws Exception { 100c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay int firstSlot = mStorage.claimStorageSlot(); 101c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay writeAll(firstSlot, TEST_URIS); 102c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay mStorage.getFile(firstSlot); 103b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan for (int i = 0; i < NUM_OF_SLOTS - 1; ++i) { 104c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay int slot = mStorage.claimStorageSlot(); 105c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay writeAll(slot, TEST_URIS); 106c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay mStorage.getFile(slot); 107b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan } 108b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan 109c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay assertEquals(firstSlot, mStorage.claimStorageSlot()); 110b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan } 111b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan 112b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan @Test 113b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan public void testReadConcurrently() throws Exception { 114c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay writeAll(mSlot, TEST_URIS); 115b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan List<Uri> uris = new ArrayList<>(); 116b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan List<Uri> uris2 = new ArrayList<>(); 117b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan 118c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay File copy = mStorage.getFile(mSlot); 119c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay File copy2 = mStorage.getFile(mSlot); 1209666ce691a4d45344460f17cec3577dbe075235aGarfield, Tan try(ClipStorageReader reader = mStorage.createReader(copy)) { 1219666ce691a4d45344460f17cec3577dbe075235aGarfield, Tan try(ClipStorageReader reader2 = mStorage.createReader(copy2)){ 122b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan Iterator<Uri> iter = reader.iterator(); 123b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan Iterator<Uri> iter2 = reader2.iterator(); 124b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan 125b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan while (iter.hasNext() && iter2.hasNext()) { 126b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan uris.add(iter.next()); 127b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan uris2.add(iter2.next()); 128b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan } 129b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan 130b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan assertFalse(iter.hasNext()); 131b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan assertFalse(iter2.hasNext()); 132b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan } 133b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan } 134b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan assertEquals(TEST_URIS, uris); 135b7e5f6b55f5075e4752bd94586211fae9af2bae0Garfield, Tan assertEquals(TEST_URIS, uris2); 13684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay } 13784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 13884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay @Test 13984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay public void testPrepareStorage_CreatesDir() throws Exception { 14084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay File clipDir = ClipStorage.prepareStorage(folder.getRoot()); 14184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay assertTrue(clipDir.exists()); 14284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay assertTrue(clipDir.isDirectory()); 14384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay assertFalse(clipDir.equals(folder.getRoot())); 14484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay } 14584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 146c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay private void writeAll(int slot, List<Uri> uris) { 147c8889af6757ecb348fb8fd6dadf84d67d3478cbfSteve McKay mStorage.persistUris(uris, slot); 148edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan mExecutor.runAll(); 14984769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay } 15084769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay 15184769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay private static List<Uri> createList(String... values) { 15284769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay List<Uri> uris = new ArrayList<>(values.length); 15384769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay for (int i = 0; i < values.length; i++) { 15484769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay uris.add(i, Uri.parse(values[i])); 15584769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay } 15684769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay return uris; 15784769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay } 15884769b8205cf4a100c9d4f65c41cf72ba7a3b40fSteve McKay} 159