WorkerWrapperTest.java revision dcbf20db18e3e93a13e9fa75fa4b723255b87c54
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.State.BLOCKED; 20import static androidx.work.State.CANCELLED; 21import static androidx.work.State.ENQUEUED; 22import static androidx.work.State.FAILED; 23import static androidx.work.State.RUNNING; 24import static androidx.work.State.SUCCEEDED; 25 26import static org.hamcrest.CoreMatchers.equalTo; 27import static org.hamcrest.CoreMatchers.is; 28import static org.hamcrest.CoreMatchers.notNullValue; 29import static org.hamcrest.MatcherAssert.assertThat; 30import static org.hamcrest.Matchers.contains; 31import static org.hamcrest.Matchers.containsInAnyOrder; 32import static org.hamcrest.Matchers.greaterThan; 33import static org.mockito.Mockito.mock; 34import static org.mockito.Mockito.spy; 35import static org.mockito.Mockito.times; 36import static org.mockito.Mockito.verify; 37 38import android.content.Context; 39import android.support.test.InstrumentationRegistry; 40import android.support.test.filters.LargeTest; 41import android.support.test.filters.SmallTest; 42import android.support.test.runner.AndroidJUnit4; 43 44import androidx.work.ArrayCreatingInputMerger; 45import androidx.work.Data; 46import androidx.work.DatabaseTest; 47import androidx.work.PeriodicWorkRequest; 48import androidx.work.WorkRequest; 49import androidx.work.Worker; 50import androidx.work.impl.model.Dependency; 51import androidx.work.impl.model.DependencyDao; 52import androidx.work.impl.model.WorkSpec; 53import androidx.work.impl.model.WorkSpecDao; 54import androidx.work.impl.utils.taskexecutor.InstantTaskExecutorRule; 55import androidx.work.worker.ChainedArgumentWorker; 56import androidx.work.worker.EchoingWorker; 57import androidx.work.worker.FailureWorker; 58import androidx.work.worker.RetryWorker; 59import androidx.work.worker.SleepTestWorker; 60import androidx.work.worker.TestWorker; 61 62import org.junit.Before; 63import org.junit.Rule; 64import org.junit.Test; 65import org.junit.runner.RunWith; 66import org.mockito.ArgumentCaptor; 67 68import java.util.Arrays; 69import java.util.Collections; 70import java.util.List; 71import java.util.concurrent.Executors; 72import java.util.concurrent.TimeUnit; 73 74@RunWith(AndroidJUnit4.class) 75public class WorkerWrapperTest extends DatabaseTest { 76 private WorkSpecDao mWorkSpecDao; 77 private DependencyDao mDependencyDao; 78 private Context mContext; 79 private ExecutionListener mMockListener; 80 private Scheduler mMockScheduler; 81 82 @Rule 83 public InstantTaskExecutorRule mRule = new InstantTaskExecutorRule(); 84 85 @Before 86 public void setUp() { 87 mContext = InstrumentationRegistry.getTargetContext(); 88 mWorkSpecDao = spy(mDatabase.workSpecDao()); 89 mDependencyDao = mDatabase.dependencyDao(); 90 mMockListener = mock(ExecutionListener.class); 91 mMockScheduler = mock(Scheduler.class); 92 } 93 94 @Test 95 @SmallTest 96 public void testSuccess() { 97 WorkRequest work = new WorkRequest.Builder(TestWorker.class).build(); 98 insertWork(work); 99 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 100 .withListener(mMockListener) 101 .build() 102 .run(); 103 verify(mMockListener).onExecuted(work.getId(), true, false); 104 assertThat(mWorkSpecDao.getState(work.getId()), is(SUCCEEDED)); 105 } 106 107 @Test 108 @SmallTest 109 public void testRunAttemptCountIncremented_successfulExecution() { 110 WorkRequest work = new WorkRequest.Builder(TestWorker.class).build(); 111 insertWork(work); 112 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 113 .withSchedulers(Collections.singletonList(mMockScheduler)) 114 .withListener(mMockListener) 115 .build() 116 .run(); 117 WorkSpec latestWorkSpec = mWorkSpecDao.getWorkSpec(work.getId()); 118 assertThat(latestWorkSpec.runAttemptCount, is(1)); 119 } 120 121 @Test 122 @SmallTest 123 public void testRunAttemptCountIncremented_failedExecution() { 124 WorkRequest work = new WorkRequest.Builder(FailureWorker.class).build(); 125 insertWork(work); 126 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 127 .withSchedulers(Collections.singletonList(mMockScheduler)) 128 .withListener(mMockListener) 129 .build() 130 .run(); 131 WorkSpec latestWorkSpec = mWorkSpecDao.getWorkSpec(work.getId()); 132 assertThat(latestWorkSpec.runAttemptCount, is(1)); 133 } 134 135 @Test 136 @SmallTest 137 public void testPermanentErrorWithInvalidWorkSpecId() { 138 final String invalidWorkSpecId = "INVALID_ID"; 139 new WorkerWrapper.Builder(mContext, mDatabase, invalidWorkSpecId) 140 .withListener(mMockListener) 141 .build() 142 .run(); 143 verify(mMockListener).onExecuted(invalidWorkSpecId, false, false); 144 } 145 146 @Test 147 @SmallTest 148 public void testNotEnqueued() { 149 WorkRequest work = new WorkRequest.Builder(TestWorker.class) 150 .withInitialState(RUNNING) 151 .build(); 152 insertWork(work); 153 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 154 .withListener(mMockListener) 155 .build() 156 .run(); 157 verify(mMockListener).onExecuted(work.getId(), false, true); 158 } 159 160 @Test 161 @SmallTest 162 public void testCancelled() { 163 WorkRequest work = new WorkRequest.Builder(TestWorker.class) 164 .withInitialState(CANCELLED) 165 .build(); 166 insertWork(work); 167 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 168 .withListener(mMockListener) 169 .build() 170 .run(); 171 verify(mMockListener).onExecuted(work.getId(), false, false); 172 assertThat(mWorkSpecDao.getState(work.getId()), is(CANCELLED)); 173 } 174 175 @Test 176 @SmallTest 177 public void testPermanentErrorWithInvalidWorkerClass() { 178 WorkRequest work = new WorkRequest.Builder(TestWorker.class).build(); 179 getWorkSpec(work).workerClassName = "INVALID_CLASS_NAME"; 180 insertWork(work); 181 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 182 .withListener(mMockListener) 183 .build() 184 .run(); 185 verify(mMockListener).onExecuted(work.getId(), false, false); 186 assertThat(mWorkSpecDao.getState(work.getId()), is(FAILED)); 187 } 188 189 @Test 190 @SmallTest 191 public void testPermanentErrorWithInvalidInputMergerClass() { 192 WorkRequest work = new WorkRequest.Builder(TestWorker.class).build(); 193 getWorkSpec(work).inputMergerClassName = "INVALID_CLASS_NAME"; 194 insertWork(work); 195 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 196 .withSchedulers(Collections.singletonList(mMockScheduler)) 197 .withListener(mMockListener) 198 .build() 199 .run(); 200 verify(mMockListener).onExecuted(work.getId(), false, false); 201 assertThat(mWorkSpecDao.getState(work.getId()), is(FAILED)); 202 } 203 204 @Test 205 @SmallTest 206 public void testFailed() { 207 WorkRequest work = new WorkRequest.Builder(FailureWorker.class).build(); 208 insertWork(work); 209 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 210 .withListener(mMockListener) 211 .build() 212 .run(); 213 verify(mMockListener).onExecuted(work.getId(), false, false); 214 assertThat(mWorkSpecDao.getState(work.getId()), is(FAILED)); 215 } 216 217 @Test 218 @LargeTest 219 public void testRunning() throws InterruptedException { 220 WorkRequest work = new WorkRequest.Builder(SleepTestWorker.class).build(); 221 insertWork(work); 222 WorkerWrapper wrapper = new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 223 .withListener(mMockListener) 224 .build(); 225 Executors.newSingleThreadExecutor().submit(wrapper); 226 Thread.sleep(2000L); // Async wait duration. 227 assertThat(mWorkSpecDao.getState(work.getId()), is(RUNNING)); 228 Thread.sleep(SleepTestWorker.SLEEP_DURATION); 229 verify(mMockListener).onExecuted(work.getId(), true, false); 230 } 231 232 @Test 233 @SmallTest 234 public void testRunning_onlyWhenEnqueued() { 235 WorkRequest work = new WorkRequest.Builder(TestWorker.class) 236 .withInitialState(RUNNING) 237 .build(); 238 insertWork(work); 239 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 240 .withListener(mMockListener) 241 .build() 242 .run(); 243 verify(mMockListener).onExecuted(work.getId(), false, true); 244 } 245 246 @Test 247 @SmallTest 248 public void testDependencies() { 249 WorkRequest prerequisiteWork = new WorkRequest.Builder(TestWorker.class).build(); 250 WorkRequest work = new WorkRequest.Builder(TestWorker.class) 251 .withInitialState(BLOCKED).build(); 252 Dependency dependency = new Dependency(work.getId(), prerequisiteWork.getId()); 253 254 mDatabase.beginTransaction(); 255 try { 256 insertWork(prerequisiteWork); 257 insertWork(work); 258 mDependencyDao.insertDependency(dependency); 259 mDatabase.setTransactionSuccessful(); 260 } finally { 261 mDatabase.endTransaction(); 262 } 263 264 assertThat(mWorkSpecDao.getState(prerequisiteWork.getId()), is(ENQUEUED)); 265 assertThat(mWorkSpecDao.getState(work.getId()), is(BLOCKED)); 266 assertThat(mDependencyDao.hasCompletedAllPrerequisites(work.getId()), is(false)); 267 268 new WorkerWrapper.Builder(mContext, mDatabase, prerequisiteWork.getId()) 269 .withListener(mMockListener) 270 .withSchedulers(Collections.singletonList(mMockScheduler)) 271 .build() 272 .run(); 273 274 assertThat(mWorkSpecDao.getState(prerequisiteWork.getId()), is(SUCCEEDED)); 275 assertThat(mWorkSpecDao.getState(work.getId()), is(ENQUEUED)); 276 assertThat(mDependencyDao.hasCompletedAllPrerequisites(work.getId()), is(true)); 277 278 ArgumentCaptor<WorkSpec> captor = ArgumentCaptor.forClass(WorkSpec.class); 279 verify(mMockScheduler).schedule(captor.capture()); 280 assertThat(captor.getValue().id, is(work.getId())); 281 } 282 283 @Test 284 @SmallTest 285 public void testDependencies_passesOutputs() { 286 WorkRequest prerequisiteWork = new WorkRequest.Builder(ChainedArgumentWorker.class).build(); 287 WorkRequest work = new WorkRequest.Builder(TestWorker.class) 288 .withInitialState(BLOCKED) 289 .build(); 290 Dependency dependency = new Dependency(work.getId(), prerequisiteWork.getId()); 291 292 mDatabase.beginTransaction(); 293 try { 294 insertWork(prerequisiteWork); 295 insertWork(work); 296 mDependencyDao.insertDependency(dependency); 297 mDatabase.setTransactionSuccessful(); 298 } finally { 299 mDatabase.endTransaction(); 300 } 301 302 new WorkerWrapper.Builder(mContext, mDatabase, prerequisiteWork.getId()) 303 .withSchedulers(Collections.singletonList(mMockScheduler)) 304 .build().run(); 305 306 List<Data> arguments = mWorkSpecDao.getInputsFromPrerequisites(work.getId()); 307 assertThat(arguments.size(), is(1)); 308 assertThat(arguments, contains(ChainedArgumentWorker.getChainedArguments())); 309 } 310 311 @Test 312 @SmallTest 313 public void testDependencies_passesMergedOutputs() { 314 String key = "key"; 315 String value1 = "value1"; 316 String value2 = "value2"; 317 318 WorkRequest prerequisiteWork1 = new WorkRequest.Builder(EchoingWorker.class) 319 .withInputData(new Data.Builder().putString(key, value1).build()) 320 .build(); 321 WorkRequest prerequisiteWork2 = new WorkRequest.Builder(EchoingWorker.class) 322 .withInputData(new Data.Builder().putString(key, value2).build()) 323 .build(); 324 WorkRequest work = new WorkRequest.Builder(TestWorker.class) 325 .withInputMerger(ArrayCreatingInputMerger.class) 326 .build(); 327 Dependency dependency1 = new Dependency(work.getId(), prerequisiteWork1.getId()); 328 Dependency dependency2 = new Dependency(work.getId(), prerequisiteWork2.getId()); 329 330 mDatabase.beginTransaction(); 331 try { 332 insertWork(prerequisiteWork1); 333 insertWork(prerequisiteWork2); 334 insertWork(work); 335 mDependencyDao.insertDependency(dependency1); 336 mDependencyDao.insertDependency(dependency2); 337 mDatabase.setTransactionSuccessful(); 338 } finally { 339 mDatabase.endTransaction(); 340 } 341 342 // Run the prerequisites. 343 new WorkerWrapper.Builder(mContext, mDatabase, prerequisiteWork1.getId()) 344 .withSchedulers(Collections.singletonList(mMockScheduler)) 345 .build().run(); 346 347 new WorkerWrapper.Builder(mContext, mDatabase, prerequisiteWork2.getId()) 348 .withSchedulers(Collections.singletonList(mMockScheduler)) 349 .build().run(); 350 351 // Create and run the dependent work. 352 WorkerWrapper workerWrapper = new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 353 .withSchedulers(Collections.singletonList(mMockScheduler)) 354 .build(); 355 workerWrapper.run(); 356 357 Data input = workerWrapper.mWorker.getInputData(); 358 assertThat(input.size(), is(1)); 359 assertThat(Arrays.asList(input.getStringArray(key)), 360 containsInAnyOrder(value1, value2)); 361 } 362 363 @Test 364 @SmallTest 365 public void testDependencies_setsPeriodStartTimesForUnblockedWork() { 366 WorkRequest prerequisiteWork = new WorkRequest.Builder(TestWorker.class).build(); 367 WorkRequest work = new WorkRequest.Builder(TestWorker.class) 368 .withInitialState(BLOCKED) 369 .build(); 370 Dependency dependency = new Dependency(work.getId(), prerequisiteWork.getId()); 371 372 mDatabase.beginTransaction(); 373 try { 374 insertWork(prerequisiteWork); 375 insertWork(work); 376 mDependencyDao.insertDependency(dependency); 377 mDatabase.setTransactionSuccessful(); 378 } finally { 379 mDatabase.endTransaction(); 380 } 381 382 long beforeUnblockedTime = System.currentTimeMillis(); 383 384 new WorkerWrapper.Builder(mContext, mDatabase, prerequisiteWork.getId()) 385 .withListener(mMockListener) 386 .withSchedulers(Collections.singletonList(mMockScheduler)) 387 .build() 388 .run(); 389 390 WorkSpec workSpec = mWorkSpecDao.getWorkSpec(work.getId()); 391 assertThat(workSpec.periodStartTime, is(greaterThan(beforeUnblockedTime))); 392 } 393 394 @Test 395 @SmallTest 396 public void testDependencies_failsUncancelledDependentsOnFailure() { 397 WorkRequest prerequisiteWork = new WorkRequest.Builder(FailureWorker.class).build(); 398 WorkRequest work = new WorkRequest.Builder(TestWorker.class) 399 .withInitialState(BLOCKED) 400 .build(); 401 WorkRequest cancelledWork = new WorkRequest.Builder(TestWorker.class) 402 .withInitialState(CANCELLED) 403 .build(); 404 Dependency dependency1 = new Dependency(work.getId(), prerequisiteWork.getId()); 405 Dependency dependency2 = new Dependency(cancelledWork.getId(), prerequisiteWork.getId()); 406 407 mDatabase.beginTransaction(); 408 try { 409 insertWork(prerequisiteWork); 410 insertWork(work); 411 insertWork(cancelledWork); 412 mDependencyDao.insertDependency(dependency1); 413 mDependencyDao.insertDependency(dependency2); 414 mDatabase.setTransactionSuccessful(); 415 } finally { 416 mDatabase.endTransaction(); 417 } 418 419 new WorkerWrapper.Builder(mContext, mDatabase, prerequisiteWork.getId()).build().run(); 420 421 assertThat(mWorkSpecDao.getState(prerequisiteWork.getId()), is(FAILED)); 422 assertThat(mWorkSpecDao.getState(work.getId()), is(FAILED)); 423 assertThat(mWorkSpecDao.getState(cancelledWork.getId()), is(CANCELLED)); 424 } 425 426 @Test 427 @SmallTest 428 public void testRun_periodicWork_success_updatesPeriodStartTime() { 429 long intervalDuration = PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS; 430 long periodStartTime = System.currentTimeMillis(); 431 long expectedNextPeriodStartTime = periodStartTime + intervalDuration; 432 433 PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder( 434 TestWorker.class, intervalDuration, TimeUnit.MILLISECONDS).build(); 435 436 getWorkSpec(periodicWork).periodStartTime = periodStartTime; 437 438 insertWork(periodicWork); 439 440 new WorkerWrapper.Builder(mContext, mDatabase, periodicWork.getId()) 441 .withListener(mMockListener) 442 .build() 443 .run(); 444 445 WorkSpec updatedWorkSpec = mWorkSpecDao.getWorkSpec(periodicWork.getId()); 446 assertThat(updatedWorkSpec.periodStartTime, is(expectedNextPeriodStartTime)); 447 } 448 449 @Test 450 @SmallTest 451 public void testRun_periodicWork_failure_updatesPeriodStartTime() { 452 long intervalDuration = PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS; 453 long periodStartTime = System.currentTimeMillis(); 454 long expectedNextPeriodStartTime = periodStartTime + intervalDuration; 455 456 PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder( 457 FailureWorker.class, intervalDuration, TimeUnit.MILLISECONDS).build(); 458 459 getWorkSpec(periodicWork).periodStartTime = periodStartTime; 460 461 insertWork(periodicWork); 462 463 new WorkerWrapper.Builder(mContext, mDatabase, periodicWork.getId()) 464 .withListener(mMockListener) 465 .build() 466 .run(); 467 468 WorkSpec updatedWorkSpec = mWorkSpecDao.getWorkSpec(periodicWork.getId()); 469 assertThat(updatedWorkSpec.periodStartTime, is(expectedNextPeriodStartTime)); 470 } 471 472 @Test 473 @SmallTest 474 public void testPeriodicWork_success() { 475 PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder( 476 TestWorker.class, 477 PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, 478 TimeUnit.MILLISECONDS) 479 .build(); 480 481 final String periodicWorkId = periodicWork.getId(); 482 insertWork(periodicWork); 483 new WorkerWrapper.Builder(mContext, mDatabase, periodicWorkId) 484 .withListener(mMockListener) 485 .build() 486 .run(); 487 488 WorkSpec periodicWorkSpecAfterFirstRun = mWorkSpecDao.getWorkSpec(periodicWorkId); 489 verify(mMockListener).onExecuted(periodicWorkId, true, false); 490 assertThat(periodicWorkSpecAfterFirstRun.runAttemptCount, is(0)); 491 assertThat(periodicWorkSpecAfterFirstRun.state, is(ENQUEUED)); 492 } 493 494 @Test 495 @SmallTest 496 public void testPeriodicWork_fail() { 497 PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder( 498 FailureWorker.class, 499 PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, 500 TimeUnit.MILLISECONDS) 501 .build(); 502 503 final String periodicWorkId = periodicWork.getId(); 504 insertWork(periodicWork); 505 new WorkerWrapper.Builder(mContext, mDatabase, periodicWorkId) 506 .withListener(mMockListener) 507 .build() 508 .run(); 509 510 WorkSpec periodicWorkSpecAfterFirstRun = mWorkSpecDao.getWorkSpec(periodicWorkId); 511 verify(mMockListener).onExecuted(periodicWorkId, false, false); 512 assertThat(periodicWorkSpecAfterFirstRun.runAttemptCount, is(0)); 513 assertThat(periodicWorkSpecAfterFirstRun.state, is(ENQUEUED)); 514 } 515 516 @Test 517 @SmallTest 518 public void testPeriodicWork_retry() { 519 PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder( 520 RetryWorker.class, 521 PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, 522 TimeUnit.MILLISECONDS) 523 .build(); 524 525 final String periodicWorkId = periodicWork.getId(); 526 insertWork(periodicWork); 527 new WorkerWrapper.Builder(mContext, mDatabase, periodicWorkId) 528 .withListener(mMockListener) 529 .build() 530 .run(); 531 532 WorkSpec periodicWorkSpecAfterFirstRun = mWorkSpecDao.getWorkSpec(periodicWorkId); 533 verify(mMockListener).onExecuted(periodicWorkId, false, true); 534 assertThat(periodicWorkSpecAfterFirstRun.runAttemptCount, is(1)); 535 assertThat(periodicWorkSpecAfterFirstRun.state, is(ENQUEUED)); 536 } 537 538 @Test 539 @SmallTest 540 public void testScheduler() { 541 WorkRequest work = new WorkRequest.Builder(TestWorker.class).build(); 542 insertWork(work); 543 Scheduler mockScheduler = mock(Scheduler.class); 544 545 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 546 .withSchedulers(Collections.singletonList(mockScheduler)) 547 .build() 548 .run(); 549 550 verify(mockScheduler).schedule(); 551 } 552 553 @Test 554 @SmallTest 555 public void testFromWorkSpec_hasAppContext() { 556 WorkRequest work = new WorkRequest.Builder(TestWorker.class).build(); 557 Worker worker = WorkerWrapper.workerFromWorkSpec( 558 mContext, 559 getWorkSpec(work), 560 Data.EMPTY, 561 null); 562 563 assertThat(worker, is(notNullValue())); 564 assertThat(worker.getAppContext(), is(equalTo(mContext.getApplicationContext()))); 565 } 566 567 @Test 568 @SmallTest 569 public void testFromWorkSpec_hasCorrectArguments() { 570 String key = "KEY"; 571 String expectedValue = "VALUE"; 572 Data input = new Data.Builder().putString(key, expectedValue).build(); 573 574 WorkRequest work = new WorkRequest.Builder(TestWorker.class).withInputData(input).build(); 575 Worker worker = WorkerWrapper.workerFromWorkSpec( 576 mContext, 577 getWorkSpec(work), 578 input, 579 null); 580 581 assertThat(worker, is(notNullValue())); 582 assertThat(worker.getInputData().getString(key, null), is(expectedValue)); 583 584 work = new WorkRequest.Builder(TestWorker.class).build(); 585 worker = WorkerWrapper.workerFromWorkSpec( 586 mContext, 587 getWorkSpec(work), 588 Data.EMPTY, 589 null); 590 591 assertThat(worker, is(notNullValue())); 592 assertThat(worker.getInputData().size(), is(0)); 593 } 594 595 @Test 596 @SmallTest 597 public void testSuccess_withPendingScheduledWork() { 598 WorkRequest work = new WorkRequest.Builder(TestWorker.class).build(); 599 insertWork(work); 600 601 WorkRequest unscheduled = new WorkRequest.Builder(TestWorker.class).build(); 602 insertWork(unscheduled); 603 604 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 605 .withSchedulers(Collections.singletonList(mMockScheduler)) 606 .withListener(mMockListener) 607 .build() 608 .run(); 609 610 verify(mMockScheduler, times(1)).schedule(unscheduled.getWorkSpec()); 611 verify(mMockListener).onExecuted(work.getId(), true, false); 612 assertThat(mWorkSpecDao.getState(work.getId()), is(SUCCEEDED)); 613 } 614 615 @Test 616 @SmallTest 617 public void testFailure_withPendingScheduledWork() { 618 WorkRequest work = new WorkRequest.Builder(FailureWorker.class).build(); 619 insertWork(work); 620 621 WorkRequest unscheduled = new WorkRequest.Builder(TestWorker.class).build(); 622 insertWork(unscheduled); 623 624 new WorkerWrapper.Builder(mContext, mDatabase, work.getId()) 625 .withSchedulers(Collections.singletonList(mMockScheduler)) 626 .withListener(mMockListener) 627 .build() 628 .run(); 629 630 verify(mMockScheduler, times(1)).schedule(unscheduled.getWorkSpec()); 631 verify(mMockListener).onExecuted(work.getId(), false, false); 632 assertThat(mWorkSpecDao.getState(work.getId()), is(FAILED)); 633 } 634} 635