@Test
  public void startAndRescheduleTwoJobs_workerProcess_stopOnReschedule() throws Exception {
    CountDownLatch startLatch = new CountDownLatch(2);
    // Does not need to be concurrent because access is guarded by the startLatch.
    Set<String> startedJobs = new HashSet<>();
    CountDownLatch stopLatch = new CountDownLatch(2);
    // Does not need to be concurrent because access is guarded by the stopLatch.
    Set<String> stoppedJobs = new HashSet<>();

    appContext.registerReceiver(
        new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
            Log.i(WorkerProcessTestJobService.TAG, "BroadcastReceiver intent " + intent);
            int eventType =
                intent.getExtras().getInt(WorkerProcessTestJobService.EXTRA_EVENT_TYPE, -1);
            String tag = intent.getExtras().getString(WorkerProcessTestJobService.EXTRA_BUNDLE_TAG);
            assertNotNull(tag);

            switch (eventType) {
              case WorkerProcessTestJobService.EVENT_TYPE_ON_START_JOB:
                startedJobs.add(tag);
                startLatch.countDown();
                break;
              case WorkerProcessTestJobService.EVENT_TYPE_ON_STOP_JOB:
                stoppedJobs.add(tag);
                stopLatch.countDown();
                break;
              default:
                fail("Unexpected event type " + eventType);
            }
            Bundle results = new Bundle();
            results.putBoolean(WorkerProcessTestJobService.EXTRA_MORE_WORK_REMAINING, true);
            setResultExtras(results);
          }
        },
        new IntentFilter(WorkerProcessTestJobService.ACTION_JOBSERVICE_EVENT));

    dispatcher.mustSchedule(
        dispatcher
            .newJobBuilder()
            .setService(WorkerProcessTestJobService.class)
            .setTrigger(Trigger.NOW)
            .setTag(FIRST_JOB)
            .build());

    dispatcher.mustSchedule(
        dispatcher
            .newJobBuilder()
            .setService(WorkerProcessTestJobService.class)
            .setTrigger(Trigger.NOW)
            .setTag(SECOND_JOB)
            .build());
    assertTrue(startLatch.await(120, TimeUnit.SECONDS));
    assertEquals(2, startedJobs.size());
    assertTrue(startedJobs.contains(FIRST_JOB));
    assertTrue(startedJobs.contains(SECOND_JOB));
    assertTrue(stoppedJobs.isEmpty());

    // reschedule
    dispatcher.mustSchedule(
        dispatcher
            .newJobBuilder()
            .setService(WorkerProcessTestJobService.class)
            .setTrigger(Trigger.NOW)
            .setTag(FIRST_JOB)
            .build());

    dispatcher.mustSchedule(
        dispatcher
            .newJobBuilder()
            .setService(WorkerProcessTestJobService.class)
            .setTrigger(Trigger.NOW)
            .setTag(SECOND_JOB)
            .build());

    assertTrue(stopLatch.await(120, TimeUnit.SECONDS));
    assertEquals(2, stoppedJobs.size());
    assertTrue(stoppedJobs.contains(FIRST_JOB));
    assertTrue(stoppedJobs.contains(SECOND_JOB));
  }
Basic end to end test for the JobDispatcher. Requires Google Play services be installed and
available.
jobdispatcher/src/androidTest/java/com/firebase/jobdispatcher/EndToEndAndroidTest.java