JobService { public void killJobsDeadSince(final int seconds) { final OffsetDateTime timeToMarkJobAsStopped = now(clock).minusSeconds(seconds); LOG.debug("JobCleanup: Looking for jobs older than {}.", timeToMarkJobAsStopped); final List<JobInfo> deadJobs = jobRepository.findRunningWithoutUpdateSince(timeToMarkJobAsStopped); deadJobs.forEach(deadJob -> killJob(deadJob.getJobId())); clearRunLocks(); } JobService();   JobService(final JobRepository jobRepository,
               final JobMetaService jobMetaService,
               final List<JobRunnable> jobRunnables,
               final ScheduledExecutorService executor,
               final ApplicationEventPublisher applicationEventPublisher,
               final Clock clock,
               final SystemInfo systemInfo,
               final UuidProvider uuidProvider); @PostConstruct void postConstruct(); Optional<String> startAsyncJob(String jobType); Optional<JobInfo> findJob(final String id); List<JobInfo> findJobs(final Optional<String> type, final int count); List<JobInfo> findJobsDistinct(); void deleteJobs(final Optional<String> type); void stopJob(final String jobId); void killJobsDeadSince(final int seconds); void killJob(final String jobId); void appendMessage(final String jobId,
                              final JobMessage jobMessage); void keepAlive(final String jobId); void markSkipped(final String jobId); void markRestarted(final String jobId); void handleTooBigJobLogs();  }
@Test public void shouldKillDeadJobsSince() { JobInfo someJobInfo = defaultJobInfo().setJobType("jobType").build(); when(jobRepository.findRunningWithoutUpdateSince(any())).thenReturn(singletonList(someJobInfo)); when(jobRepository.findOne(someJobInfo.getJobId())).thenReturn(Optional.of(someJobInfo)); jobService.killJobsDeadSince(60); verify(jobMetaService).releaseRunLock("jobType"); }