144235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar/* 244235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * Copyright 2018 The Android Open Source Project 344235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * 444235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * Licensed under the Apache License, Version 2.0 (the "License"); 544235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * you may not use this file except in compliance with the License. 644235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * You may obtain a copy of the License at 744235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * 844235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * http://www.apache.org/licenses/LICENSE-2.0 944235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * 1044235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * Unless required by applicable law or agreed to in writing, software 1144235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * distributed under the License is distributed on an "AS IS" BASIS, 1244235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1344235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * See the License for the specific language governing permissions and 1444235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar * limitations under the License. 1544235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar */ 1644235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 17564e43098c323d1a90be53c190b8fdbdde973505Sumir Katariapackage androidx.work.impl; 1844235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 1987d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport static org.hamcrest.CoreMatchers.is; 2087e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport static org.hamcrest.CoreMatchers.not; 2187d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport static org.hamcrest.CoreMatchers.notNullValue; 2287d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport static org.hamcrest.CoreMatchers.nullValue; 2387d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport static org.hamcrest.MatcherAssert.assertThat; 2487e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport static org.hamcrest.Matchers.contains; 2587d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport static org.hamcrest.Matchers.containsInAnyOrder; 260c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumarimport static org.mockito.Mockito.mock; 2787d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport static org.mockito.Mockito.spy; 2844235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumarimport static org.mockito.Mockito.times; 2944235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumarimport static org.mockito.Mockito.verify; 300c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumarimport static org.mockito.Mockito.when; 3144235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 3287d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport android.arch.core.executor.ArchTaskExecutor; 3387d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport android.arch.lifecycle.Lifecycle; 3487d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport android.content.Context; 3587d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport android.support.annotation.NonNull; 3687d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport android.support.test.InstrumentationRegistry; 372574ac4ac18d2bb4ceeae795a213d86c3a70fc68Rahul Ravikumarimport android.support.test.filters.LargeTest; 3844235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumarimport android.support.test.filters.SmallTest; 3944235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumarimport android.support.test.runner.AndroidJUnit4; 4044235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 417f44b37e7640e4b91656e024d1754fa7a062a833Sumir Katariaimport androidx.work.Configuration; 4264e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Katariaimport androidx.work.Data; 437031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumarimport androidx.work.OneTimeWorkRequest; 4487e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport androidx.work.State; 4587e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport androidx.work.TestLifecycleOwner; 4687e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport androidx.work.WorkContinuation; 4787e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport androidx.work.WorkManagerTest; 485a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumarimport androidx.work.WorkStatus; 4987e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport androidx.work.impl.model.WorkSpec; 5087e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport androidx.work.impl.model.WorkSpecDao; 5187e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport androidx.work.impl.utils.taskexecutor.InstantTaskExecutorRule; 5287e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport androidx.work.worker.TestWorker; 5387e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria 5487d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport org.junit.After; 5544235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumarimport org.junit.Before; 5687d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport org.junit.Rule; 5744235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumarimport org.junit.Test; 5844235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumarimport org.junit.runner.RunWith; 590c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumarimport org.mockito.ArgumentCaptor; 6044235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 615a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumarimport java.util.ArrayList; 6287e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariaimport java.util.Arrays; 6351b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Katariaimport java.util.Collections; 640c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumarimport java.util.HashSet; 6587d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumarimport java.util.List; 660c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumarimport java.util.Set; 67fa284c943bd003ff03f1934370d70bd4a5e034c3Sumir Katariaimport java.util.UUID; 68137c84c9c8212a44ee81c238a1a2271637ffa24bSumir Katariaimport java.util.concurrent.Executors; 6987d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar 7044235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 7144235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar@RunWith(AndroidJUnit4.class) 7244235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar@SmallTest 7387e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Katariapublic class WorkContinuationImplTest extends WorkManagerTest { 7444235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 75e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar private Configuration mConfiguration; 7687d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar private WorkDatabase mDatabase; 7744235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar private WorkManagerImpl mWorkManagerImpl; 780c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar private Scheduler mScheduler; 7987d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar 8087d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar @Rule 8187d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public InstantTaskExecutorRule mRule = new InstantTaskExecutorRule(); 8244235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 8344235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar @Before 8487d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public void setUp() { 8587d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar ArchTaskExecutor.getInstance().setDelegate(new android.arch.core.executor.TaskExecutor() { 8687d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar @Override 8787d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public void executeOnDiskIO(@NonNull Runnable runnable) { 8887d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar runnable.run(); 8987d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar } 9087d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar 9187d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar @Override 9287d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public void postToMainThread(@NonNull Runnable runnable) { 9387d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar runnable.run(); 9487d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar } 9587d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar 9687d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar @Override 9787d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public boolean isMainThread() { 9887d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar return true; 9987d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar } 10087d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar }); 10187d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar 10287d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner(); 10387d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar lifecycleOwner.mLifecycleRegistry.markState(Lifecycle.State.CREATED); 10487d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar 1050c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar mScheduler = mock(Scheduler.class); 10687d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar Context context = InstrumentationRegistry.getTargetContext(); 107e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar mConfiguration = new Configuration.Builder() 108b9490b789c8cba57b58cb8404463c0b83fb89074Rahul Ravikumar .setExecutor(Executors.newSingleThreadExecutor()) 1097f44b37e7640e4b91656e024d1754fa7a062a833Sumir Kataria .build(); 1100c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar 111e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar mWorkManagerImpl = spy(new WorkManagerImpl(context, mConfiguration)); 1120c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar when(mWorkManagerImpl.getSchedulers()).thenReturn(Collections.singletonList(mScheduler)); 113cc86a28f45a8393bb14b1945dfe5b35ec44a190bSumir Kataria WorkManagerImpl.setDelegate(mWorkManagerImpl); 11487d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar mDatabase = mWorkManagerImpl.getWorkDatabase(); 11587d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar } 11687d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar 11787d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar @After 11887d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public void tearDown() { 11987d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar List<String> ids = mDatabase.workSpecDao().getAllWorkSpecIds(); 12087d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar for (String id : ids) { 121fa284c943bd003ff03f1934370d70bd4a5e034c3Sumir Kataria mWorkManagerImpl.cancelWorkByIdSync(UUID.fromString(id)); 12287d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar } 123cc86a28f45a8393bb14b1945dfe5b35ec44a190bSumir Kataria WorkManagerImpl.setDelegate(null); 12487d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar ArchTaskExecutor.getInstance().setDelegate(null); 12544235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar } 12644235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 12744235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar @Test 12887d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public void testContinuation_noParent() { 1297031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest testWork = createTestWorker(); 13087d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar WorkContinuationImpl continuation = 13151b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria new WorkContinuationImpl(mWorkManagerImpl, Collections.singletonList(testWork)); 13244235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 13359cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar assertThat(continuation.getParents(), is(nullValue())); 13459cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar assertThat(continuation.getIds().size(), is(1)); 135fa284c943bd003ff03f1934370d70bd4a5e034c3Sumir Kataria assertThat(continuation.getIds().get(0), is(testWork.getStringId())); 13687d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar assertThat(continuation.getAllIds().size(), is(1)); 13744235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar } 13844235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 13944235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar @Test 14087d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public void testContinuation_singleChain() { 1417031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest testWork = createTestWorker(); 1427031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest dependentWork = createTestWorker(); 143b776ef68aac1def7eeda4a1f14b7364009302982Sumir Kataria WorkContinuationImpl continuation = 14451b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria new WorkContinuationImpl(mWorkManagerImpl, Collections.singletonList(testWork)); 145b776ef68aac1def7eeda4a1f14b7364009302982Sumir Kataria WorkContinuationImpl dependent = (WorkContinuationImpl) (continuation.then( 14644235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar dependentWork)); 14744235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 14859cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar assertThat(dependent.getParents(), containsInAnyOrder(continuation)); 14959cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar assertThat(dependent.getIds().size(), is(1)); 150fa284c943bd003ff03f1934370d70bd4a5e034c3Sumir Kataria assertThat(dependent.getIds().get(0), is(dependentWork.getStringId())); 15187d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar assertThat(dependent.getAllIds().size(), is(2)); 15287d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar assertThat( 15387d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar dependent.getAllIds(), 154fa284c943bd003ff03f1934370d70bd4a5e034c3Sumir Kataria containsInAnyOrder(dependentWork.getStringId(), testWork.getStringId())); 15544235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar } 15644235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 15744235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar @Test 15887d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public void testContinuation_enqueue() { 159b776ef68aac1def7eeda4a1f14b7364009302982Sumir Kataria WorkContinuationImpl continuation = new WorkContinuationImpl(mWorkManagerImpl, 16051b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 16187d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar assertThat(continuation.isEnqueued(), is(false)); 16262e0be94ea7e54ca9227564b14c1c6736ae770f7Sumir Kataria continuation.enqueueSync(); 16344235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar verifyEnqueued(continuation); 1640c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar verifyScheduled(mScheduler, continuation); 16544235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar } 16644235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 16744235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar @Test 16887d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public void testContinuation_chainEnqueue() { 169b776ef68aac1def7eeda4a1f14b7364009302982Sumir Kataria WorkContinuationImpl continuation = 17051b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria new WorkContinuationImpl(mWorkManagerImpl, createTestWorkerList()); 171b776ef68aac1def7eeda4a1f14b7364009302982Sumir Kataria WorkContinuationImpl chain = (WorkContinuationImpl) ( 17244235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar continuation.then(createTestWorker()).then(createTestWorker(), createTestWorker())); 17362e0be94ea7e54ca9227564b14c1c6736ae770f7Sumir Kataria chain.enqueueSync(); 17444235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar verifyEnqueued(continuation); 1750c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar verifyScheduled(mScheduler, continuation); 17644235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar } 17744235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 17844235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar @Test 17987d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar public void testContinuation_chainEnqueueNoOpOnRetry() { 180b776ef68aac1def7eeda4a1f14b7364009302982Sumir Kataria WorkContinuationImpl continuation = 18151b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria new WorkContinuationImpl(mWorkManagerImpl, createTestWorkerList()); 182b776ef68aac1def7eeda4a1f14b7364009302982Sumir Kataria WorkContinuationImpl chain = (WorkContinuationImpl) ( 18344235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar continuation.then(createTestWorker()).then(createTestWorker(), createTestWorker())); 18462e0be94ea7e54ca9227564b14c1c6736ae770f7Sumir Kataria chain.enqueueSync(); 18544235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar verifyEnqueued(continuation); 1860c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar verifyScheduled(mScheduler, continuation); 18787d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar WorkContinuationImpl spy = spy(chain); 18862e0be94ea7e54ca9227564b14c1c6736ae770f7Sumir Kataria spy.enqueueSync(); 18987d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar // Verify no more calls to markEnqueued(). 19087d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar verify(spy, times(0)).markEnqueued(); 19144235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar } 19244235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 19359cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar @Test 19459cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar public void testContinuation_join() { 19559cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar WorkContinuationImpl first = new WorkContinuationImpl(mWorkManagerImpl, 19651b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 19759cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar WorkContinuationImpl second = new WorkContinuationImpl(mWorkManagerImpl, 19851b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 199930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar 20055a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl dependent = (WorkContinuationImpl) WorkContinuation.combine(first, 20159cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar second); 20259cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar assertThat(dependent.getParents(), is(notNullValue())); 20359cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar assertThat(dependent.getParents(), containsInAnyOrder(first, second)); 20459cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar } 20559cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar 206930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar public void testContinuation_withWorkJoin() { 207930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar WorkContinuationImpl first = new WorkContinuationImpl(mWorkManagerImpl, 20851b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 209930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar WorkContinuationImpl second = new WorkContinuationImpl(mWorkManagerImpl, 21051b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 211930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar 2127031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest work = createTestWorker(); 213930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar 21455a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl dependent = (WorkContinuationImpl) WorkContinuation.combine( 21555a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria work, first, second); 216930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar 217fa284c943bd003ff03f1934370d70bd4a5e034c3Sumir Kataria assertThat(dependent.getIds(), containsInAnyOrder(work.getStringId())); 218930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar assertThat(dependent.getParents(), is(notNullValue())); 219930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar assertThat(dependent.getParents(), containsInAnyOrder(first, second)); 220930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar } 221930c8fb091c540642a0002e89eebb35c9eb88205Rahul Ravikumar 22259cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar @Test 22359cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar public void testContinuation_joinAndEnqueue() { 22459cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar WorkContinuationImpl first = new WorkContinuationImpl(mWorkManagerImpl, 22551b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 22659cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar WorkContinuationImpl second = new WorkContinuationImpl(mWorkManagerImpl, 22751b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 22859cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar 22959cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar WorkContinuationImpl third = new WorkContinuationImpl(mWorkManagerImpl, 23051b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 23159cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar WorkContinuationImpl fourth = new WorkContinuationImpl(mWorkManagerImpl, 23251b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 23359cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar 23455a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl firstDependent = (WorkContinuationImpl) WorkContinuation.combine( 23555a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria first, second); 23655a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl secondDependent = (WorkContinuationImpl) WorkContinuation.combine( 23755a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria third, fourth); 23855a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl dependent = (WorkContinuationImpl) WorkContinuation.combine( 23959cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar firstDependent, secondDependent); 24062e0be94ea7e54ca9227564b14c1c6736ae770f7Sumir Kataria dependent.enqueueSync(); 24159cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar verifyEnqueued(dependent); 2420c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar verifyScheduled(mScheduler, dependent); 24359cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar } 24459cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar 24559cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar @Test 24659cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar public void testContinuation_joinAndEnqueueWithOverlaps() { 24759cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar WorkContinuationImpl first = new WorkContinuationImpl(mWorkManagerImpl, 24851b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 24959cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar WorkContinuationImpl second = new WorkContinuationImpl(mWorkManagerImpl, 25051b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 25159cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar WorkContinuationImpl third = new WorkContinuationImpl(mWorkManagerImpl, 25251b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria createTestWorkerList()); 25355a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl firstDependent = (WorkContinuationImpl) WorkContinuation.combine( 25455a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria first, second); 25555a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl secondDependent = (WorkContinuationImpl) WorkContinuation.combine( 25655a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria first, third); 25755a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl dependent = (WorkContinuationImpl) WorkContinuation.combine( 25859cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar firstDependent, secondDependent); 25962e0be94ea7e54ca9227564b14c1c6736ae770f7Sumir Kataria dependent.enqueueSync(); 26059cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar verifyEnqueued(dependent); 2610c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar verifyScheduled(mScheduler, dependent); 26259cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar } 26359cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar 26487e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria @Test 2652574ac4ac18d2bb4ceeae795a213d86c3a70fc68Rahul Ravikumar @LargeTest 26687e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria @SuppressWarnings("unchecked") 26787e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria public void testContinuation_joinPassesAllOutput() throws InterruptedException { 26887e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria final String intTag = "myint"; 26987e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria final String stringTag = "mystring"; 27087e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria 2717031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest firstWork = new OneTimeWorkRequest.Builder(TestWorker.class) 27262a7e773945d980084dfc5d00c724de2e27dc22dSumir Kataria .setInitialState(State.SUCCEEDED) 27387e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria .build(); 2747031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest secondWork = new OneTimeWorkRequest.Builder(TestWorker.class) 27562a7e773945d980084dfc5d00c724de2e27dc22dSumir Kataria .setInitialState(State.SUCCEEDED) 27687e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria .build(); 27787e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria 27887e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 27987e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria workSpecDao.insertWorkSpec(getWorkSpec(firstWork)); 28087e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria workSpecDao.insertWorkSpec(getWorkSpec(secondWork)); 28187e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria 28287e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria workSpecDao.setOutput( 283fa284c943bd003ff03f1934370d70bd4a5e034c3Sumir Kataria firstWork.getStringId(), 28464e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria new Data.Builder().putInt(intTag, 0).build()); 28587e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria workSpecDao.setOutput( 286fa284c943bd003ff03f1934370d70bd4a5e034c3Sumir Kataria secondWork.getStringId(), 28764e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria new Data.Builder().putInt(intTag, 1).putString(stringTag, "hello").build()); 28887e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria 28987e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria WorkContinuationImpl firstContinuation = 29087e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria new WorkContinuationImpl(mWorkManagerImpl, Collections.singletonList(firstWork)); 29187e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria WorkContinuationImpl secondContinuation = 29287e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria new WorkContinuationImpl(mWorkManagerImpl, Collections.singletonList(secondWork)); 29387e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria WorkContinuationImpl dependentContinuation = 29455a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria (WorkContinuationImpl) WorkContinuation.combine( 29555a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria firstContinuation, secondContinuation); 29662e0be94ea7e54ca9227564b14c1c6736ae770f7Sumir Kataria dependentContinuation.enqueueSync(); 29787e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria 29887e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria String joinId = null; 29987e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria for (String id : dependentContinuation.getAllIds()) { 300fa284c943bd003ff03f1934370d70bd4a5e034c3Sumir Kataria if (!firstWork.getStringId().equals(id) && !secondWork.getStringId().equals(id)) { 30187e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria joinId = id; 30287e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria break; 30387e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria } 30487e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria } 30587e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria 3065f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria Thread.sleep(5000L); 3075f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria 3085f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria // TODO(sumir): I can't seem to get this kicked off automatically, so I'm running it myself. 3095f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria // Figure out what's going on here. 310e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar Context context = InstrumentationRegistry.getTargetContext(); 311e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar new WorkerWrapper.Builder(context, mConfiguration, mDatabase, joinId) 3125f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria .build() 3135f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria .run(); 3145f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria 31587e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria assertThat(joinId, is(not(nullValue()))); 3165f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria WorkSpec joinWorkSpec = mDatabase.workSpecDao().getWorkSpec(joinId); 31787e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria assertThat(joinWorkSpec, is(not(nullValue()))); 3185f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria assertThat(joinWorkSpec.state, is(State.SUCCEEDED)); 31987e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria 32064e6bd86c786f1cb1b0c3dbc2b5307cca5c0d1f6Sumir Kataria Data output = joinWorkSpec.output; 3215f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria int[] intArray = output.getIntArray(intTag); 3225f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria 3235f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria assertThat(intArray, is(not(nullValue()))); 3245f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria Arrays.sort(intArray); 3255f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria assertThat(Arrays.binarySearch(intArray, 0), is(not(-1))); 3265f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria assertThat(Arrays.binarySearch(intArray, 1), is(not(-1))); 32787e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria assertThat(output.getStringArray(stringTag), is(not(nullValue()))); 32887e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria assertThat(Arrays.asList(output.getStringArray(stringTag)), contains("hello")); 3295f5e7072d763d88253de1f3f092957b67f4cd8e4Sumir Kataria 33087e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria } 33187e8dc0458781cd41a5ee990be811790ac7f4e88Sumir Kataria 3322ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @Test 3332ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @SmallTest 33455a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria public void testContinuation_hasCycles() { 3357031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest aWork = createTestWorker(); // A 3367031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest bWork = createTestWorker(); // B 3377031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest cWork = createTestWorker(); // C 3382ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3392ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationA = new WorkContinuationImpl( 3402ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Collections.singletonList(aWork)); 3412ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3422ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationB = new WorkContinuationImpl( 3432ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Collections.singletonList(bWork)); 3442ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3452ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // B -> C 3462ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationBC = continuationB.then(cWork); 3472ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 34855a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria // combine -> A, C 34955a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuation join = WorkContinuation.combine(continuationA, continuationBC); 3502ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3512ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // withCycles -> B 3522ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuationImpl withCycles = (WorkContinuationImpl) join.then(bWork); 3532ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar assertThat(withCycles.hasCycles(), is(true)); 3542ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar } 3552ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3562ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @Test 3572ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @SmallTest 35855a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria public void testContinuation_hasCycles2() { 3597031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest aWork = createTestWorker(); // A 3602ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationA = new WorkContinuationImpl( 3612ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Collections.singletonList(aWork)); 3622ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3632ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A -> A 3642ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuationImpl withCycles = (WorkContinuationImpl) continuationA.then(aWork); 3652ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar assertThat(withCycles.hasCycles(), is(true)); 3662ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar } 3672ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3682ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @Test 3692ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @SmallTest 37055a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria public void testContinuation_hasCycles3() { 3717031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest aWork = createTestWorker(); // A 3722ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationA = new WorkContinuationImpl( 3732ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Collections.singletonList(aWork)); 3742ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3752ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A -> A 3762ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation first = continuationA.then(aWork); 3772ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A -> A 3782ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation second = continuationA.then(aWork); 3792ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A 3802ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A A 3812ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A 38255a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl joined = (WorkContinuationImpl) WorkContinuation.combine( 38355a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria first, second); 3842ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar assertThat(joined.hasCycles(), is(true)); 3852ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar } 3862ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3872ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @Test 3882ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @SmallTest 38955a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria public void testContinuation_hasCycles4() { 3907031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest aWork = createTestWorker(); // A 3917031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest cWork = createTestWorker(); // C 3922ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3932ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationA = new WorkContinuationImpl( 3942ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Collections.singletonList(aWork)); 3952ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 3962ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A A 3972ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // B 39855a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuation continuationB = WorkContinuation.combine(continuationA, continuationA); 3992ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A A 4002ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // B 4012ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // C 4022ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationC = continuationB.then(cWork); 4032ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A A 4042ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // B 4052ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // C 4062ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A 4072ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuationImpl withCycles = (WorkContinuationImpl) continuationC.then(aWork); 4082ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar assertThat(withCycles.hasCycles(), is(true)); 4092ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar } 4102ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4112ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @Test 4122ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @SmallTest 41355a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria public void testContinuation_hasNoCycles() { 4147031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest aWork = createTestWorker(); // A 4157031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest bWork = createTestWorker(); // B 4167031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest cWork = createTestWorker(); // C 4172ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4182ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationAB = new WorkContinuationImpl( 4192ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Arrays.asList(aWork, bWork)); 4202ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4212ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationBC = new WorkContinuationImpl( 4222ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Arrays.asList(bWork, cWork)); 4232ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4242ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuationImpl joined = 42555a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria (WorkContinuationImpl) WorkContinuation.combine(continuationAB, continuationBC); 4262ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4272ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar assertThat(joined.hasCycles(), is(false)); 4282ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar } 4292ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4302ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @Test 4312ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @SmallTest 43255a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria public void testContinuation_hasNoCycles2() { 4337031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest aWork = createTestWorker(); // A 4347031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest bWork = createTestWorker(); // B 4357031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest cWork = createTestWorker(); // C 4362ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4372ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationA = new WorkContinuationImpl( 4382ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Collections.singletonList(aWork)); 4392ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4402ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A -> B 4412ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationB = continuationA.then(bWork); 4422ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A -> C 4432ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationC = continuationA.then(cWork); 4442ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4452ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationA2 = new WorkContinuationImpl( 4462ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Collections.singletonList(aWork)); 4472ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A -> B 4482ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationB2 = continuationA2.then(bWork); 4492ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A -> C 4502ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationC2 = continuationA2.then(cWork); 4512ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4522ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // A A 4532ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // B C B C 4542ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar // D 45555a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl joined = (WorkContinuationImpl) WorkContinuation.combine( 45655a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria continuationB, continuationC, continuationB2, continuationC2); 4572ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4582ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar assertThat(joined.hasCycles(), is(false)); 4592ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar } 4602ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4612ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @Test 4622ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar @SmallTest 46355a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria public void testContinuation_hasNoCycles3() { 4647031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest aWork = createTestWorker(); // A 4657031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest bWork = createTestWorker(); // B 4667031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar OneTimeWorkRequest cWork = createTestWorker(); // C 4672ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4682ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationA = new WorkContinuationImpl( 4692ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Collections.singletonList(aWork)); 4702ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4712ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationB = new WorkContinuationImpl( 4722ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Collections.singletonList(bWork)); 4732ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4742ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar WorkContinuation continuationC = new WorkContinuationImpl( 4752ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar mWorkManagerImpl, Collections.singletonList(cWork)); 4762ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 47755a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuation first = WorkContinuation.combine(continuationA, continuationB); 47855a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuation second = WorkContinuation.combine(continuationA, continuationC); 4792ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 48055a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria WorkContinuationImpl joined = (WorkContinuationImpl) WorkContinuation.combine( 48155a030183e5b974f3ebf04ef5cd9ab83f3557dadSumir Kataria first, second); 4822ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar assertThat(joined.hasCycles(), is(false)); 4832ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar } 4842ca6b2dec030049de439acaa719e321252af4413Rahul Ravikumar 4855a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar @Test 4865a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar @SmallTest 4875a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar public void testGetStatusesSync() { 4885a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar OneTimeWorkRequest aWork = createTestWorker(); // A 4895a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar OneTimeWorkRequest bWork = createTestWorker(); // B 4905a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar OneTimeWorkRequest cWork = createTestWorker(); // C 4915a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar OneTimeWorkRequest dWork = createTestWorker(); // D 4925a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar 4935a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar WorkContinuation firstChain = mWorkManagerImpl.beginWith(aWork).then(bWork); 4945a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar WorkContinuation secondChain = mWorkManagerImpl.beginWith(cWork); 4955a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar WorkContinuation combined = WorkContinuation.combine(dWork, firstChain, secondChain); 4965a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar 4975a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar combined.synchronous().enqueueSync(); 4985a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar List<WorkStatus> statuses = combined.synchronous().getStatusesSync(); 4995a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar assertThat(statuses, is(notNullValue())); 5005a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar List<UUID> ids = new ArrayList<>(statuses.size()); 5015a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar for (WorkStatus status : statuses) { 5025a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar ids.add(status.getId()); 5035a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar } 5045a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar assertThat(ids, containsInAnyOrder( 5055a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar aWork.getId(), bWork.getId(), cWork.getId(), dWork.getId())); 5065a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar } 5075a4ced8020d8a3ee4b9100b97559db3d1fb5132bRahul Ravikumar 5080c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar private static void verifyEnqueued(WorkContinuationImpl continuation) { 50987d37e5587b277ba523d69df71e17a4039274cdaRahul Ravikumar assertThat(continuation.isEnqueued(), is(true)); 51059cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar List<WorkContinuationImpl> parents = continuation.getParents(); 51159cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar if (parents != null) { 51259cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar for (WorkContinuationImpl parent : parents) { 51359cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar verifyEnqueued(parent); 51459cbb5756e54d32fb51e72fe1ed94934c93f7303Rahul Ravikumar } 51544235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar } 51644235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar } 51744235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar 5180c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar private static void verifyScheduled(Scheduler scheduler, WorkContinuationImpl continuation) { 519e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar Configuration configuration = continuation.getWorkManagerImpl().getConfiguration(); 5200c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar ArgumentCaptor<WorkSpec> captor = ArgumentCaptor.forClass(WorkSpec.class); 5210c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar verify(scheduler, times(1)).schedule(captor.capture()); 5220c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar List<WorkSpec> workSpecs = captor.getAllValues(); 5230c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar assertThat(workSpecs, notNullValue()); 5240c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar 5250c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar WorkDatabase workDatabase = continuation.getWorkManagerImpl().getWorkDatabase(); 5260c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar List<WorkSpec> eligibleWorkSpecs = 527e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar workDatabase 528e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar .workSpecDao() 529e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar .getEligibleWorkForScheduling( 530e326592ec414dfe4c002e2840d9fc4aef0ee8747Rahul Ravikumar configuration.getMaxSchedulerLimit()); 5310c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar 5320c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar Set<String> capturedIds = new HashSet<>(); 5330c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar for (WorkSpec workSpec : workSpecs) { 5340c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar capturedIds.add(workSpec.id); 5350c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar } 5360c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar 5370c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar for (WorkSpec eligibleWorkSpec : eligibleWorkSpecs) { 5380c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar assertThat(capturedIds.contains(eligibleWorkSpec.id), is(true)); 5390c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar } 5400c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar } 5410c252a21d65ac58c2a19540bd6af9ffdd77b1e94Rahul Ravikumar 5427031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar private static OneTimeWorkRequest createTestWorker() { 5437031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar return new OneTimeWorkRequest.Builder(TestWorker.class).build(); 54444235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar } 54551b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria 5467031a0fbe12b8159ab2dc6d9c50be5b3f38477faRahul Ravikumar private static List<OneTimeWorkRequest> createTestWorkerList() { 54751b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria return Collections.singletonList(createTestWorker()); 54851b5cd2bc8a7fb7979e2bcd731fc8fd0d195f860Sumir Kataria } 54944235b3ed93a4783f6bb1f3979779ee039289bfcRahul Ravikumar} 550