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