use of com.birbit.android.jobqueue.JobManager in project android-priority-jobqueue by yigit.
the class RetryLogicTest method testChangeDelayOfTheGroup.
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void testChangeDelayOfTheGroup(Boolean persistent) throws InterruptedException {
final JobManager jobManager = createJobManager();
canRun = true;
final RetryJob job1 = new RetryJob(new Params(2).setPersistent(Boolean.TRUE.equals(persistent)).groupBy("g1"));
job1.identifier = "job 1 id";
RetryJob job2 = new RetryJob(new Params(2).setPersistent(!Boolean.FALSE.equals(persistent)).groupBy("g1"));
job2.identifier = "job 2 id";
job1.retryLimit = 2;
job2.retryLimit = 2;
final String job1Id = job1.identifier;
final String job2Id = job2.identifier;
final PersistableDummyJob postTestJob = new PersistableDummyJob(new Params(1).groupBy("g1").setPersistent(Boolean.TRUE.equals(persistent)));
final Semaphore jobsCanRun = new Semaphore(4);
jobsCanRun.acquire(3);
final Job[] unexpectedRun = new Job[1];
final CallbackManager callbackManager = JobManagerTrojan.getCallbackManager(jobManager);
retryProvider = new RetryProvider() {
@Override
public RetryConstraint build(Job job, Throwable throwable, int runCount, int maxRunCount) {
RetryConstraint constraint = new RetryConstraint(true);
constraint.setNewDelayInMs(2000L);
JqLog.d("setting new delay in mS to %s. now is %s. job is %s", 2000, mockTimer.nanoTime(), ((RetryJob) job).identifier);
constraint.setApplyNewDelayToGroup(true);
return constraint;
}
};
final List<Pair<String, Long>> runTimes = new ArrayList<>();
final Map<String, Long> cancelTimes = new HashMap<>();
final Throwable[] lastJobRunOrder = new Throwable[1];
onRunCallback = new Callback() {
@Override
public void on(Job job) {
if (!callbackManager.waitUntilAllMessagesAreConsumed(30)) {
lastJobRunOrder[0] = new RuntimeException("consumers did not finish in 30 seconds");
}
RetryJob retryJob = (RetryJob) job;
if (!jobsCanRun.tryAcquire() && unexpectedRun[0] == null) {
unexpectedRun[0] = job;
}
runTimes.add(new Pair<>(retryJob.identifier, mockTimer.nanoTime()));
}
};
onCancelCallback = new CancelCallback() {
@Override
public void on(Job job, int cancelReason, Throwable throwable) {
JqLog.d("on cancel of job %s", job);
RetryJob retryJob = (RetryJob) job;
assertThat("Job should cancel only once", cancelTimes.containsKey(retryJob.identifier), is(false));
cancelTimes.put(retryJob.identifier, mockTimer.nanoTime());
if (!job.isPersistent() || postTestJob.isPersistent()) {
if (dummyJobRunLatch.getCount() != 1) {
lastJobRunOrder[0] = new Exception("the 3rd job should not run until others cancel fully");
}
}
}
};
cancelLatch = new CountDownLatch(2);
final CountDownLatch jobRunLatch = new CountDownLatch(5);
final Throwable[] afterJobError = new Throwable[1];
jobManager.addCallback(new JobManagerCallbackAdapter() {
@Override
public void onJobRun(@NonNull Job job, int resultCode) {
synchronized (this) {
try {
if (job instanceof RetryJob) {
RetryJob retryJob = (RetryJob) job;
if (retryJob.identifier.equals(job1Id) && retryJob.getCurrentRunCount() == retryJob.getRetryLimit()) {
jobsCanRun.release();
}
}
} catch (Throwable t) {
afterJobError[0] = t;
}
}
}
@Override
public void onAfterJobRun(@NonNull Job job, int resultCode) {
synchronized (this) {
try {
if (job instanceof RetryJob) {
assertThat("no job should have run unexpectedly " + jobRunLatch.getCount(), unexpectedRun[0], nullValue());
RetryJob retryJob = (RetryJob) job;
if (retryJob.getCurrentRunCount() == 2) {
// next job should be ready, asserted in onRun
} else {
mockTimer.incrementMs(1999);
assertThat("no jobs should be ready", jobManager.countReadyJobs(), is(0));
jobsCanRun.release();
mockTimer.incrementMs(2);
}
}
} catch (Throwable t) {
afterJobError[0] = t;
jobRunLatch.countDown();
jobRunLatch.countDown();
jobRunLatch.countDown();
jobRunLatch.countDown();
jobRunLatch.countDown();
} finally {
jobRunLatch.countDown();
}
}
}
});
jobManager.addJob(job1);
jobManager.addJob(job2);
jobManager.addJob(postTestJob);
assertThat("all expected jobs should run", jobRunLatch.await(5, TimeUnit.MINUTES), is(true));
assertThat("on run assertions should all pass", afterJobError[0], nullValue());
assertThat("jobs should be canceled", cancelLatch.await(1, TimeUnit.MILLISECONDS), is(true));
assertThat("should run 4 times", runTimes.size(), is(4));
for (int i = 0; i < 4; i++) {
assertThat("first two runs should be job1, last two jobs should be job 2. checking " + i, runTimes.get(i).first, is(i < 2 ? job1Id : job2Id));
}
long timeInBetween = TimeUnit.NANOSECONDS.toSeconds(runTimes.get(1).second - runTimes.get(0).second);
assertThat("time between two runs should be at least 2 seconds. job 1 and 2" + ":" + timeInBetween, 2 <= timeInBetween, is(true));
timeInBetween = TimeUnit.NANOSECONDS.toSeconds(runTimes.get(3).second - runTimes.get(2).second);
assertThat("time between two runs should be at least 2 seconds. job 3 and 4" + ":" + timeInBetween, 2 <= timeInBetween, is(true));
assertThat("the other job should run after others are cancelled", dummyJobRunLatch.await(1, TimeUnit.SECONDS), is(true));
// another job should just run
dummyJobRunLatch = new CountDownLatch(1);
jobManager.addJob(new PersistableDummyJob(new Params(1).groupBy("g1")));
assertThat("a newly added job should just run quickly", dummyJobRunLatch.await(500, TimeUnit.MILLISECONDS), is(true));
assertThat(lastJobRunOrder[0], nullValue());
}
use of com.birbit.android.jobqueue.JobManager in project android-priority-jobqueue by yigit.
the class DeadlineTest method deadlineTest.
@Test
public void deadlineTest() throws Exception {
DummyNetworkUtil networkUtil = new DummyNetworkUtilWithConnectivityEventSupport();
JobManager jobManager = createJobManager(new Configuration.Builder(RuntimeEnvironment.application).networkUtil(networkUtil).timer(mockTimer));
networkUtil.setNetworkStatus(NetworkUtil.DISCONNECTED);
Params params = new Params(0).setPersistent(persistent).setRequiresNetwork(reqNetwork).setRequiresUnmeteredNetwork(reqUnmeteredNetwork).delayInMs(delay);
if (cancelOnDeadline) {
params.overrideDeadlineToCancelInMs(200);
} else {
params.overrideDeadlineToRunInMs(200);
}
DeadlineJob job = new DeadlineJob(params);
jobManager.addJob(job);
if (!reqNetwork && !reqUnmeteredNetwork) {
if (delay > 0) {
assertThat(DeadlineJob.runLatch.await(3, TimeUnit.SECONDS), is(false));
assertThat(DeadlineJob.cancelLatch.await(3, TimeUnit.SECONDS), is(false));
mockTimer.incrementMs(delay);
}
// no network is required, it should run
assertThat(DeadlineJob.runLatch.await(3, TimeUnit.SECONDS), is(true));
assertThat(DeadlineJob.cancelLatch.await(3, TimeUnit.SECONDS), is(false));
assertThat(DeadlineJob.wasDeadlineReached, is(false));
return;
}
assertThat(DeadlineJob.runLatch.await(3, TimeUnit.SECONDS), is(false));
assertThat(DeadlineJob.cancelLatch.await(1, TimeUnit.MILLISECONDS), is(false));
mockTimer.incrementMs(200);
if (cancelOnDeadline) {
assertThat(DeadlineJob.cancelLatch.await(3, TimeUnit.SECONDS), is(true));
assertThat(DeadlineJob.runLatch.await(1, TimeUnit.SECONDS), is(false));
assertThat(DeadlineJob.cancelReason, is(CancelReason.REACHED_DEADLINE));
} else {
assertThat(DeadlineJob.runLatch.await(3, TimeUnit.SECONDS), is(true));
assertThat(DeadlineJob.cancelLatch.await(1, TimeUnit.SECONDS), is(false));
assertThat(DeadlineJob.cancelReason, is(-1));
}
assertThat(DeadlineJob.wasDeadlineReached, is(true));
}
use of com.birbit.android.jobqueue.JobManager in project android-priority-jobqueue by yigit.
the class DelayedRunTest method testDelayWith0Consumers.
@Test
public void testDelayWith0Consumers() throws InterruptedException {
JobManager jobManager = createJobManager(new Configuration.Builder(RuntimeEnvironment.application).minConsumerCount(0).maxConsumerCount(3).timer(mockTimer));
final CountDownLatch latch = new CountDownLatch(1);
final DummyJob dummyJob = new DummyJob(new Params(0).delayInMs(2000)) {
@Override
public void onRun() throws Throwable {
super.onRun();
latch.countDown();
}
};
jobManager.addJob(dummyJob);
mockTimer.incrementMs(1999);
assertThat("there should not be any ready jobs", jobManager.countReadyJobs(), is(0));
waitUntilAJobIsDone(jobManager, new WaitUntilCallback() {
@Override
public void run() {
mockTimer.incrementMs(1002);
}
@Override
public void assertJob(Job job) {
assertThat("should be the dummy job", job, is((Job) dummyJob));
}
});
assertThat("job should run in 3 seconds", latch.await(3, TimeUnit.NANOSECONDS), is(true));
}
use of com.birbit.android.jobqueue.JobManager in project android-priority-jobqueue by yigit.
the class DelayedRunTest method delayedRunTest.
public void delayedRunTest(boolean persist, boolean tryToStop) throws Exception {
final JobManager jobManager = createJobManager();
jobManager.addCallback(new JobManagerCallbackAdapter() {
@Override
public void onJobRun(@NonNull Job job, int resultCode) {
super.onJobRun(job, resultCode);
System.out.println("CB job run " + job.getTags().toArray()[0] + ", " + mockTimer.nanoTime());
}
@Override
public void onDone(@NonNull Job job) {
System.out.println("CB job done " + job.getTags().toArray()[0] + ", " + mockTimer.nanoTime());
}
@Override
public void onAfterJobRun(@NonNull Job job, int resultCode) {
System.out.println("CB job after run " + job.getTags().toArray()[0] + ", " + mockTimer.nanoTime());
}
});
final DummyJob delayedJob = new DummyJob(new Params(10).delayInMs(2000).setPersistent(persist).addTags("delayed"));
final DummyJob nonDelayedJob = new DummyJob(new Params(0).setPersistent(persist).addTags("notDelayed"));
waitUntilAJobIsDone(jobManager, new WaitUntilCallback() {
@Override
public void run() {
jobManager.addJob(delayedJob);
jobManager.addJob(nonDelayedJob);
}
@Override
public void assertJob(Job job) {
assertThat("correct job should run first", (String) job.getTags().toArray()[0], is("notDelayed"));
}
});
MatcherAssert.assertThat("there should be 1 delayed job waiting to be run", jobManager.count(), equalTo(1));
if (tryToStop) {
//see issue #11
jobManager.stopAndWaitUntilConsumersAreFinished();
mockTimer.incrementMs(3000);
MatcherAssert.assertThat("there should still be 1 delayed job waiting to be run when job manager is stopped", jobManager.count(), equalTo(1));
waitUntilAJobIsDone(jobManager, new WaitUntilCallback() {
@Override
public void run() {
jobManager.start();
}
@Override
public void assertJob(Job job) {
assertThat("correct job should run first", (String) job.getTags().toArray()[0], is("delayed"));
}
});
} else {
waitUntilAJobIsDone(jobManager, new WaitUntilCallback() {
@Override
public void run() {
mockTimer.incrementMs(3000);
}
@Override
public void assertJob(Job job) {
assertThat("correct job should run first", (String) job.getTags().toArray()[0], is("delayed"));
}
});
}
MatcherAssert.assertThat("all jobs should be completed", jobManager.count(), equalTo(0));
}
use of com.birbit.android.jobqueue.JobManager in project android-priority-jobqueue by yigit.
the class GroupingTest method testGroupingRaceCondition.
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@Test
public void testGroupingRaceCondition() throws Exception {
DummyNetworkUtilWithConnectivityEventSupport dummyNetworkUtil = new DummyNetworkUtilWithConnectivityEventSupport();
JobManager jobManager = createJobManager(new Configuration.Builder(RuntimeEnvironment.application).minConsumerCount(5).maxConsumerCount(10).networkUtil(dummyNetworkUtil).timer(mockTimer));
dummyNetworkUtil.setNetworkStatus(NetworkUtil.DISCONNECTED, true);
//add a bunch of network requring jobs
final String GROUP_ID = "shared_group_id";
final int AFTER_ADDED_JOBS_COUNT = 5;
final int NOT_SET_JOB_ID = -1;
final AtomicInteger firstRunJob = new AtomicInteger(NOT_SET_JOB_ID);
final int FIRST_JOB_ID = -10;
final CountDownLatch onAddedCalled = new CountDownLatch(1);
final CountDownLatch remainingJobsOnAddedCalled = new CountDownLatch(AFTER_ADDED_JOBS_COUNT);
final CountDownLatch aJobRun = new CountDownLatch(1);
jobManager.addCallback(new JobManagerCallbackAdapter() {
@Override
public void onJobRun(@NonNull Job job, int resultCode) {
aJobRun.countDown();
}
});
jobManager.addJobInBackground(new DummyJob(new Params(10).requireNetwork().groupBy(GROUP_ID)) {
@Override
public void onAdded() {
super.onAdded();
onAddedCalled.countDown();
}
@Override
public void onRun() throws Throwable {
super.onRun();
firstRunJob.compareAndSet(NOT_SET_JOB_ID, FIRST_JOB_ID);
}
});
//ensure first jobs on added is called
onAddedCalled.await();
for (int i = 0; i < AFTER_ADDED_JOBS_COUNT; i++) {
final int finalI = i;
jobManager.addJob(new DummyJob(new Params(5).groupBy(GROUP_ID).requireNetwork()) {
final int id = finalI + 1;
@Override
public void onAdded() {
super.onAdded();
remainingJobsOnAddedCalled.countDown();
}
@Override
public void onRun() throws Throwable {
super.onRun();
firstRunJob.compareAndSet(NOT_SET_JOB_ID, id);
}
});
}
dummyNetworkUtil.setNetworkStatus(NetworkUtil.METERED, true);
//wait until all jobs are completed
aJobRun.await(1, TimeUnit.MINUTES);
MatcherAssert.assertThat("highest priority job should run if it is added before others", firstRunJob.get(), is(FIRST_JOB_ID));
}
Aggregations