/* * Copyright 2014 Effektif GmbH. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.effektif.workflow.test.api; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.List; import org.joda.time.LocalDateTime; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.effektif.workflow.api.json.TypeName; import com.effektif.workflow.impl.job.AbstractJobType; import com.effektif.workflow.impl.job.Job; import com.effektif.workflow.impl.job.JobController; import com.effektif.workflow.impl.job.JobExecution; import com.effektif.workflow.impl.util.Time; import com.effektif.workflow.test.JobWorkflowTest; /** * @author Tom Baeyens */ public class JobServiceTest extends JobWorkflowTest { public static final Logger log = LoggerFactory.getLogger(JobServiceTest.class); @TypeName("tst") public static class TestJob extends AbstractJobType { static List<JobExecution> jobExecutions; static boolean throwException; @Override public void execute(JobController jobController) { jobExecutions.add((JobExecution)jobController); if (throwException) { jobController.log("oops"); throw new RuntimeException("oops"); } else { jobController.log(":ok_hand:"); } } } @Before public void before() { TestJob.jobExecutions = new ArrayList<>(); TestJob.throwException = false; Time.now = null; } // @Test // public void testWorkfowJobOK() throws Exception { // // quickest way to get a processInstanceId // Workflow workflow = new Workflow() // .activity("t", new UserTask()); // deploy(workflow); // String workflowInstanceId = start(workflow).getId(); // // jobService.scheduleJob(new Job() // .jobType(new TestJob()) // .dueDate(Time.now()) // .processInstanceId(workflowInstanceId)); // // assertEquals(0, TestJob.jobExecutions.size()); // checkOtherJobs(); // assertEquals(0, TestJob.jobExecutions.size()); // checkProcessJobs(); // only this one should execute the job // assertEquals(1, TestJob.jobExecutions.size()); // checkOtherJobs(); // assertEquals(1, TestJob.jobExecutions.size()); // checkProcessJobs(); // assertEquals(1, TestJob.jobExecutions.size()); // // JobExecution jobExecution = TestJob.jobExecutions.get(0); // assertNull(jobExecution.error); // } // @Test // public void testRealProcessJobOK() throws Exception { // // quickest way to get a processInstanceId // WorkflowBuilder w = processEngine.newWorkflow(); // w.newActivity("t", new UserTask()) // .newTimer(new TestJob()) // ; // String workflowId = w.deploy(); // String workflowInstanceId = processEngine.newStart() // .workflowId(workflowId) // .startWorkflowInstance() // .getId(); // // jobService.newJob(new TestJob()) // .dueDate(Time.now()) // .processInstanceId(workflowInstanceId) // .save(); // // assertEquals(0, TestJob.jobExecutions.size()); // checkOtherJobs(); // assertEquals(0, TestJob.jobExecutions.size()); // checkProcessJobs(); // only this one should execute the job // assertEquals(1, TestJob.jobExecutions.size()); // checkOtherJobs(); // assertEquals(1, TestJob.jobExecutions.size()); // checkProcessJobs(); // assertEquals(1, TestJob.jobExecutions.size()); // // JobExecution jobExecution = TestJob.jobExecutions.get(0); // assertNull(jobExecution.error); // } @Test public void testJobOK() throws Exception { jobService.saveJob(new Job() .jobType(new TestJob()) .dueDate(Time.now())); checkWorkflowInstanceJobs(); assertEquals(0, TestJob.jobExecutions.size()); checkJobs(); // only this one should execute the job assertEquals(1, TestJob.jobExecutions.size()); checkJobs(); assertEquals(1, TestJob.jobExecutions.size()); checkWorkflowInstanceJobs(); assertEquals(1, TestJob.jobExecutions.size()); JobExecution jobExecution = TestJob.jobExecutions.get(0); assertNull(jobExecution.error); } @Test public void testJobFailAndRecover() throws Exception { jobService.saveJob(new Job() .jobType(new TestJob()) .dueDate(Time.now())); TestJob.throwException = true; assertEquals(0, TestJob.jobExecutions.size()); checkJobs(); assertEquals(1, TestJob.jobExecutions.size()); assertTrue(TestJob.jobExecutions.get(0).error); assertNull(TestJob.jobExecutions.get(0).job.done); // the default retry reschedule is 3 seconds Time.now = new LocalDateTime().plusMinutes(10); TestJob.throwException = false; checkJobs(); assertEquals(2, TestJob.jobExecutions.size()); assertNull(TestJob.jobExecutions.get(1).error); assertNotNull(TestJob.jobExecutions.get(1).job.done); } @Test public void testJobFailTillDead() throws Exception { jobService.saveJob(new Job() .jobType(new TestJob()) .dueDate(Time.now())); TestJob.throwException = true; checkJobs(); assertEquals(1, TestJob.jobExecutions.size()); JobExecution jobExecution = TestJob.jobExecutions.get(0); assertTrue(jobExecution.error); assertNull(jobExecution.job.done); assertNull(jobExecution.job.dead); // the first retry rescheduled in 3 seconds Time.now = new LocalDateTime().plusSeconds(4); checkJobs(); assertEquals(2, TestJob.jobExecutions.size()); jobExecution = TestJob.jobExecutions.get(1); assertTrue(jobExecution.error); assertNull(jobExecution.job.done); assertNull(jobExecution.job.dead); // the second retry rescheduled in an hour seconds Time.now = new LocalDateTime().plusHours(2); checkJobs(); assertEquals(3, TestJob.jobExecutions.size()); jobExecution = TestJob.jobExecutions.get(2); assertTrue(jobExecution.error); assertNull(jobExecution.job.done); assertNull(jobExecution.job.dead); // the second retry rescheduled in an hour seconds Time.now = new LocalDateTime().plusDays(2); checkJobs(); assertEquals(4, TestJob.jobExecutions.size()); jobExecution = TestJob.jobExecutions.get(3); assertTrue(jobExecution.error); // But now the job should be dead assertNotNull(jobExecution.job.done); assertTrue(jobExecution.job.dead); } @Test public void testUniqueJob() throws Exception { jobService.saveJob(new Job() .key("uniqueid") .jobType(new TestJob()) .dueDate(Time.now())); jobService.saveJob(new Job() .key("uniqueid") .jobType(new TestJob()) .dueDate(Time.now())); checkJobs(); assertEquals(1, TestJob.jobExecutions.size()); } }