WorkManagerImplTest.java revision 1afd3cb3685451cf522c3ad54e1c9a2afe5a9549
1/* 2 * Copyright 2017 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 17package androidx.work.impl; 18 19import static androidx.work.ExistingWorkPolicy.APPEND; 20import static androidx.work.ExistingWorkPolicy.KEEP; 21import static androidx.work.ExistingWorkPolicy.REPLACE; 22import static androidx.work.NetworkType.METERED; 23import static androidx.work.NetworkType.NOT_REQUIRED; 24import static androidx.work.State.BLOCKED; 25import static androidx.work.State.CANCELLED; 26import static androidx.work.State.ENQUEUED; 27import static androidx.work.State.FAILED; 28import static androidx.work.State.RUNNING; 29import static androidx.work.State.SUCCEEDED; 30 31import static org.hamcrest.CoreMatchers.is; 32import static org.hamcrest.CoreMatchers.not; 33import static org.hamcrest.CoreMatchers.notNullValue; 34import static org.hamcrest.CoreMatchers.nullValue; 35import static org.hamcrest.MatcherAssert.assertThat; 36import static org.hamcrest.Matchers.containsInAnyOrder; 37import static org.hamcrest.Matchers.emptyCollectionOf; 38import static org.hamcrest.Matchers.greaterThanOrEqualTo; 39import static org.hamcrest.Matchers.isIn; 40import static org.hamcrest.Matchers.isOneOf; 41import static org.mockito.Mockito.clearInvocations; 42import static org.mockito.Mockito.mock; 43import static org.mockito.Mockito.times; 44import static org.mockito.Mockito.verify; 45 46import android.arch.core.executor.ArchTaskExecutor; 47import android.arch.core.executor.TaskExecutor; 48import android.arch.lifecycle.LiveData; 49import android.arch.lifecycle.Observer; 50import android.arch.persistence.db.SupportSQLiteDatabase; 51import android.arch.persistence.db.SupportSQLiteOpenHelper; 52import android.content.Context; 53import android.net.Uri; 54import android.os.Build; 55import android.provider.MediaStore; 56import android.support.annotation.NonNull; 57import android.support.test.InstrumentationRegistry; 58import android.support.test.filters.SdkSuppress; 59import android.support.test.filters.SmallTest; 60import android.support.test.runner.AndroidJUnit4; 61 62import androidx.work.Arguments; 63import androidx.work.BackoffPolicy; 64import androidx.work.BaseWork; 65import androidx.work.Constraints; 66import androidx.work.ContentUriTriggers; 67import androidx.work.PeriodicWork; 68import androidx.work.TestLifecycleOwner; 69import androidx.work.Work; 70import androidx.work.WorkContinuation; 71import androidx.work.WorkManagerTest; 72import androidx.work.WorkStatus; 73import androidx.work.impl.model.Dependency; 74import androidx.work.impl.model.DependencyDao; 75import androidx.work.impl.model.WorkName; 76import androidx.work.impl.model.WorkSpec; 77import androidx.work.impl.model.WorkSpecDao; 78import androidx.work.impl.model.WorkTag; 79import androidx.work.impl.model.WorkTagDao; 80import androidx.work.impl.utils.taskexecutor.InstantTaskExecutorRule; 81import androidx.work.worker.InfiniteTestWorker; 82import androidx.work.worker.TestWorker; 83 84import org.junit.After; 85import org.junit.Before; 86import org.junit.Rule; 87import org.junit.Test; 88import org.junit.runner.RunWith; 89import org.mockito.ArgumentCaptor; 90 91import java.util.Arrays; 92import java.util.Collections; 93import java.util.List; 94import java.util.concurrent.Executors; 95import java.util.concurrent.TimeUnit; 96 97@RunWith(AndroidJUnit4.class) 98public class WorkManagerImplTest extends WorkManagerTest { 99 private WorkDatabase mDatabase; 100 private WorkManagerImpl mWorkManagerImpl; 101 102 @Rule 103 public InstantTaskExecutorRule mRule = new InstantTaskExecutorRule(); 104 105 @Before 106 public void setUp() { 107 ArchTaskExecutor.getInstance().setDelegate(new TaskExecutor() { 108 @Override 109 public void executeOnDiskIO(@NonNull Runnable runnable) { 110 runnable.run(); 111 } 112 113 @Override 114 public void postToMainThread(@NonNull Runnable runnable) { 115 runnable.run(); 116 } 117 118 @Override 119 public boolean isMainThread() { 120 return true; 121 } 122 }); 123 124 Context context = InstrumentationRegistry.getTargetContext(); 125 WorkManagerConfiguration configuration = new WorkManagerConfiguration( 126 context, 127 true, 128 Executors.newSingleThreadExecutor()); 129 mWorkManagerImpl = new WorkManagerImpl(context, configuration); 130 mDatabase = mWorkManagerImpl.getWorkDatabase(); 131 } 132 133 @After 134 public void tearDown() { 135 List<String> ids = mDatabase.workSpecDao().getAllWorkSpecIds(); 136 for (String id : ids) { 137 mWorkManagerImpl.cancelWorkById(id); 138 } 139 mDatabase.close(); 140 ArchTaskExecutor.getInstance().setDelegate(null); 141 } 142 143 @Test 144 @SmallTest 145 public void testEnqueue_insertWork() throws InterruptedException { 146 final int workCount = 3; 147 final Work[] workArray = new Work[workCount]; 148 for (int i = 0; i < workCount; ++i) { 149 workArray[i] = new Work.Builder(TestWorker.class).build(); 150 } 151 mWorkManagerImpl.beginWith(workArray[0]).then(workArray[1]).then(workArray[2]).enqueue(); 152 153 for (int i = 0; i < workCount; ++i) { 154 String id = workArray[i].getId(); 155 assertThat(mDatabase.workSpecDao().getWorkSpec(id), is(notNullValue())); 156 assertThat( 157 "index " + i + " does not have expected number of dependencies!", 158 mDatabase.dependencyDao().getPrerequisites(id).size() > 0, 159 is(i > 0)); 160 } 161 } 162 163 @Test 164 @SmallTest 165 public void testEnqueue_insertMultipleWork() { 166 Work work1 = new Work.Builder(TestWorker.class).build(); 167 Work work2 = new Work.Builder(TestWorker.class).build(); 168 Work work3 = new Work.Builder(TestWorker.class).build(); 169 170 mWorkManagerImpl.enqueue(work1, work2, work3); 171 172 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 173 assertThat(workSpecDao.getWorkSpec(work1.getId()), is(notNullValue())); 174 assertThat(workSpecDao.getWorkSpec(work2.getId()), is(notNullValue())); 175 assertThat(workSpecDao.getWorkSpec(work3.getId()), is(notNullValue())); 176 } 177 178 @Test 179 @SmallTest 180 public void testEnqueue_insertWithDependencies() { 181 Work work1a = new Work.Builder(TestWorker.class).build(); 182 Work work1b = new Work.Builder(TestWorker.class).build(); 183 Work work2 = new Work.Builder(TestWorker.class).build(); 184 Work work3a = new Work.Builder(TestWorker.class).build(); 185 Work work3b = new Work.Builder(TestWorker.class).build(); 186 187 mWorkManagerImpl.beginWith(work1a, work1b).then(work2).then(work3a, work3b).enqueue(); 188 189 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 190 assertThat(workSpecDao.getWorkSpec(work1a.getId()), is(notNullValue())); 191 assertThat(workSpecDao.getWorkSpec(work1b.getId()), is(notNullValue())); 192 assertThat(workSpecDao.getWorkSpec(work2.getId()), is(notNullValue())); 193 assertThat(workSpecDao.getWorkSpec(work3a.getId()), is(notNullValue())); 194 assertThat(workSpecDao.getWorkSpec(work3b.getId()), is(notNullValue())); 195 196 DependencyDao dependencyDao = mDatabase.dependencyDao(); 197 assertThat(dependencyDao.getPrerequisites(work1a.getId()), 198 is(emptyCollectionOf(String.class))); 199 assertThat(dependencyDao.getPrerequisites(work1b.getId()), 200 is(emptyCollectionOf(String.class))); 201 202 List<String> prerequisites = dependencyDao.getPrerequisites(work2.getId()); 203 assertThat(prerequisites, containsInAnyOrder(work1a.getId(), work1b.getId())); 204 205 prerequisites = dependencyDao.getPrerequisites(work3a.getId()); 206 assertThat(prerequisites, containsInAnyOrder(work2.getId())); 207 208 prerequisites = dependencyDao.getPrerequisites(work3b.getId()); 209 assertThat(prerequisites, containsInAnyOrder(work2.getId())); 210 } 211 212 @Test 213 @SmallTest 214 public void testEnqueue_insertWithCompletedDependencies_isNotStatusBlocked() { 215 Work work1 = new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build(); 216 217 WorkContinuation workContinuation = mWorkManagerImpl.beginWith(work1); 218 workContinuation.enqueue(); 219 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 220 assertThat(workSpecDao.getState(work1.getId()), is(SUCCEEDED)); 221 222 Work work2 = new Work.Builder(InfiniteTestWorker.class).build(); 223 workContinuation.then(work2).enqueue(); 224 assertThat(workSpecDao.getState(work2.getId()), isOneOf(ENQUEUED, RUNNING)); 225 } 226 227 @Test 228 @SmallTest 229 public void testEnqueue_insertWithFailedDependencies_isStatusFailed() { 230 Work work1 = new Work.Builder(TestWorker.class).withInitialState(FAILED).build(); 231 232 WorkContinuation workContinuation = mWorkManagerImpl.beginWith(work1); 233 workContinuation.enqueue(); 234 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 235 assertThat(workSpecDao.getState(work1.getId()), is(FAILED)); 236 237 Work work2 = new Work.Builder(TestWorker.class).build(); 238 workContinuation.then(work2).enqueue(); 239 assertThat(workSpecDao.getState(work2.getId()), is(FAILED)); 240 } 241 242 @Test 243 @SmallTest 244 public void testEnqueue_insertWithCancelledDependencies_isStatusCancelled() { 245 Work work1 = new Work.Builder(TestWorker.class).withInitialState(CANCELLED).build(); 246 247 WorkContinuation workContinuation = mWorkManagerImpl.beginWith(work1); 248 workContinuation.enqueue(); 249 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 250 assertThat(workSpecDao.getState(work1.getId()), is(CANCELLED)); 251 252 Work work2 = new Work.Builder(TestWorker.class).build(); 253 workContinuation.then(work2).enqueue(); 254 assertThat(workSpecDao.getState(work2.getId()), is(CANCELLED)); 255 } 256 257 @Test 258 @SmallTest 259 @SdkSuppress(minSdkVersion = 23) 260 public void testEnqueue_insertWorkConstraints() { 261 Uri testUri1 = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 262 Uri testUri2 = MediaStore.Images.Media.INTERNAL_CONTENT_URI; 263 264 Work work0 = new Work.Builder(TestWorker.class) 265 .withConstraints( 266 new Constraints.Builder() 267 .setRequiresCharging(true) 268 .setRequiresDeviceIdle(true) 269 .setRequiredNetworkType(METERED) 270 .setRequiresBatteryNotLow(true) 271 .setRequiresStorageNotLow(true) 272 .addContentUriTrigger(testUri1, true) 273 .addContentUriTrigger(testUri2, false) 274 .build()) 275 .build(); 276 Work work1 = new Work.Builder(TestWorker.class).build(); 277 mWorkManagerImpl.beginWith(work0).then(work1).enqueue(); 278 279 WorkSpec workSpec0 = mDatabase.workSpecDao().getWorkSpec(work0.getId()); 280 WorkSpec workSpec1 = mDatabase.workSpecDao().getWorkSpec(work1.getId()); 281 282 ContentUriTriggers expectedTriggers = new ContentUriTriggers(); 283 expectedTriggers.add(testUri1, true); 284 expectedTriggers.add(testUri2, false); 285 286 Constraints constraints = workSpec0.getConstraints(); 287 assertThat(constraints, is(notNullValue())); 288 assertThat(constraints.requiresCharging(), is(true)); 289 assertThat(constraints.requiresDeviceIdle(), is(true)); 290 assertThat(constraints.requiresBatteryNotLow(), is(true)); 291 assertThat(constraints.requiresStorageNotLow(), is(true)); 292 assertThat(constraints.getRequiredNetworkType(), is(METERED)); 293 if (Build.VERSION.SDK_INT >= 24) { 294 assertThat(constraints.getContentUriTriggers(), is(expectedTriggers)); 295 } else { 296 assertThat(constraints.getContentUriTriggers(), is(new ContentUriTriggers())); 297 } 298 299 constraints = workSpec1.getConstraints(); 300 assertThat(constraints, is(notNullValue())); 301 assertThat(constraints.requiresCharging(), is(false)); 302 assertThat(constraints.requiresDeviceIdle(), is(false)); 303 assertThat(constraints.requiresBatteryNotLow(), is(false)); 304 assertThat(constraints.requiresStorageNotLow(), is(false)); 305 assertThat(constraints.getRequiredNetworkType(), is(NOT_REQUIRED)); 306 assertThat(constraints.getContentUriTriggers().size(), is(0)); 307 } 308 309 @Test 310 @SmallTest 311 public void testEnqueue_insertWorkInitialDelay() { 312 final long expectedInitialDelay = 5000L; 313 Work work0 = new Work.Builder(TestWorker.class) 314 .withInitialDelay(expectedInitialDelay, TimeUnit.MILLISECONDS) 315 .build(); 316 Work work1 = new Work.Builder(TestWorker.class).build(); 317 mWorkManagerImpl.beginWith(work0).then(work1).enqueue(); 318 319 WorkSpec workSpec0 = mDatabase.workSpecDao().getWorkSpec(work0.getId()); 320 WorkSpec workSpec1 = mDatabase.workSpecDao().getWorkSpec(work1.getId()); 321 322 assertThat(workSpec0.getInitialDelay(), is(expectedInitialDelay)); 323 assertThat(workSpec1.getInitialDelay(), is(0L)); 324 } 325 326 @Test 327 @SmallTest 328 public void testEnqueue_insertWorkBackoffPolicy() { 329 Work work0 = new Work.Builder(TestWorker.class) 330 .withBackoffCriteria(BackoffPolicy.LINEAR, 50000, TimeUnit.MILLISECONDS) 331 .build(); 332 Work work1 = new Work.Builder(TestWorker.class).build(); 333 mWorkManagerImpl.beginWith(work0).then(work1).enqueue(); 334 335 WorkSpec workSpec0 = mDatabase.workSpecDao().getWorkSpec(work0.getId()); 336 WorkSpec workSpec1 = mDatabase.workSpecDao().getWorkSpec(work1.getId()); 337 338 assertThat(workSpec0.getBackoffPolicy(), is(BackoffPolicy.LINEAR)); 339 assertThat(workSpec0.getBackoffDelayDuration(), is(50000L)); 340 341 assertThat(workSpec1.getBackoffPolicy(), is(BackoffPolicy.EXPONENTIAL)); 342 assertThat(workSpec1.getBackoffDelayDuration(), is(BaseWork.DEFAULT_BACKOFF_DELAY_MILLIS)); 343 } 344 345 @Test 346 @SmallTest 347 public void testEnqueue_insertWorkTags() { 348 final String firstTag = "first_tag"; 349 final String secondTag = "second_tag"; 350 final String thirdTag = "third_tag"; 351 352 Work work0 = new Work.Builder(TestWorker.class).addTag(firstTag).addTag(secondTag).build(); 353 Work work1 = new Work.Builder(TestWorker.class).addTag(firstTag).build(); 354 Work work2 = new Work.Builder(TestWorker.class).build(); 355 mWorkManagerImpl.beginWith(work0).then(work1).then(work2).enqueue(); 356 357 WorkTagDao workTagDao = mDatabase.workTagDao(); 358 assertThat(workTagDao.getWorkSpecIdsWithTag(firstTag), 359 containsInAnyOrder(work0.getId(), work1.getId())); 360 assertThat(workTagDao.getWorkSpecIdsWithTag(secondTag), containsInAnyOrder(work0.getId())); 361 assertThat(workTagDao.getWorkSpecIdsWithTag(thirdTag), emptyCollectionOf(String.class)); 362 } 363 364 @Test 365 @SmallTest 366 public void testEnqueue_insertPeriodicWork() { 367 PeriodicWork periodicWork = new PeriodicWork.Builder( 368 TestWorker.class, 369 PeriodicWork.MIN_PERIODIC_INTERVAL_MILLIS, 370 TimeUnit.MILLISECONDS) 371 .build(); 372 mWorkManagerImpl.enqueue(periodicWork); 373 374 WorkSpec workSpec = mDatabase.workSpecDao().getWorkSpec(periodicWork.getId()); 375 assertThat(workSpec.isPeriodic(), is(true)); 376 assertThat(workSpec.getIntervalDuration(), is(PeriodicWork.MIN_PERIODIC_INTERVAL_MILLIS)); 377 assertThat(workSpec.getFlexDuration(), is(PeriodicWork.MIN_PERIODIC_INTERVAL_MILLIS)); 378 } 379 380 @Test 381 @SmallTest 382 public void testEnqueued_work_setsPeriodStartTime() { 383 Work work = new Work.Builder(TestWorker.class).build(); 384 assertThat(getWorkSpec(work).getPeriodStartTime(), is(0L)); 385 386 long beforeEnqueueTime = System.currentTimeMillis(); 387 388 mWorkManagerImpl.enqueue(work); 389 390 WorkSpec workSpec = mDatabase.workSpecDao().getWorkSpec(work.getId()); 391 assertThat(workSpec.getPeriodStartTime(), is(greaterThanOrEqualTo(beforeEnqueueTime))); 392 } 393 394 @Test 395 @SmallTest 396 public void testEnqueued_periodicWork_setsPeriodStartTime() { 397 PeriodicWork periodicWork = new PeriodicWork.Builder( 398 TestWorker.class, 399 PeriodicWork.MIN_PERIODIC_INTERVAL_MILLIS, 400 TimeUnit.MILLISECONDS) 401 .build(); 402 assertThat(getWorkSpec(periodicWork).getPeriodStartTime(), is(0L)); 403 404 long beforeEnqueueTime = System.currentTimeMillis(); 405 406 mWorkManagerImpl.enqueue(periodicWork); 407 408 WorkSpec workSpec = mDatabase.workSpecDao().getWorkSpec(periodicWork.getId()); 409 assertThat(workSpec.getPeriodStartTime(), is(greaterThanOrEqualTo(beforeEnqueueTime))); 410 } 411 412 @Test 413 @SmallTest 414 public void testBeginWithName_setsUniqueName() { 415 final String testName = "myname"; 416 417 Work work = new Work.Builder(TestWorker.class).build(); 418 mWorkManagerImpl.beginWithName(testName, REPLACE) 419 .then(work) 420 .enqueue(); 421 422 List<String> workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 423 assertThat(work.getId(), isIn(workSpecIds)); 424 } 425 426 @Test 427 @SmallTest 428 public void testBeginWithName_deletesOldWorkOnReplace() { 429 final String testName = "myname"; 430 431 Work originalWork = new Work.Builder(InfiniteTestWorker.class).build(); 432 insertNamedWorks(testName, originalWork); 433 434 List<String> workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 435 assertThat(workSpecIds, containsInAnyOrder(originalWork.getId())); 436 437 Work replacementWork1 = new Work.Builder(TestWorker.class).build(); 438 Work replacementWork2 = new Work.Builder(TestWorker.class).build(); 439 mWorkManagerImpl 440 .beginWithName(testName, REPLACE, replacementWork1) 441 .then(replacementWork2) 442 .enqueue(); 443 444 workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 445 assertThat( 446 workSpecIds, 447 containsInAnyOrder(replacementWork1.getId(), replacementWork2.getId())); 448 449 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 450 assertThat(workSpecDao.getWorkSpec(originalWork.getId()), is(nullValue())); 451 assertThat(workSpecDao.getWorkSpec(replacementWork1.getId()), is(not(nullValue()))); 452 assertThat(workSpecDao.getWorkSpec(replacementWork2.getId()), is(not(nullValue()))); 453 } 454 455 @Test 456 @SmallTest 457 public void testBeginWithName_keepsExistingWorkOnKeep() { 458 final String testName = "myname"; 459 460 Work originalWork = new Work.Builder(InfiniteTestWorker.class).build(); 461 insertNamedWorks(testName, originalWork); 462 463 List<String> workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 464 assertThat(workSpecIds, containsInAnyOrder(originalWork.getId())); 465 466 Work replacementWork1 = new Work.Builder(TestWorker.class).build(); 467 Work replacementWork2 = new Work.Builder(TestWorker.class).build(); 468 mWorkManagerImpl 469 .beginWithName(testName, KEEP, replacementWork1) 470 .then(replacementWork2) 471 .enqueue(); 472 473 workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 474 assertThat(workSpecIds, containsInAnyOrder(originalWork.getId())); 475 476 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 477 assertThat(workSpecDao.getWorkSpec(originalWork.getId()), is(not(nullValue()))); 478 assertThat(workSpecDao.getWorkSpec(replacementWork1.getId()), is(nullValue())); 479 assertThat(workSpecDao.getWorkSpec(replacementWork2.getId()), is(nullValue())); 480 } 481 482 @Test 483 @SmallTest 484 public void testBeginWithName_replacesExistingWorkOnKeepWhenExistingWorkIsFinished() { 485 final String testName = "myname"; 486 487 Work originalWork = new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build(); 488 insertNamedWorks(testName, originalWork); 489 490 List<String> workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 491 assertThat(workSpecIds, containsInAnyOrder(originalWork.getId())); 492 493 Work replacementWork1 = new Work.Builder(TestWorker.class).build(); 494 Work replacementWork2 = new Work.Builder(TestWorker.class).build(); 495 mWorkManagerImpl 496 .beginWithName(testName, KEEP, replacementWork1) 497 .then(replacementWork2) 498 .enqueue(); 499 500 workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 501 assertThat(workSpecIds, 502 containsInAnyOrder(replacementWork1.getId(), replacementWork2.getId())); 503 504 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 505 assertThat(workSpecDao.getWorkSpec(originalWork.getId()), is(nullValue())); 506 assertThat(workSpecDao.getWorkSpec(replacementWork1.getId()), is(not(nullValue()))); 507 assertThat(workSpecDao.getWorkSpec(replacementWork2.getId()), is(not(nullValue()))); 508 } 509 510 @Test 511 @SmallTest 512 public void testBeginWithName_appendsExistingWorkOnAppend() { 513 final String testName = "myname"; 514 515 Work originalWork = new Work.Builder(InfiniteTestWorker.class).build(); 516 insertNamedWorks(testName, originalWork); 517 518 List<String> workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 519 assertThat(workSpecIds, containsInAnyOrder(originalWork.getId())); 520 521 Work appendWork1 = new Work.Builder(TestWorker.class).build(); 522 Work appendWork2 = new Work.Builder(TestWorker.class).build(); 523 mWorkManagerImpl 524 .beginWithName(testName, APPEND, appendWork1) 525 .then(appendWork2) 526 .enqueue(); 527 528 workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 529 assertThat(workSpecIds, 530 containsInAnyOrder(originalWork.getId(), appendWork1.getId(), appendWork2.getId())); 531 532 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 533 assertThat(workSpecDao.getWorkSpec(originalWork.getId()), is(not(nullValue()))); 534 assertThat(workSpecDao.getState(appendWork1.getId()), is(BLOCKED)); 535 assertThat(workSpecDao.getState(appendWork2.getId()), is(BLOCKED)); 536 537 assertThat(mDatabase.dependencyDao().getDependentWorkIds(originalWork.getId()), 538 containsInAnyOrder(appendWork1.getId())); 539 } 540 541 @Test 542 @SmallTest 543 public void testBeginWithName_appendsExistingWorkToOnlyLeavesOnAppend() { 544 final String testName = "myname"; 545 546 Work originalWork1 = new Work.Builder(InfiniteTestWorker.class).build(); 547 Work originalWork2 = new Work.Builder(InfiniteTestWorker.class).build(); 548 Work originalWork3 = new Work.Builder(InfiniteTestWorker.class).build(); 549 Work originalWork4 = new Work.Builder(InfiniteTestWorker.class).build(); 550 insertNamedWorks(testName, originalWork1, originalWork2, originalWork3, originalWork4); 551 insertDependency(originalWork4, originalWork2); 552 insertDependency(originalWork3, originalWork2); 553 insertDependency(originalWork2, originalWork1); 554 555 List<String> workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 556 assertThat(workSpecIds, 557 containsInAnyOrder( 558 originalWork1.getId(), 559 originalWork2.getId(), 560 originalWork3.getId(), 561 originalWork4.getId())); 562 563 Work appendWork1 = new Work.Builder(TestWorker.class).build(); 564 Work appendWork2 = new Work.Builder(TestWorker.class).build(); 565 mWorkManagerImpl 566 .beginWithName(testName, APPEND, appendWork1) 567 .then(appendWork2) 568 .enqueue(); 569 570 workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 571 assertThat(workSpecIds, 572 containsInAnyOrder( 573 originalWork1.getId(), 574 originalWork2.getId(), 575 originalWork3.getId(), 576 originalWork4.getId(), 577 appendWork1.getId(), 578 appendWork2.getId())); 579 580 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 581 assertThat(workSpecDao.getWorkSpec(originalWork1.getId()), is(not(nullValue()))); 582 assertThat(workSpecDao.getWorkSpec(originalWork2.getId()), is(not(nullValue()))); 583 assertThat(workSpecDao.getWorkSpec(originalWork3.getId()), is(not(nullValue()))); 584 assertThat(workSpecDao.getWorkSpec(originalWork4.getId()), is(not(nullValue()))); 585 assertThat(workSpecDao.getState(appendWork1.getId()), is(BLOCKED)); 586 assertThat(workSpecDao.getState(appendWork2.getId()), is(BLOCKED)); 587 588 DependencyDao dependencyDao = mDatabase.dependencyDao(); 589 assertThat(dependencyDao.getPrerequisites(appendWork1.getId()), 590 containsInAnyOrder(originalWork3.getId(), originalWork4.getId())); 591 assertThat(dependencyDao.getPrerequisites(appendWork2.getId()), 592 containsInAnyOrder(appendWork1.getId())); 593 } 594 595 @Test 596 @SmallTest 597 public void testBeginWithName_insertsExistingWorkWhenNothingToAppendTo() { 598 final String testName = "myname"; 599 600 Work appendWork1 = new Work.Builder(TestWorker.class).build(); 601 Work appendWork2 = new Work.Builder(TestWorker.class).build(); 602 mWorkManagerImpl 603 .beginWithName(testName, APPEND, appendWork1) 604 .then(appendWork2) 605 .enqueue(); 606 607 List<String> workSpecIds = mDatabase.workNameDao().getWorkSpecIdsWithName(testName); 608 assertThat(workSpecIds, 609 containsInAnyOrder(appendWork1.getId(), appendWork2.getId())); 610 } 611 612 @Test 613 @SmallTest 614 public void testGetStatusByIdSync() { 615 Work work = new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build(); 616 insertWorkSpecAndTags(work); 617 618 WorkStatus workStatus = mWorkManagerImpl.getStatusByIdBlocking(work.getId()); 619 assertThat(workStatus.getId(), is(work.getId())); 620 assertThat(workStatus.getState(), is(SUCCEEDED)); 621 } 622 623 @Test 624 @SmallTest 625 public void testGetStatusByIdSync_returnsNullIfNotInDatabase() { 626 WorkStatus workStatus = mWorkManagerImpl.getStatusByIdBlocking("dummy"); 627 assertThat(workStatus, is(nullValue())); 628 } 629 630 @Test 631 @SmallTest 632 @SuppressWarnings("unchecked") 633 public void testGetStatusesById() { 634 Work work0 = new Work.Builder(TestWorker.class).build(); 635 Work work1 = new Work.Builder(TestWorker.class).build(); 636 insertWorkSpecAndTags(work0); 637 insertWorkSpecAndTags(work1); 638 639 Observer<List<WorkStatus>> mockObserver = mock(Observer.class); 640 641 TestLifecycleOwner testLifecycleOwner = new TestLifecycleOwner(); 642 LiveData<List<WorkStatus>> liveData = 643 mWorkManagerImpl.getStatusesById(Arrays.asList(work0.getId(), work1.getId())); 644 liveData.observe(testLifecycleOwner, mockObserver); 645 646 ArgumentCaptor<List<WorkStatus>> captor = ArgumentCaptor.forClass(List.class); 647 verify(mockObserver).onChanged(captor.capture()); 648 assertThat(captor.getValue(), is(not(nullValue()))); 649 assertThat(captor.getValue().size(), is(2)); 650 651 WorkStatus workStatus0 = new WorkStatus( 652 work0.getId(), 653 ENQUEUED, 654 Arguments.EMPTY, 655 Collections.<String>emptyList()); 656 WorkStatus workStatus1 = new WorkStatus( 657 work1.getId(), 658 ENQUEUED, 659 Arguments.EMPTY, 660 Collections.<String>emptyList()); 661 assertThat(captor.getValue(), containsInAnyOrder(workStatus0, workStatus1)); 662 663 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 664 workSpecDao.setState(RUNNING, work0.getId()); 665 666 verify(mockObserver, times(2)).onChanged(captor.capture()); 667 assertThat(captor.getValue(), is(not(nullValue()))); 668 assertThat(captor.getValue().size(), is(2)); 669 670 workStatus0 = new WorkStatus( 671 work0.getId(), 672 RUNNING, 673 Arguments.EMPTY, 674 Collections.<String>emptyList()); 675 assertThat(captor.getValue(), containsInAnyOrder(workStatus0, workStatus1)); 676 677 clearInvocations(mockObserver); 678 workSpecDao.setState(RUNNING, work1.getId()); 679 680 verify(mockObserver).onChanged(captor.capture()); 681 assertThat(captor.getValue(), is(not(nullValue()))); 682 assertThat(captor.getValue().size(), is(2)); 683 684 workStatus1 = new WorkStatus( 685 work1.getId(), 686 RUNNING, 687 Arguments.EMPTY, 688 Collections.<String>emptyList()); 689 assertThat(captor.getValue(), containsInAnyOrder(workStatus0, workStatus1)); 690 691 liveData.removeObservers(testLifecycleOwner); 692 } 693 694 @Test 695 @SmallTest 696 public void testGetStatusesByTagSync() { 697 final String firstTag = "first_tag"; 698 final String secondTag = "second_tag"; 699 700 Work work0 = new Work.Builder(TestWorker.class) 701 .addTag(firstTag) 702 .addTag(secondTag) 703 .withInitialState(RUNNING) 704 .build(); 705 Work work1 = new Work.Builder(TestWorker.class) 706 .addTag(firstTag) 707 .withInitialState(BLOCKED) 708 .build(); 709 Work work2 = new Work.Builder(TestWorker.class) 710 .addTag(secondTag) 711 .withInitialState(SUCCEEDED) 712 .build(); 713 insertWorkSpecAndTags(work0); 714 insertWorkSpecAndTags(work1); 715 insertWorkSpecAndTags(work2); 716 717 WorkStatus workStatus0 = new WorkStatus( 718 work0.getId(), 719 RUNNING, 720 Arguments.EMPTY, 721 Arrays.asList(firstTag, secondTag)); 722 WorkStatus workStatus1 = new WorkStatus( 723 work1.getId(), 724 BLOCKED, 725 Arguments.EMPTY, 726 Collections.singletonList(firstTag)); 727 WorkStatus workStatus2 = new WorkStatus( 728 work2.getId(), 729 SUCCEEDED, 730 Arguments.EMPTY, 731 Collections.singletonList(secondTag)); 732 733 List<WorkStatus> workStatuses = mWorkManagerImpl.getStatusesByTagBlocking(firstTag); 734 assertThat(workStatuses, containsInAnyOrder(workStatus0, workStatus1)); 735 736 workStatuses = mWorkManagerImpl.getStatusesByTagBlocking(secondTag); 737 assertThat(workStatuses, containsInAnyOrder(workStatus0, workStatus2)); 738 739 workStatuses = mWorkManagerImpl.getStatusesByTagBlocking("dummy"); 740 assertThat(workStatuses.size(), is(0)); 741 } 742 743 @Test 744 @SmallTest 745 @SuppressWarnings("unchecked") 746 public void testGetStatusesByTag() { 747 final String firstTag = "first_tag"; 748 final String secondTag = "second_tag"; 749 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 750 751 Work work0 = new Work.Builder(TestWorker.class) 752 .addTag(firstTag) 753 .addTag(secondTag) 754 .withInitialState(RUNNING) 755 .build(); 756 Work work1 = new Work.Builder(TestWorker.class) 757 .addTag(firstTag) 758 .withInitialState(BLOCKED) 759 .build(); 760 Work work2 = new Work.Builder(TestWorker.class) 761 .addTag(secondTag) 762 .withInitialState(SUCCEEDED) 763 .build(); 764 insertWorkSpecAndTags(work0); 765 insertWorkSpecAndTags(work1); 766 insertWorkSpecAndTags(work2); 767 768 Observer<List<WorkStatus>> mockObserver = mock(Observer.class); 769 770 TestLifecycleOwner testLifecycleOwner = new TestLifecycleOwner(); 771 LiveData<List<WorkStatus>> liveData = mWorkManagerImpl.getStatusesByTag(firstTag); 772 liveData.observe(testLifecycleOwner, mockObserver); 773 774 ArgumentCaptor<List<WorkStatus>> captor = ArgumentCaptor.forClass(List.class); 775 verify(mockObserver).onChanged(captor.capture()); 776 assertThat(captor.getValue(), is(not(nullValue()))); 777 assertThat(captor.getValue().size(), is(2)); 778 779 WorkStatus workStatus0 = new WorkStatus( 780 work0.getId(), 781 RUNNING, 782 Arguments.EMPTY, 783 Arrays.asList(firstTag, secondTag)); 784 WorkStatus workStatus1 = new WorkStatus( 785 work1.getId(), 786 BLOCKED, 787 Arguments.EMPTY, 788 Collections.singletonList(firstTag)); 789 assertThat(captor.getValue(), containsInAnyOrder(workStatus0, workStatus1)); 790 791 workSpecDao.setState(ENQUEUED, work0.getId()); 792 793 verify(mockObserver, times(2)).onChanged(captor.capture()); 794 assertThat(captor.getValue(), is(not(nullValue()))); 795 assertThat(captor.getValue().size(), is(2)); 796 797 workStatus0 = new WorkStatus( 798 work0.getId(), 799 ENQUEUED, 800 Arguments.EMPTY, 801 Arrays.asList(firstTag, secondTag)); 802 assertThat(captor.getValue(), containsInAnyOrder(workStatus0, workStatus1)); 803 804 liveData.removeObservers(testLifecycleOwner); 805 } 806 807 @Test 808 @SmallTest 809 public void getStatusByNameSync() { 810 final String testName = "myname"; 811 812 Work work0 = new Work.Builder(InfiniteTestWorker.class).withInitialState(RUNNING).build(); 813 Work work1 = new Work.Builder(InfiniteTestWorker.class).withInitialState(BLOCKED).build(); 814 Work work2 = new Work.Builder(InfiniteTestWorker.class).withInitialState(BLOCKED).build(); 815 insertNamedWorks(testName, work0, work1, work2); 816 insertDependency(work1, work0); 817 insertDependency(work2, work1); 818 819 WorkStatus workStatus0 = new WorkStatus( 820 work0.getId(), 821 RUNNING, 822 Arguments.EMPTY, 823 Collections.<String>emptyList()); 824 WorkStatus workStatus1 = new WorkStatus( 825 work1.getId(), 826 BLOCKED, 827 Arguments.EMPTY, 828 Collections.<String>emptyList()); 829 WorkStatus workStatus2 = new WorkStatus( 830 work2.getId(), 831 BLOCKED, 832 Arguments.EMPTY, 833 Collections.<String>emptyList()); 834 835 List<WorkStatus> workStatuses = mWorkManagerImpl.getStatusesByNameBlocking(testName); 836 assertThat(workStatuses, containsInAnyOrder(workStatus0, workStatus1, workStatus2)); 837 838 workStatuses = mWorkManagerImpl.getStatusesByNameBlocking("dummy"); 839 assertThat(workStatuses.size(), is(0)); 840 } 841 842 @Test 843 @SmallTest 844 @SuppressWarnings("unchecked") 845 public void testGetStatusesByName() { 846 final String testName = "myname"; 847 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 848 849 Work work0 = new Work.Builder(InfiniteTestWorker.class).withInitialState(RUNNING).build(); 850 Work work1 = new Work.Builder(InfiniteTestWorker.class).withInitialState(BLOCKED).build(); 851 Work work2 = new Work.Builder(InfiniteTestWorker.class).withInitialState(BLOCKED).build(); 852 insertNamedWorks(testName, work0, work1, work2); 853 insertDependency(work1, work0); 854 insertDependency(work2, work1); 855 856 Observer<List<WorkStatus>> mockObserver = mock(Observer.class); 857 858 TestLifecycleOwner testLifecycleOwner = new TestLifecycleOwner(); 859 LiveData<List<WorkStatus>> liveData = mWorkManagerImpl.getStatusesByName(testName); 860 liveData.observe(testLifecycleOwner, mockObserver); 861 862 ArgumentCaptor<List<WorkStatus>> captor = ArgumentCaptor.forClass(List.class); 863 verify(mockObserver).onChanged(captor.capture()); 864 assertThat(captor.getValue(), is(not(nullValue()))); 865 assertThat(captor.getValue().size(), is(3)); 866 867 WorkStatus workStatus0 = new WorkStatus( 868 work0.getId(), 869 RUNNING, 870 Arguments.EMPTY, 871 Collections.<String>emptyList()); 872 WorkStatus workStatus1 = new WorkStatus( 873 work1.getId(), 874 BLOCKED, 875 Arguments.EMPTY, 876 Collections.<String>emptyList()); 877 WorkStatus workStatus2 = new WorkStatus( 878 work2.getId(), 879 BLOCKED, 880 Arguments.EMPTY, 881 Collections.<String>emptyList()); 882 assertThat(captor.getValue(), containsInAnyOrder(workStatus0, workStatus1, workStatus2)); 883 884 workSpecDao.setState(ENQUEUED, work0.getId()); 885 886 verify(mockObserver, times(2)).onChanged(captor.capture()); 887 assertThat(captor.getValue(), is(not(nullValue()))); 888 assertThat(captor.getValue().size(), is(3)); 889 890 workStatus0 = new WorkStatus( 891 work0.getId(), 892 ENQUEUED, 893 Arguments.EMPTY, 894 Collections.<String>emptyList()); 895 assertThat(captor.getValue(), containsInAnyOrder(workStatus0, workStatus1, workStatus2)); 896 897 liveData.removeObservers(testLifecycleOwner); 898 } 899 900 @Test 901 @SmallTest 902 public void testCancelWorkForId() { 903 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 904 905 Work work0 = new Work.Builder(TestWorker.class).build(); 906 Work work1 = new Work.Builder(TestWorker.class).build(); 907 insertWorkSpecAndTags(work0); 908 insertWorkSpecAndTags(work1); 909 910 mWorkManagerImpl.cancelWorkById(work0.getId()); 911 912 assertThat(workSpecDao.getState(work0.getId()), is(CANCELLED)); 913 assertThat(workSpecDao.getState(work1.getId()), is(not(CANCELLED))); 914 } 915 916 @Test 917 @SmallTest 918 public void testCancelWorkForId_cancelsDependentWork() { 919 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 920 921 Work work0 = new Work.Builder(TestWorker.class).build(); 922 Work work1 = new Work.Builder(TestWorker.class).withInitialState(BLOCKED).build(); 923 insertWorkSpecAndTags(work0); 924 insertWorkSpecAndTags(work1); 925 insertDependency(work1, work0); 926 927 mWorkManagerImpl.cancelWorkById(work0.getId()); 928 929 assertThat(workSpecDao.getState(work0.getId()), is(CANCELLED)); 930 assertThat(workSpecDao.getState(work1.getId()), is(CANCELLED)); 931 } 932 933 @Test 934 @SmallTest 935 public void testCancelWorkForId_cancelsUnfinishedWorkOnly() { 936 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 937 938 Work work0 = new Work.Builder(TestWorker.class).withInitialState(SUCCEEDED).build(); 939 Work work1 = new Work.Builder(TestWorker.class).withInitialState(ENQUEUED).build(); 940 insertWorkSpecAndTags(work0); 941 insertWorkSpecAndTags(work1); 942 insertDependency(work1, work0); 943 944 mWorkManagerImpl.cancelWorkById(work0.getId()); 945 946 assertThat(workSpecDao.getState(work0.getId()), is(SUCCEEDED)); 947 assertThat(workSpecDao.getState(work1.getId()), is(CANCELLED)); 948 } 949 950 @Test 951 @SmallTest 952 public void testCancelAllWorkWithTag() { 953 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 954 955 final String tagToClear = "tag_to_clear"; 956 final String tagNotToClear = "tag_not_to_clear"; 957 958 Work work0 = new Work.Builder(TestWorker.class).addTag(tagToClear).build(); 959 Work work1 = new Work.Builder(TestWorker.class).addTag(tagToClear).build(); 960 Work work2 = new Work.Builder(TestWorker.class).addTag(tagNotToClear).build(); 961 Work work3 = new Work.Builder(TestWorker.class).addTag(tagNotToClear).build(); 962 insertWorkSpecAndTags(work0); 963 insertWorkSpecAndTags(work1); 964 insertWorkSpecAndTags(work2); 965 insertWorkSpecAndTags(work3); 966 967 mWorkManagerImpl.cancelAllWorkWithTag(tagToClear); 968 969 assertThat(workSpecDao.getState(work0.getId()), is(CANCELLED)); 970 assertThat(workSpecDao.getState(work1.getId()), is(CANCELLED)); 971 assertThat(workSpecDao.getState(work2.getId()), is(not(CANCELLED))); 972 assertThat(workSpecDao.getState(work3.getId()), is(not(CANCELLED))); 973 } 974 975 @Test 976 @SmallTest 977 public void testCancelAllWorkWithTag_cancelsDependentWork() { 978 String tag = "tag"; 979 980 Work work0 = new Work.Builder(TestWorker.class).addTag(tag).build(); 981 Work work1 = new Work.Builder(TestWorker.class).build(); 982 Work work2 = new Work.Builder(TestWorker.class).build(); 983 Work work3 = new Work.Builder(TestWorker.class).build(); 984 Work work4 = new Work.Builder(TestWorker.class).build(); 985 986 insertWorkSpecAndTags(work0); 987 insertWorkSpecAndTags(work1); 988 insertWorkSpecAndTags(work2); 989 insertWorkSpecAndTags(work3); 990 insertWorkSpecAndTags(work4); 991 992 // Dependency graph: 993 // 0 994 // | 995 // |------------| 996 // 3 1 4 997 // | | 998 // ------------ 999 // | 1000 // 2 1001 1002 insertDependency(work2, work1); 1003 insertDependency(work2, work3); 1004 insertDependency(work1, work0); 1005 insertDependency(work4, work0); 1006 1007 mWorkManagerImpl.cancelAllWorkWithTag(tag); 1008 1009 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 1010 assertThat(workSpecDao.getState(work0.getId()), is(CANCELLED)); 1011 assertThat(workSpecDao.getState(work1.getId()), is(CANCELLED)); 1012 assertThat(workSpecDao.getState(work2.getId()), is(CANCELLED)); 1013 assertThat(workSpecDao.getState(work3.getId()), is(not(CANCELLED))); 1014 assertThat(workSpecDao.getState(work4.getId()), is(CANCELLED)); 1015 } 1016 1017 @Test 1018 @SmallTest 1019 public void testCancelWorkForName() { 1020 final String testName = "myname"; 1021 1022 Work work0 = new Work.Builder(InfiniteTestWorker.class).build(); 1023 Work work1 = new Work.Builder(InfiniteTestWorker.class).build(); 1024 insertNamedWorks(testName, work0, work1); 1025 1026 mWorkManagerImpl.cancelAllWorkWithName(testName); 1027 1028 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 1029 assertThat(workSpecDao.getState(work0.getId()), is(CANCELLED)); 1030 assertThat(workSpecDao.getState(work1.getId()), is(CANCELLED)); 1031 } 1032 1033 @Test 1034 @SmallTest 1035 public void testCancelWorkForName_ignoresFinishedWork() { 1036 final String testName = "myname"; 1037 1038 Work work0 = new Work.Builder(InfiniteTestWorker.class).withInitialState(SUCCEEDED).build(); 1039 Work work1 = new Work.Builder(InfiniteTestWorker.class).build(); 1040 insertNamedWorks(testName, work0, work1); 1041 1042 mWorkManagerImpl.cancelAllWorkWithName(testName); 1043 1044 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 1045 assertThat(workSpecDao.getState(work0.getId()), is(SUCCEEDED)); 1046 assertThat(workSpecDao.getState(work1.getId()), is(CANCELLED)); 1047 } 1048 1049 @Test 1050 @SmallTest 1051 public void testSynchronousCancelAndGetStatus() { 1052 Work work = new Work.Builder(TestWorker.class).build(); 1053 insertWorkSpecAndTags(work); 1054 1055 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 1056 assertThat(workSpecDao.getState(work.getId()), is(ENQUEUED)); 1057 1058 mWorkManagerImpl.cancelWorkByIdBlocking(work.getId()); 1059 assertThat(mWorkManagerImpl.getStatusByIdBlocking(work.getId()).getState(), is(CANCELLED)); 1060 } 1061 1062 @Test 1063 @SmallTest 1064 public void testGenerateCleanupCallback_resetsRunningWorkStatuses() { 1065 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 1066 1067 Work work = new Work.Builder(TestWorker.class).withInitialState(RUNNING).build(); 1068 workSpecDao.insertWorkSpec(getWorkSpec(work)); 1069 1070 assertThat(workSpecDao.getState(work.getId()), is(RUNNING)); 1071 1072 SupportSQLiteOpenHelper openHelper = mDatabase.getOpenHelper(); 1073 SupportSQLiteDatabase db = openHelper.getWritableDatabase(); 1074 WorkDatabase.generateCleanupCallback().onOpen(db); 1075 1076 assertThat(workSpecDao.getState(work.getId()), is(ENQUEUED)); 1077 } 1078 1079 @Test 1080 @SmallTest 1081 public void testGenerateCleanupCallback_deletesOldFinishedWork() { 1082 Work work1 = new Work.Builder(TestWorker.class) 1083 .withInitialState(SUCCEEDED) 1084 .withPeriodStartTime(WorkDatabase.getPruneDate() - 1L, TimeUnit.MILLISECONDS) 1085 .build(); 1086 Work work2 = new Work.Builder(TestWorker.class) 1087 .withPeriodStartTime(Long.MAX_VALUE, TimeUnit.MILLISECONDS) 1088 .build(); 1089 1090 insertWorkSpecAndTags(work1); 1091 insertWorkSpecAndTags(work2); 1092 1093 SupportSQLiteOpenHelper openHelper = mDatabase.getOpenHelper(); 1094 SupportSQLiteDatabase db = openHelper.getWritableDatabase(); 1095 WorkDatabase.generateCleanupCallback().onOpen(db); 1096 1097 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 1098 assertThat(workSpecDao.getWorkSpec(work1.getId()), is(nullValue())); 1099 assertThat(workSpecDao.getWorkSpec(work2.getId()), is(not(nullValue()))); 1100 } 1101 1102 @Test 1103 @SmallTest 1104 public void testGenerateCleanupCallback_doesNotDeleteOldFinishedWorkWithActiveDependents() { 1105 Work work0 = new Work.Builder(TestWorker.class) 1106 .withInitialState(SUCCEEDED) 1107 .withPeriodStartTime(WorkDatabase.getPruneDate() - 1L, TimeUnit.MILLISECONDS) 1108 .build(); 1109 Work work1 = new Work.Builder(TestWorker.class) 1110 .withInitialState(SUCCEEDED) 1111 .withPeriodStartTime(WorkDatabase.getPruneDate() - 1L, TimeUnit.MILLISECONDS) 1112 .build(); 1113 Work work2 = new Work.Builder(TestWorker.class) 1114 .withInitialState(ENQUEUED) 1115 .withPeriodStartTime(WorkDatabase.getPruneDate() - 1L, TimeUnit.MILLISECONDS) 1116 .build(); 1117 1118 insertWorkSpecAndTags(work0); 1119 insertWorkSpecAndTags(work1); 1120 insertWorkSpecAndTags(work2); 1121 1122 // Dependency graph: 0 -> 1 -> 2 1123 insertDependency(work1, work0); 1124 insertDependency(work2, work1); 1125 1126 SupportSQLiteOpenHelper openHelper = mDatabase.getOpenHelper(); 1127 SupportSQLiteDatabase db = openHelper.getWritableDatabase(); 1128 WorkDatabase.generateCleanupCallback().onOpen(db); 1129 1130 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 1131 assertThat(workSpecDao.getWorkSpec(work0.getId()), is(nullValue())); 1132 assertThat(workSpecDao.getWorkSpec(work1.getId()), is(not(nullValue()))); 1133 assertThat(workSpecDao.getWorkSpec(work2.getId()), is(not(nullValue()))); 1134 } 1135 1136 private void insertWorkSpecAndTags(Work work) { 1137 mDatabase.workSpecDao().insertWorkSpec(getWorkSpec(work)); 1138 for (String tag : getTags(work)) { 1139 mDatabase.workTagDao().insert(new WorkTag(tag, work.getId())); 1140 } 1141 } 1142 1143 private void insertNamedWorks(String name, Work... works) { 1144 for (Work work : works) { 1145 insertWorkSpecAndTags(work); 1146 mDatabase.workNameDao().insert(new WorkName(name, work.getId())); 1147 } 1148 } 1149 1150 private void insertDependency(Work work, Work prerequisiteWork) { 1151 mDatabase.dependencyDao().insertDependency( 1152 new Dependency(work.getId(), prerequisiteWork.getId())); 1153 } 1154} 1155