Closes #2222 refactor TaskCleanupJobAccTest to use new TestApi
Co-authored-by: Mustapha Zorgati <15628173+mustaphazorgati@users.noreply.github.com>
This commit is contained in:
parent
ee914db0ca
commit
58a751a538
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue