Closes #2222 refactor TaskCleanupJobAccTest to use new TestApi

Co-authored-by: Mustapha Zorgati <15628173+mustaphazorgati@users.noreply.github.com>
This commit is contained in:
arolfes 2023-04-13 11:56:47 +02:00 committed by Alex
parent ee914db0ca
commit 58a751a538
3 changed files with 419 additions and 265 deletions

View File

@ -0,0 +1,129 @@
package acceptance.jobs;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import pro.taskana.TaskanaConfiguration;
import pro.taskana.TaskanaConfiguration.Builder;
import pro.taskana.classification.internal.jobs.ClassificationChangedJob;
import pro.taskana.common.api.JobService;
import pro.taskana.common.api.ScheduledJob;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.internal.JobMapper;
import pro.taskana.common.internal.jobs.AbstractTaskanaJob;
import pro.taskana.common.internal.jobs.JobRunner;
import pro.taskana.task.internal.jobs.TaskCleanupJob;
import pro.taskana.task.internal.jobs.TaskRefreshJob;
import pro.taskana.testapi.TaskanaConfigurationModifier;
import pro.taskana.testapi.TaskanaInject;
import pro.taskana.testapi.TaskanaIntegrationTest;
import pro.taskana.testapi.security.WithAccessId;
@TaskanaIntegrationTest
class AbstractTaskanaJobAccTest {
@TaskanaInject JobMapper jobMapper;
@TaskanaInject JobService jobService;
@TaskanaInject TaskanaEngine taskanaEngine;
@TaskanaInject TaskanaConfiguration taskanaConfiguration;
@AfterEach
void cleanupJobs() {
// Dirty Hack, please refactor me with ticket https://github.com/Taskana/taskana/issues/2238
jobMapper.deleteMultiple(TaskCleanupJob.class.getName());
jobMapper.deleteMultiple(TaskRefreshJob.class.getName());
jobMapper.deleteMultiple(ClassificationChangedJob.class.getName());
}
@WithAccessId(user = "admin")
@Test
void should_SetNextScheduledJobBasedOnDueDateOfPredecessor_When_RunningTaskCleanupJob() {
List<ScheduledJob> jobsToRun = jobMapper.findJobsToRun(Instant.now());
assertThat(jobsToRun).isEmpty();
Instant firstDue = Instant.now().truncatedTo(ChronoUnit.MILLIS);
ScheduledJob scheduledJob = new ScheduledJob();
scheduledJob.setType(TaskCleanupJob.class.getName());
scheduledJob.setDue(firstDue);
jobService.createJob(scheduledJob);
jobsToRun = jobMapper.findJobsToRun(Instant.now());
assertThat(jobsToRun).extracting(ScheduledJob::getDue).containsExactly(firstDue);
JobRunner runner = new JobRunner(taskanaEngine);
runner.runJobs();
Duration runEvery = taskanaConfiguration.getJobRunEvery();
jobsToRun = jobMapper.findJobsToRun(Instant.now().plus(runEvery));
assertThat(jobsToRun).extracting(ScheduledJob::getDue).containsExactly(firstDue.plus(runEvery));
}
@WithAccessId(user = "admin")
@Test
void should_DeleteOldTaskCleanupJobs_When_InitializingSchedule() {
for (int i = 0; i < 10; i++) {
ScheduledJob job = new ScheduledJob();
job.setType(TaskCleanupJob.class.getName());
taskanaEngine.getJobService().createJob(job);
job.setType(TaskRefreshJob.class.getName());
taskanaEngine.getJobService().createJob(job);
job.setType(ClassificationChangedJob.class.getName());
taskanaEngine.getJobService().createJob(job);
}
List<ScheduledJob> jobsToRun = jobMapper.findJobsToRun(Instant.now());
assertThat(jobsToRun).hasSize(30);
List<ScheduledJob> taskCleanupJobs =
jobsToRun.stream()
.filter(scheduledJob -> scheduledJob.getType().equals(TaskCleanupJob.class.getName()))
.collect(Collectors.toList());
AbstractTaskanaJob.initializeSchedule(taskanaEngine, TaskCleanupJob.class);
jobsToRun = jobMapper.findJobsToRun(Instant.now());
assertThat(jobsToRun).doesNotContainAnyElementsOf(taskCleanupJobs);
}
@Nested
@TestInstance(Lifecycle.PER_CLASS)
class CleanCompletedTasks implements TaskanaConfigurationModifier {
@TaskanaInject TaskanaEngine taskanaEngine;
@TaskanaInject JobMapper jobMapper;
@Override
public Builder modify(Builder builder) {
return builder
.taskCleanupJobEnabled(true)
.jobRunEvery(Duration.ofMillis(1))
.jobFirstRun(Instant.now().plus(5, ChronoUnit.MINUTES));
}
@WithAccessId(user = "admin")
@Test
void should_FindNoJobsToRunUntilFirstRunIsReached_When_CleanupScheduleIsInitialized()
throws Exception {
AbstractTaskanaJob.initializeSchedule(taskanaEngine, TaskCleanupJob.class);
List<ScheduledJob> nextJobs = jobMapper.findJobsToRun(Instant.now());
assertThat(nextJobs).isEmpty();
}
}
}

View File

@ -0,0 +1,290 @@
package acceptance.jobs;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.function.ThrowingConsumer;
import pro.taskana.TaskanaConfiguration.Builder;
import pro.taskana.classification.api.ClassificationService;
import pro.taskana.classification.api.models.ClassificationSummary;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.models.ObjectReference;
import pro.taskana.task.api.models.TaskSummary;
import pro.taskana.task.internal.jobs.TaskCleanupJob;
import pro.taskana.testapi.DefaultTestEntities;
import pro.taskana.testapi.TaskanaConfigurationModifier;
import pro.taskana.testapi.TaskanaInject;
import pro.taskana.testapi.TaskanaIntegrationTest;
import pro.taskana.testapi.builder.TaskBuilder;
import pro.taskana.testapi.security.WithAccessId;
import pro.taskana.workbasket.api.WorkbasketService;
import pro.taskana.workbasket.api.models.WorkbasketSummary;
// All tests are executed as admin, because the jobrunner needs admin rights.
@TaskanaIntegrationTest
class TaskCleanupJobAccTest {
@TaskanaInject TaskService taskService;
@TaskanaInject WorkbasketService workbasketService;
@TaskanaInject ClassificationService classificationService;
ClassificationSummary classification;
ObjectReference primaryObjRef;
@WithAccessId(user = "businessadmin")
@BeforeAll
void setup() throws Exception {
classification =
DefaultTestEntities.defaultTestClassification()
.buildAndStoreAsSummary(classificationService);
primaryObjRef = DefaultTestEntities.defaultTestObjectReference().build();
}
@Nested
@TestInstance(Lifecycle.PER_CLASS)
class CleanCompletedTasks implements TaskanaConfigurationModifier {
WorkbasketSummary workbasket;
@TaskanaInject TaskanaEngine taskanaEngine;
@Override
public Builder modify(Builder builder) {
return builder
.taskCleanupJobEnabled(true)
.jobFirstRun(Instant.now().minus(10, ChronoUnit.MILLIS))
.jobRunEvery(Duration.ofMillis(1))
.taskCleanupJobMinimumAge(Duration.ofDays(5));
}
@WithAccessId(user = "businessadmin")
@BeforeAll
void setup() throws Exception {
workbasket =
DefaultTestEntities.defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);
}
@WithAccessId(user = "admin")
@Test
void should_CleanCompletedTasks_When_CompletedTimestampIsOlderThenTaskCleanupJobMinimumAge()
throws Exception {
TaskBuilder.newTask()
.workbasketSummary(workbasket)
.classificationSummary(classification)
.primaryObjRef(primaryObjRef)
.state(TaskState.COMPLETED)
.completed(Instant.now().minus(6, ChronoUnit.DAYS))
.buildAndStoreAsSummary(taskService);
TaskCleanupJob job = new TaskCleanupJob(taskanaEngine, null, null);
job.run();
List<TaskSummary> taskSummaries = taskService.createTaskQuery().list();
assertThat(taskSummaries)
.filteredOn(t -> t.getWorkbasketSummary().equals(workbasket))
.isEmpty();
}
}
@Nested
@TestInstance(Lifecycle.PER_CLASS)
class NotCleanCompletedTasksWhereDateIsNotReached implements TaskanaConfigurationModifier {
@TaskanaInject TaskanaEngine taskanaEngine;
@Override
public Builder modify(Builder builder) {
return builder
.taskCleanupJobEnabled(true)
.jobFirstRun(Instant.now().minus(10, ChronoUnit.MILLIS))
.jobRunEvery(Duration.ofMillis(1))
.taskCleanupJobMinimumAge(Duration.ofDays(5));
}
@WithAccessId(user = "admin")
@Test
void should_NotCleanCompletedTasksAfterDefinedDay() throws Exception {
WorkbasketSummary workbasket =
DefaultTestEntities.defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);
TaskSummary taskSummary =
TaskBuilder.newTask()
.workbasketSummary(workbasket)
.classificationSummary(classification)
.primaryObjRef(primaryObjRef)
.state(TaskState.COMPLETED)
.completed(Instant.now().minus(3, ChronoUnit.DAYS))
.buildAndStoreAsSummary(taskService);
TaskCleanupJob job = new TaskCleanupJob(taskanaEngine, null, null);
job.run();
List<TaskSummary> taskSummaries = taskService.createTaskQuery().list();
assertThat(taskSummaries)
.filteredOn(t -> t.getWorkbasketSummary().equals(workbasket))
.containsExactlyInAnyOrder(taskSummary);
}
@WithAccessId(user = "admin")
@Test
void should_OnlyCleanCompletedTasks_When_DefinedCompletedExceedThreshold() throws Exception {
WorkbasketSummary workbasket =
DefaultTestEntities.defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);
TaskBuilder taskBuilder =
TaskBuilder.newTask()
.workbasketSummary(workbasket)
.classificationSummary(classification)
.primaryObjRef(primaryObjRef)
.state(TaskState.COMPLETED)
.completed(Instant.now().minus(3, ChronoUnit.DAYS));
TaskSummary taskSummary1 = taskBuilder.buildAndStoreAsSummary(taskService);
TaskSummary taskSummary2 =
taskBuilder
.completed(Instant.now().minus(10, ChronoUnit.DAYS))
.buildAndStoreAsSummary(taskService);
TaskCleanupJob job = new TaskCleanupJob(taskanaEngine, null, null);
job.run();
List<TaskSummary> taskSummaries = taskService.createTaskQuery().list();
assertThat(taskSummaries)
.filteredOn(t -> t.getWorkbasketSummary().equals(workbasket))
.containsExactlyInAnyOrder(taskSummary1)
.doesNotContain(taskSummary2);
}
}
@Nested
@TestInstance(Lifecycle.PER_CLASS)
class CleanCompletedTasksWithBusinessProcessId implements TaskanaConfigurationModifier {
@TaskanaInject TaskanaEngine taskanaEngine;
@Override
public Builder modify(Builder builder) {
return builder
.taskCleanupJobEnabled(true)
.jobFirstRun(Instant.now().minus(10, ChronoUnit.MILLIS))
.jobRunEvery(Duration.ofMillis(1))
.taskCleanupJobMinimumAge(Duration.ofDays(5))
.taskCleanupJobAllCompletedSameParentBusiness(true);
}
@WithAccessId(user = "admin")
@Test
void should_CleanCompletedTasksWithSameParentBusiness() throws Exception {
WorkbasketSummary workbasket =
DefaultTestEntities.defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);
TaskBuilder taskBuilder =
TaskBuilder.newTask()
.workbasketSummary(workbasket)
.classificationSummary(classification)
.primaryObjRef(primaryObjRef)
.state(TaskState.COMPLETED)
.completed(Instant.now().minus(10, ChronoUnit.DAYS))
.parentBusinessProcessId("ParentProcessId_1");
taskBuilder.buildAndStoreAsSummary(taskService);
taskBuilder.buildAndStoreAsSummary(taskService);
TaskCleanupJob job = new TaskCleanupJob(taskanaEngine, null, null);
job.run();
List<TaskSummary> taskSummaries = taskService.createTaskQuery().list();
assertThat(taskSummaries)
.filteredOn(t -> t.getWorkbasketSummary().equals(workbasket))
.isEmpty();
}
@WithAccessId(user = "admin")
@Test
void should_NotCleanCompletedTasksWithSameParentBusiness_When_OneSubTaskIsIncomplete()
throws Exception {
WorkbasketSummary workbasket =
DefaultTestEntities.defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);
TaskBuilder taskBuilder =
TaskBuilder.newTask()
.workbasketSummary(workbasket)
.classificationSummary(classification)
.primaryObjRef(primaryObjRef)
.state(TaskState.COMPLETED)
.completed(Instant.now().minus(10, ChronoUnit.DAYS))
.parentBusinessProcessId("ParentProcessId_3");
TaskSummary taskSummaryCompleted1 = taskBuilder.buildAndStoreAsSummary(taskService);
TaskSummary taskSummaryCompleted2 = taskBuilder.buildAndStoreAsSummary(taskService);
TaskSummary taskSummaryCompleted =
taskBuilder
.parentBusinessProcessId("ParentProcessId_4")
.buildAndStoreAsSummary(taskService);
TaskSummary taskSummaryClaimed =
taskBuilder
.parentBusinessProcessId("ParentProcessId_4")
.state(TaskState.CLAIMED)
.completed(null)
.buildAndStoreAsSummary(taskService);
TaskCleanupJob job = new TaskCleanupJob(taskanaEngine, null, null);
job.run();
List<TaskSummary> taskSummaries = taskService.createTaskQuery().list();
assertThat(taskSummaries)
.filteredOn(t -> t.getWorkbasketSummary().equals(workbasket))
.containsExactlyInAnyOrder(taskSummaryCompleted, taskSummaryClaimed)
.doesNotContain(taskSummaryCompleted1, taskSummaryCompleted2);
}
@WithAccessId(user = "admin")
@TestFactory
Stream<DynamicTest>
should_DeleteCompletedTaskWithParentBusinessEmptyOrNull_When_RunningCleanupJob()
throws Exception {
Iterator<String> iterator = Arrays.asList("", null).iterator();
ThrowingConsumer<String> test =
parentBusinessId -> {
WorkbasketSummary workbasket =
DefaultTestEntities.defaultTestWorkbasket()
.buildAndStoreAsSummary(workbasketService);
TaskBuilder taskBuilder =
TaskBuilder.newTask()
.workbasketSummary(workbasket)
.classificationSummary(classification)
.primaryObjRef(primaryObjRef)
.state(TaskState.COMPLETED)
.completed(Instant.now().minus(10, ChronoUnit.DAYS))
.parentBusinessProcessId(parentBusinessId);
TaskSummary taskSummaryCompleted = taskBuilder.buildAndStoreAsSummary(taskService);
TaskSummary taskSummaryClaimed =
taskBuilder
.state(TaskState.CLAIMED)
.completed(null)
.buildAndStoreAsSummary(taskService);
TaskCleanupJob job = new TaskCleanupJob(taskanaEngine, null, null);
job.run();
List<TaskSummary> taskSummaries = taskService.createTaskQuery().list();
assertThat(taskSummaries)
.filteredOn(t -> t.getWorkbasketSummary().equals(workbasket))
.containsExactlyInAnyOrder(taskSummaryClaimed)
.doesNotContain(taskSummaryCompleted);
};
return DynamicTest.stream(iterator, c -> "for parentBusinessProcessId = '" + c + "'", test);
}
}
}

View File

@ -1,265 +0,0 @@
package acceptance.jobs;
import static org.assertj.core.api.Assertions.assertThat;
import acceptance.AbstractAccTest;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.function.ThrowingConsumer;
import pro.taskana.TaskanaConfiguration;
import pro.taskana.classification.internal.jobs.ClassificationChangedJob;
import pro.taskana.common.api.ScheduledJob;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
import pro.taskana.common.internal.JobMapper;
import pro.taskana.common.internal.JobServiceImpl;
import pro.taskana.common.internal.jobs.AbstractTaskanaJob;
import pro.taskana.common.internal.jobs.JobRunner;
import pro.taskana.common.test.security.JaasExtension;
import pro.taskana.common.test.security.WithAccessId;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.models.Task;
import pro.taskana.task.api.models.TaskSummary;
import pro.taskana.task.internal.jobs.TaskCleanupJob;
import pro.taskana.task.internal.jobs.TaskRefreshJob;
/** Acceptance test for all "jobs tasks runner" scenarios. */
@ExtendWith(JaasExtension.class)
class TaskCleanupJobAccTest extends AbstractAccTest {
@BeforeEach
void before() throws Exception {
// required if single tests modify database
// TODO split test class into readOnly & modifying tests to improve performance
resetDb(false);
}
@WithAccessId(user = "admin")
@Test
void should_CleanCompletedTasksUntilDate() throws Exception {
TaskanaConfiguration taskanaConfiguration =
new TaskanaConfiguration.Builder(AbstractAccTest.taskanaConfiguration)
.taskCleanupJobAllCompletedSameParentBusiness(false)
.build();
TaskanaEngine taskanaEngine =
TaskanaEngine.buildTaskanaEngine(taskanaConfiguration, ConnectionManagementMode.AUTOCOMMIT);
TaskService taskService = taskanaEngine.getTaskService();
String taskId = createAndInsertTask(taskService, null);
taskService.claim(taskId);
taskService.completeTask(taskId);
long totalTasksCount = taskService.createTaskQuery().count();
assertThat(totalTasksCount).isEqualTo(100);
TaskCleanupJob job = new TaskCleanupJob(taskanaEngine, null, null);
job.run();
totalTasksCount = taskService.createTaskQuery().count();
assertThat(totalTasksCount).isEqualTo(81);
}
@WithAccessId(user = "admin")
@Test
void shouldCleanCompletedTasksUntilDateWithSameParentBusiness() throws Exception {
long totalTasksCount = taskService.createTaskQuery().count();
assertThat(totalTasksCount).isEqualTo(99);
TaskanaConfiguration taskanaConfiguration =
new TaskanaConfiguration.Builder(AbstractAccTest.taskanaEngine.getConfiguration())
.taskCleanupJobAllCompletedSameParentBusiness(true)
.build();
TaskanaEngine taskanaEngine =
TaskanaEngine.buildTaskanaEngine(taskanaConfiguration, ConnectionManagementMode.AUTOCOMMIT);
List<TaskSummary> tasks =
taskanaEngine
.getTaskService()
.createTaskQuery()
.parentBusinessProcessIdIn("DOC_0000000000000000006")
.list();
List<String> ids = new ArrayList<>();
tasks.forEach(
item -> {
if (item.getCompleted() == null) {
ids.add(item.getId());
}
});
taskanaEngine.getTaskService().deleteTasks(ids);
TaskCleanupJob job = new TaskCleanupJob(taskanaEngine, null, null);
job.run();
totalTasksCount = taskanaEngine.getTaskService().createTaskQuery().count();
assertThat(totalTasksCount).isEqualTo(79);
}
@WithAccessId(user = "admin")
@Test
void shouldNotCleanCompleteTasksAfterDefinedDay() throws Exception {
String taskId = createAndInsertTask(taskService, null);
taskService.claim(taskId);
taskService.completeTask(taskId);
TaskCleanupJob job = new TaskCleanupJob(taskanaEngine, null, null);
job.run();
Task completedCreatedTask = taskService.getTask(taskId);
assertThat(completedCreatedTask).isNotNull();
}
@WithAccessId(user = "admin")
@Test
void should_DeleteOldTaskCleanupJobs_When_InitializingSchedule() throws Exception {
for (int i = 0; i < 10; i++) {
ScheduledJob job = new ScheduledJob();
job.setType(TaskCleanupJob.class.getName());
taskanaEngine.getJobService().createJob(job);
job.setType(TaskRefreshJob.class.getName());
taskanaEngine.getJobService().createJob(job);
job.setType(ClassificationChangedJob.class.getName());
taskanaEngine.getJobService().createJob(job);
}
List<ScheduledJob> jobsToRun = getJobMapper(taskanaEngine).findJobsToRun(Instant.now());
assertThat(jobsToRun).hasSize(30);
List<ScheduledJob> taskCleanupJobs =
jobsToRun.stream()
.filter(scheduledJob -> scheduledJob.getType().equals(TaskCleanupJob.class.getName()))
.collect(Collectors.toList());
AbstractTaskanaJob.initializeSchedule(taskanaEngine, TaskCleanupJob.class);
jobsToRun = getJobMapper(taskanaEngine).findJobsToRun(Instant.now());
assertThat(jobsToRun).doesNotContainAnyElementsOf(taskCleanupJobs);
}
@WithAccessId(user = "admin")
@TestFactory
Stream<DynamicTest>
should_DeleteCompletedTaskWithParentBusinessEmptyOrNull_When_RunningCleanupJob()
throws Exception {
Iterator<String> iterator = Arrays.asList("", null).iterator();
TaskanaConfiguration taskanaConfiguration =
new TaskanaConfiguration.Builder(AbstractAccTest.taskanaEngine.getConfiguration())
.taskCleanupJobAllCompletedSameParentBusiness(true)
.taskCleanupJobMinimumAge(Duration.ofMillis(1))
.build();
TaskanaEngine taskanaEngine =
TaskanaEngine.buildTaskanaEngine(taskanaConfiguration, ConnectionManagementMode.AUTOCOMMIT);
TaskCleanupJob job = new TaskCleanupJob(taskanaEngine, null, null);
TaskService taskService = taskanaEngine.getTaskService();
ThrowingConsumer<String> test =
parentBusinessId -> {
String taskId1 = createAndInsertTask(taskService, parentBusinessId);
taskService.claim(taskId1);
taskService.completeTask(taskId1);
String taskId2 = createAndInsertTask(taskService, parentBusinessId);
taskService.claim(taskId2);
job.run();
List<TaskSummary> tasksAfterCleaning =
taskService.createTaskQuery().idIn(taskId1, taskId2).list();
assertThat(tasksAfterCleaning).extracting(TaskSummary::getId).containsExactly(taskId2);
};
return DynamicTest.stream(iterator, c -> "for parentBusinessProcessId = '" + c + "'", test);
}
@WithAccessId(user = "admin")
@Test
void should_SetNextScheduledJobBasedOnDueDateOfPredecessor_When_RunningTaskCleanupJob()
throws Exception {
JobMapper jobMapper = getJobMapper(AbstractAccTest.taskanaEngine);
List<ScheduledJob> jobsToRun = jobMapper.findJobsToRun(Instant.now());
assertThat(jobsToRun).isEmpty();
Instant firstDue = Instant.now().truncatedTo(ChronoUnit.MILLIS);
ScheduledJob scheduledJob = new ScheduledJob();
scheduledJob.setType(TaskCleanupJob.class.getName());
scheduledJob.setDue(firstDue);
JobServiceImpl jobService = (JobServiceImpl) taskanaEngine.getJobService();
jobService.createJob(scheduledJob);
jobsToRun = jobMapper.findJobsToRun(Instant.now());
assertThat(jobsToRun).extracting(ScheduledJob::getDue).containsExactly(firstDue);
JobRunner runner = new JobRunner(taskanaEngine);
runner.runJobs();
Duration runEvery = taskanaConfiguration.getJobRunEvery();
jobsToRun = jobMapper.findJobsToRun(Instant.now().plus(runEvery));
assertThat(jobsToRun).extracting(ScheduledJob::getDue).containsExactly(firstDue.plus(runEvery));
}
@WithAccessId(user = "admin")
@Test
void should_ScheduleNextJobAccordingToFirstRun_When_PreviousJobNotExisting() throws Exception {
Instant firstRun = Instant.now().minus(2, ChronoUnit.MINUTES).truncatedTo(ChronoUnit.MILLIS);
Duration runEvery = Duration.ofMinutes(5);
TaskanaConfiguration taskanaConfiguration =
new TaskanaConfiguration.Builder(AbstractAccTest.taskanaConfiguration)
.jobRunEvery(runEvery)
.jobFirstRun(firstRun)
.jobSchedulerEnabled(true)
.jobSchedulerInitialStartDelay(1)
.jobSchedulerPeriod(1)
.jobSchedulerPeriodTimeUnit(TimeUnit.SECONDS)
.taskCleanupJobEnabled(true)
.build();
TaskanaEngine taskanaEngine =
TaskanaEngine.buildTaskanaEngine(taskanaConfiguration, ConnectionManagementMode.AUTOCOMMIT);
List<ScheduledJob> nextJobs =
getJobMapper(taskanaEngine).findJobsToRun(Instant.now().plus(runEvery));
assertThat(nextJobs).extracting(ScheduledJob::getDue).containsExactly(firstRun.plus(runEvery));
}
@WithAccessId(user = "admin")
@Test
void should_FindNoJobsToRunUntilFirstRunIsReached_When_CleanupScheduleIsInitialized()
throws Exception {
TaskanaConfiguration taskanaConfiguration =
new TaskanaConfiguration.Builder(AbstractAccTest.taskanaEngine.getConfiguration())
.jobRunEvery(Duration.ofMillis(1))
.jobFirstRun(Instant.now().plus(5, ChronoUnit.MINUTES))
.build();
TaskanaEngine taskanaEngine = TaskanaEngine.buildTaskanaEngine(taskanaConfiguration);
AbstractTaskanaJob.initializeSchedule(taskanaEngine, TaskCleanupJob.class);
List<ScheduledJob> nextJobs = getJobMapper(taskanaEngine).findJobsToRun(Instant.now());
assertThat(nextJobs).isEmpty();
}
private String createAndInsertTask(TaskService taskService, String parentBusinessProcessId)
throws Exception {
Task newTask = taskService.newTask("user-1-1", "DOMAIN_A");
newTask.setClassificationKey("T2100");
newTask.setPrimaryObjRef(
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
newTask.setParentBusinessProcessId(parentBusinessProcessId);
return taskService.createTask(newTask).getId();
}
}