package de.otto.edison.jobs.repository;
import de.otto.edison.jobs.domain.JobInfo;
import de.otto.edison.jobs.repository.cleanup.KeepLastJobs;
import de.otto.edison.jobs.repository.inmem.InMemJobRepository;
import org.junit.Test;
import java.time.Clock;
import java.time.Instant;
import static de.otto.edison.jobs.domain.JobInfo.JobStatus.ERROR;
import static de.otto.edison.jobs.domain.JobInfo.JobStatus.OK;
import static de.otto.edison.jobs.domain.JobInfo.builder;
import static de.otto.edison.testsupport.matcher.OptionalMatchers.isAbsent;
import static de.otto.edison.testsupport.matcher.OptionalMatchers.isPresent;
import static java.time.Clock.fixed;
import static java.time.OffsetDateTime.now;
import static java.time.ZoneId.systemDefault;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
public class KeepLastJobsTest {
private final Clock now = fixed(Instant.now(), systemDefault());
private final Clock earlier = fixed(Instant.now().minusSeconds(1), systemDefault());
private final Clock muchEarlier = fixed(Instant.now().minusSeconds(10), systemDefault());
private final Clock evenEarlier = fixed(Instant.now().minusSeconds(20), systemDefault());
@Test
public void shouldRemoveOldestJobs() {
// given
JobInfo job = builder()
.setJobId("foo")
.setJobType("TYPE")
.setStarted(now(now))
.setStopped(now(now))
.setHostname("localhost")
.setStatus(OK)
.build();
JobRepository repository = new InMemJobRepository() {{
createOrUpdate(job);
createOrUpdate(job.copy().setJobId("foobar").setStarted(now(earlier)).build());
createOrUpdate(job.copy().setJobId("bar").setStarted(now(muchEarlier)).build());
}};
KeepLastJobs strategy = new KeepLastJobs(repository, 2);
// when
strategy.doCleanUp();
// then
assertThat(repository.size(), is(2L));
assertThat(repository.findOne("bar"), isAbsent());
}
@Test
public void shouldOnlyRemoveStoppedJobs() {
// given
JobInfo job = builder()
.setJobId("foo")
.setJobType("TYPE")
.setHostname("localhost")
.setStatus(OK)
.build();
JobRepository repository = new InMemJobRepository() {{
createOrUpdate(job.copy().setStarted(now(now)).setStopped(now(now)).build());
createOrUpdate(job.copy().setStarted(now(earlier)).setJobId("foobar").setStarted(now(earlier)).build());
createOrUpdate(job.copy().setStarted(now(muchEarlier)).setJobId("bar").setStopped(now(now)).build());
}};
KeepLastJobs strategy = new KeepLastJobs(repository, 1);
// when
strategy.doCleanUp();
// then
assertThat(repository.findOne("foo"), isPresent());
assertThat(repository.findOne("foobar"), isPresent());
assertThat(repository.findOne("bar"), isAbsent());
assertThat(repository.size(), is(2L));
}
@Test
public void shouldKeepAtLeastOneSuccessfulJob() {
// given
JobInfo job = builder()
.setJobId("foobar")
.setJobType("TYPE")
.setStarted(now(muchEarlier))
.setStopped(now(now))
.setHostname("localhost")
.setStatus(ERROR)
.build();
JobRepository repository = new InMemJobRepository() {{
createOrUpdate(job.copy().setStatus(OK).build());
createOrUpdate(job.copy().setStarted(now(now)).setJobId("foo").build());
createOrUpdate(job.copy().setJobId("bar").setStarted(now(earlier)).build());
createOrUpdate(job.copy().setJobId("barzig").setStarted(now(evenEarlier)).build());
createOrUpdate(job.copy().setJobId("foozification").setStarted(now(evenEarlier)).build());
}};
KeepLastJobs strategy = new KeepLastJobs(repository, 2);
// when
strategy.doCleanUp();
// then
assertThat(repository.size(), is(3L));
assertThat(repository.findOne("foo"), isPresent());
assertThat(repository.findOne("bar"), isPresent());
assertThat(repository.findOne("barzig"), isAbsent());
assertThat(repository.findOne("foobar"), isPresent());
assertThat(repository.findOne("foozification"), isAbsent());
}
@Test
public void shouldKeepNJobsOfEachTypePresentAndNotRemoveRunningJobs() {
// given
JobInfo stoppedJob = builder()
.setJobId("foo1")
.setJobType("TYPE1")
.setStarted(now(now))
.setStopped(now(now))
.setHostname("localhost")
.setStatus(OK)
.build();
JobRepository repository = new InMemJobRepository() {{
createOrUpdate(stoppedJob);
createOrUpdate(stoppedJob.copy().setJobId("foo2").setStopped(now(muchEarlier)).setStarted(now(muchEarlier)).build());
createOrUpdate(stoppedJob.copy().setJobId("foo3").setStopped(now(evenEarlier)).setStarted(now(evenEarlier)).build());
createOrUpdate(stoppedJob.copy().setJobId("bar1").setJobType("TYPE2").setStopped(now(earlier)).setStarted(now(earlier)).build());
createOrUpdate(stoppedJob.copy().setJobId("bar2").setJobType("TYPE2").setStopped(now(muchEarlier)).setStarted(now(muchEarlier)).build());
createOrUpdate(stoppedJob.copy().setJobId("bar3").setJobType("TYPE2").setStopped(now(evenEarlier)).setStarted(now(evenEarlier)).build());
}};
KeepLastJobs strategy = new KeepLastJobs(repository, 2);
// when
strategy.doCleanUp();
// then
assertThat(repository.size(), is(4L));
assertThat(repository.findByType("TYPE1"), hasSize(2));
assertThat(repository.findByType("TYPE2"), hasSize(2));
}
@Test
public void shouldBeOkToKeepAllJobs() {
// given
JobRepository repository = new InMemJobRepository() {{
createOrUpdate(builder()
.setJobId("foo1")
.setJobType("TYPE1")
.setStarted(now(now))
.setStopped(now(now))
.setHostname("localhost")
.setStatus(OK)
.build());
}};
KeepLastJobs strategy = new KeepLastJobs(repository, 2);
// when
strategy.doCleanUp();
// then
assertThat(repository.size(), is(1L));
}
}