@Test public void testWriteToBundle_service() { Bundle b = writer.writeToBundle( initializeDefaultBuilder().setService(TestJobService.class).build(), new Bundle()); assertEquals("service", GooglePlayReceiver.class.getName(), b.getString("service")); }
@Test public void onReschedule_stopJob() { Bundle bundle = TestUtil.getBundleForContentJobExecution(); JobCoder prefixedCoder = new JobCoder(BundleProtocol.PACKED_PARAM_BUNDLE_PREFIX); JobInvocation invocation = prefixedCoder.decodeIntentBundle(bundle); Job job = TestUtil.getBuilderWithNoopValidator() .setService(TestJobService.class) .setTrigger(invocation.getTrigger()) .setTag(invocation.getTag()) .build(); receiver.prepareJob(jobCallbackMock, bundle); when(contextMock.bindService( any(Intent.class), any(JobServiceConnection.class), eq(BIND_AUTO_CREATE))) .thenReturn(true); new ExecutionDelegator(contextMock, mock(JobFinishedCallback.class), contraintCheckerMock) .executeJob(invocation); verify(contextMock) .bindService(any(Intent.class), jobServiceConnectionCaptor.capture(), eq(BIND_AUTO_CREATE)); assertTrue(jobServiceConnectionCaptor.getValue().hasJobInvocation(invocation)); GooglePlayReceiver.onSchedule(job); assertFalse(jobServiceConnectionCaptor.getValue().hasJobInvocation(invocation)); assertNull( "JobServiceConnection should be removed.", ExecutionDelegator.getJobServiceConnection(invocation.getService())); }
.newJobBuilder() .setConstraints(Constraint.DEVICE_CHARGING) .setService(TestJobService.class) .setTrigger(Trigger.executionWindow(0, 60)) .setRecurring(false)
.setService(SunshineFirebaseJobService.class)
.setService(SunshineFirebaseJobService.class)
.setLifetime(lifetime) .setTrigger(trigger) .setService(service) .setExtras(extras) .setRetryStrategy(rs)
@Test public void onStartJob_jobFinishedNotReschedule() throws Exception { // Verify that a termination request from within onStartJob will cause the result to be sent // to the bouncer service's handler, regardless of what value is ultimately returned from // onStartJob. JobService reschedulingService = new JobService() { @Override public boolean onStartJob(@NonNull JobParameters job) { jobFinished(job, false /* don't retry this job */); return false; } @Override public boolean onStopJob(@NonNull JobParameters job) { return false; } }; Job jobSpec = TestUtil.getBuilderWithNoopValidator() .setTag("tag") .setService(reschedulingService.getClass()) .setTrigger(Trigger.NOW) .build(); FutureSettingJobCallback callback = new FutureSettingJobCallback(); IRemoteJobService.Stub.asInterface(reschedulingService.onBind(null)) .start(getJobCoder().encode(jobSpec, new Bundle()), callback); flush(reschedulingService); callback.verifyCalledWithJobAndResult(jobSpec, JobService.RESULT_SUCCESS); }
@Test public void onStartJob_jobFinishedReschedule() throws Exception { // Verify that a retry request from within onStartJob will cause the retry result to be sent // to the bouncer service's handler, regardless of what value is ultimately returned from // onStartJob. JobService reschedulingService = new JobService() { @Override public boolean onStartJob(@NonNull JobParameters job) { // Reschedules job. jobFinished(job, true /* retry this job */); return false; } @Override public boolean onStopJob(@NonNull JobParameters job) { return false; } }; Job jobSpec = TestUtil.getBuilderWithNoopValidator() .setTag("tag") .setService(reschedulingService.getClass()) .setTrigger(Trigger.NOW) .build(); FutureSettingJobCallback callback = new FutureSettingJobCallback(); IRemoteJobService.Stub.asInterface(reschedulingService.onBind(null)) .start(getJobCoder().encode(jobSpec, new Bundle()), callback); flush(reschedulingService); callback.verifyCalledWithJobAndResult(jobSpec, JobService.RESULT_FAIL_RETRY); }
@Test public void testSchedule_failsWhenPlayServicesIsUnavailable() throws Exception { markBackendUnavailable(); mockPackageManagerInfo(); Job job = null; try { job = dispatcher .newJobBuilder() .setService(TestJobService.class) .setTag("foobar") .setConstraints(Constraint.DEVICE_CHARGING) .setTrigger(Trigger.executionWindow(0, 60)) .build(); } catch (ValidationEnforcer.ValidationException ve) { fail(TextUtils.join("\n", ve.getErrors())); } assertEquals( "Expected schedule() request to fail when backend is unavailable", FirebaseJobDispatcher.SCHEDULE_RESULT_NO_DRIVER_AVAILABLE, dispatcher.schedule(job)); }
@Test public void schedule_whenRunning_onStopIsCalled() { // simulate running job Bundle bundle = TestUtil.getBundleForContentJobExecution(); JobCoder prefixedCoder = new JobCoder(BundleProtocol.PACKED_PARAM_BUNDLE_PREFIX); JobInvocation invocation = prefixedCoder.decodeIntentBundle(bundle); googlePlayReceiver.prepareJob(jobCallbackMock, bundle); when(mMockContext.bindService( any(Intent.class), serviceConnectionCaptor.capture(), eq(BIND_AUTO_CREATE))) .thenReturn(true); new ExecutionDelegator(mMockContext, callbackMock, constraintCheckerMock) .executeJob(invocation); Job job = TestUtil.getBuilderWithNoopValidator() .setService(TestJobService.class) .setTrigger(invocation.getTrigger()) .setTag(invocation.getTag()) .build(); googlePlayDriver.schedule(job); // reschedule request during the execution verify(mMockContext).sendBroadcast(any(Intent.class)); assertTrue(serviceConnectionCaptor.getValue().wasUnbound()); assertNull( "JobServiceConnection should be removed.", ExecutionDelegator.getJobServiceConnection(invocation.getService())); }
private static void verifyOnUnbindCausesResult(JobService service, int expectedResult) throws Exception { Job jobSpec = TestUtil.getBuilderWithNoopValidator() .setTag("tag") .setService(service.getClass()) .setTrigger(Trigger.NOW) .build(); Bundle jobSpecData = getJobCoder().encode(jobSpec, new Bundle()); FutureSettingJobCallback callback = new FutureSettingJobCallback(); // start the service IRemoteJobService.Stub.asInterface(service.onBind(null)).start(jobSpecData, callback); // shouldn't have sent a result message yet (still doing background work) assertFalse(callback.getJobFinishedFuture().isDone()); // manually trigger the onUnbind hook service.onUnbind(new Intent()); flush(service); callback.verifyCalledWithJobAndResult(jobSpec, expectedResult); // Calling jobFinished should not attempt to send a second message callback.reset(); service.jobFinished(jobSpec, false); assertFalse(callback.getJobFinishedFuture().isDone()); }
@Test public void testOnStartCommand_handlesStartJob_validRequest() throws Exception { JobService service = spy(new ExampleJobService()); Job jobSpec = TestUtil.getBuilderWithNoopValidator() .setTag("tag") .setService(ExampleJobService.class) .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL) .setTrigger(Trigger.NOW) .setLifetime(Lifetime.FOREVER) .build(); countDownLatch = new CountDownLatch(1); Bundle jobSpecData = getJobCoder().encode(jobSpec, new Bundle()); IRemoteJobService remoteJobService = IRemoteJobService.Stub.asInterface(service.onBind(new Intent(JobService.ACTION_EXECUTE))); remoteJobService.start(jobSpecData, noopCallback); flush(service); assertTrue("Expected job to run to completion", countDownLatch.await(5, TimeUnit.SECONDS)); }
@Test public void testOnStartCommand_handlesStartJob_doNotStartRunningJobAgain() throws Exception { StoppableJobService service = new StoppableJobService(/* shouldReschedule= */ false); Job jobSpec = TestUtil.getBuilderWithNoopValidator() .setTag("tag") .setService(StoppableJobService.class) .setTrigger(Trigger.NOW) .build(); Bundle jobSpecData = getJobCoder().encode(jobSpec, new Bundle()); IRemoteJobService.Stub.asInterface(service.onBind(null)).start(jobSpecData, null); IRemoteJobService.Stub.asInterface(service.onBind(null)).start(jobSpecData, null); flush(service); assertEquals(1, service.getNumberOfStartRequestsReceived()); }
@Test public void onReschedule_notRunningWrongTag_noException() { Bundle bundle = TestUtil.getBundleForContentJobExecution(); Job job = TestUtil.getBuilderWithNoopValidator() .setService(TestJobService.class) .setTrigger(Trigger.NOW) .setTag("TAG") .build(); receiver.prepareJob(jobCallbackMock, bundle); GooglePlayReceiver.onSchedule(job); }
private static Builder setValidBuilderDefaults(Builder mBuilder) { return mBuilder .setTag("tag") .setTrigger(Trigger.NOW) .setService(TestJobService.class) .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL); }
private static Builder initializeDefaultBuilder() { return TestUtil.getBuilderWithNoopValidator() .setConstraints(Constraint.DEVICE_CHARGING) .setExtras(null) .setLifetime(Lifetime.FOREVER) .setRecurring(false) .setReplaceCurrent(false) .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL) .setService(TestJobService.class) .setTag("tag") .setTrigger(Trigger.NOW); }
@Test public void testDecode_failsWhenMissingFields() { assertNull( "Expected null tag to cause decoding to fail", coder.decode( coder.encode(setValidBuilderDefaults(builder).setTag(null).build(), new Bundle()))); assertNull( "Expected null service to cause decoding to fail", coder.decode( coder.encode(setValidBuilderDefaults(builder).setService(null).build(), new Bundle()))); }
@NonNull static Bundle encodeRecurringContentUriJob(ContentUriTrigger trigger, JobCoder coder) { Job job = getBuilderWithNoopValidator() .setTag(TAG) .setTrigger(trigger) .setService(TestJobService.class) .setReplaceCurrent(true) .setRecurring(true) .build(); return coder.encode(job, new Bundle()); }
@NonNull static Bundle encodeContentUriJob(ContentUriTrigger trigger, JobCoder coder) { Job job = getBuilderWithNoopValidator() .setTag(TAG) .setTrigger(trigger) .setService(TestJobService.class) .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL) .build(); return coder.encode(job, new Bundle()); }
@Test public void onReschedule_notRunning_noException() { Job job = TestUtil.getBuilderWithNoopValidator() .setService(TestJobService.class) .setTrigger(Trigger.NOW) .setTag("TAG") .build(); GooglePlayReceiver.onSchedule(job); }