1 package com.atlassian.sal.core.scheduling;
2
3 import com.atlassian.sal.api.scheduling.PluginJob;
4 import com.google.common.collect.ImmutableMap;
5 import org.junit.Before;
6 import org.junit.Test;
7 import org.junit.runner.RunWith;
8 import org.mockito.ArgumentMatcher;
9 import org.mockito.Mock;
10 import org.mockito.runners.MockitoJUnitRunner;
11 import org.quartz.*;
12
13 import java.util.Collections;
14 import java.util.Date;
15 import java.util.Map;
16 import java.util.concurrent.atomic.AtomicInteger;
17
18 import static org.junit.Assert.assertEquals;
19 import static org.mockito.Matchers.anyString;
20 import static org.mockito.Matchers.argThat;
21 import static org.mockito.Matchers.eq;
22 import static org.mockito.Matchers.isA;
23 import static org.mockito.Mockito.*;
24
25 @RunWith(MockitoJUnitRunner.class)
26 public class QuartzPluginSchedulerTest {
27
28 @Mock
29 private Scheduler scheduler;
30
31 private QuartzPluginScheduler pluginScheduler;
32
33 @Before
34 public void setUp() throws Exception {
35 pluginScheduler = new QuartzPluginScheduler() {
36 @Override
37 protected Scheduler getScheduler() {
38 return scheduler;
39 }
40 };
41 }
42
43 @Test
44 public void testSchedule() throws Exception {
45 final String jobName = "testjob";
46 final Map<String, Object> jobMap = Collections.<String, Object>singletonMap("a", "b");
47 final Date jobStartTime = new Date();
48 final int repeatInterval = 60000;
49
50 when(scheduler.scheduleJob(isA(JobDetail.class), isA(Trigger.class))).thenReturn(new Date());
51 pluginScheduler.scheduleJob(jobName, TestPluginJob.class, jobMap, jobStartTime, repeatInterval);
52 verify(scheduler).scheduleJob(argThat(new JobDetailsMatcher(jobName)),
53 argThat(new JobTriggerMatcher(jobStartTime, repeatInterval)));
54 }
55
56 @Test
57 public void testUnschedule() throws Exception {
58 when(scheduler.getJobNames(anyString())).thenReturn(new String[]{"test"});
59 when(scheduler.deleteJob(anyString(), anyString())).thenReturn(true);
60
61 pluginScheduler.unscheduleJob("test");
62 verify(scheduler).deleteJob(eq("test"), anyString());
63 }
64
65 @Test(expected = IllegalArgumentException.class)
66 public void testUnscheduleInexisting() throws Exception {
67 when(scheduler.getJobNames(anyString())).thenReturn(new String[0]);
68 pluginScheduler.unscheduleJob("test");
69 }
70
71 @Test
72 public void testPluginJob() throws Exception {
73 final JobExecutionContext context = mock(JobExecutionContext.class);
74 final JobDetail jobDetail = mock(JobDetail.class);
75 when(context.getJobDetail()).thenReturn(jobDetail);
76 when(jobDetail.getJobDataMap()).thenReturn(getJobDataMap());
77
78 new QuartzPluginScheduler.QuartzPluginJob().execute(context);
79 assertEquals(1, QuartzJob.n.intValue());
80 }
81
82 private JobDataMap getJobDataMap() {
83 return new JobDataMap(ImmutableMap.<String, Object>builder()
84 .put("pluginJobClass", QuartzJob.class)
85 .build());
86 }
87
88
89
90
91 public static class QuartzJob implements PluginJob {
92 private static AtomicInteger n = new AtomicInteger(0);
93
94 @Override
95 public void execute(Map<String, Object> jobDataMap) {
96 n.incrementAndGet();
97 }
98 }
99
100 private abstract static class TestPluginJob implements PluginJob {
101 }
102
103 private static class JobDetailsMatcher extends ArgumentMatcher<JobDetail> {
104 private final String name;
105
106 private JobDetailsMatcher(String name) {
107 this.name = name;
108 }
109
110 @Override
111 public boolean matches(Object o) {
112 JobDetail details = (JobDetail) o;
113 return name.equals(details.getName());
114 }
115 }
116
117 private static class JobTriggerMatcher extends ArgumentMatcher<Trigger> {
118 private final Date startTime;
119 private final int repeatInterval;
120
121 private JobTriggerMatcher(Date jobStartTime, int repeatInterval) {
122 startTime = jobStartTime;
123 this.repeatInterval = repeatInterval;
124 }
125
126 @Override
127 public boolean matches(Object o) {
128 SimpleTrigger trigger = (SimpleTrigger) o;
129 return startTime.equals(trigger.getStartTime()) && repeatInterval == trigger.getRepeatInterval();
130 }
131 }
132
133 }