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