1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration2.reloading;
18
19 import static org.junit.jupiter.api.Assertions.assertFalse;
20 import static org.junit.jupiter.api.Assertions.assertNotNull;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.verifyNoMoreInteractions;
28 import static org.mockito.Mockito.when;
29
30 import java.util.concurrent.ScheduledExecutorService;
31 import java.util.concurrent.ScheduledFuture;
32 import java.util.concurrent.TimeUnit;
33
34 import org.apache.commons.lang3.mutable.MutableObject;
35 import org.junit.jupiter.api.BeforeEach;
36 import org.junit.jupiter.api.Test;
37 import org.mockito.stubbing.OngoingStubbing;
38
39
40
41
42 public class TestPeriodicReloadingTrigger {
43
44
45 private static final Object CTRL_PARAM = "Test controller parameter";
46
47
48 private static final long PERIOD = 60;
49
50
51 private static final TimeUnit UNIT = TimeUnit.SECONDS;
52
53
54
55
56
57
58 @SuppressWarnings("unchecked")
59 private static ScheduledFuture<Void> createFutureMock() {
60 return mock(ScheduledFuture.class);
61 }
62
63
64 private ScheduledExecutorService executor;
65
66
67 private ReloadingController controller;
68
69
70
71
72
73
74 private PeriodicReloadingTrigger createTrigger() {
75 return new PeriodicReloadingTrigger(controller, CTRL_PARAM, PERIOD, UNIT, executor);
76 }
77
78 @BeforeEach
79 public void setUp() throws Exception {
80 executor = mock(ScheduledExecutorService.class);
81 controller = mock(ReloadingController.class);
82 }
83
84
85
86
87 @Test
88 void testDefaultExecutor() {
89 final PeriodicReloadingTrigger trigger = new PeriodicReloadingTrigger(controller, CTRL_PARAM, PERIOD, UNIT);
90 assertNotNull(trigger.getExecutorService());
91 }
92
93
94
95
96 @Test
97 void testInitNoController() {
98 assertThrows(IllegalArgumentException.class, () -> new PeriodicReloadingTrigger(null, CTRL_PARAM, PERIOD, UNIT));
99 }
100
101
102
103
104 @Test
105 void testIsRunningAfterInit() {
106 assertFalse(createTrigger().isRunning());
107 }
108
109
110
111
112 @Test
113 void testShutdown() {
114 final ScheduledFuture<Void> future = createFutureMock();
115
116 whenScheduled().thenReturn(future);
117 when(future.cancel(false)).thenReturn(Boolean.TRUE);
118
119 final PeriodicReloadingTrigger trigger = createTrigger();
120 trigger.start();
121 trigger.shutdown();
122
123 verifyScheduled();
124 verify(future).cancel(false);
125 verify(executor).shutdown();
126 verifyNoMoreInteractions(future, controller, executor);
127 }
128
129
130
131
132 @Test
133 void testShutdownNoExecutor() {
134 createTrigger().shutdown(false);
135 }
136
137
138
139
140 @Test
141 void testStart() {
142 final ScheduledFuture<Void> future = createFutureMock();
143 final MutableObject<Runnable> refTask = new MutableObject<>();
144
145 whenScheduled().thenAnswer(invocation -> {
146 refTask.setValue(invocation.getArgument(0, Runnable.class));
147 return future;
148 });
149 when(controller.checkForReloading(CTRL_PARAM)).thenReturn(Boolean.FALSE);
150
151 final PeriodicReloadingTrigger trigger = createTrigger();
152 trigger.start();
153 assertTrue(trigger.isRunning());
154 refTask.getValue().run();
155
156 verifyScheduled();
157 verify(controller).checkForReloading(CTRL_PARAM);
158 verifyNoMoreInteractions(future, controller, executor);
159 }
160
161
162
163
164 @Test
165 void testStartTwice() {
166 final ScheduledFuture<Void> future = createFutureMock();
167
168 whenScheduled().thenReturn(future);
169
170 final PeriodicReloadingTrigger trigger = createTrigger();
171 trigger.start();
172 trigger.start();
173
174 verifyScheduled();
175 verifyNoMoreInteractions(future, controller, executor);
176 }
177
178
179
180
181 @Test
182 void testStop() {
183 final ScheduledFuture<Void> future = createFutureMock();
184
185 whenScheduled().thenReturn(future);
186 when(future.cancel(false)).thenReturn(Boolean.TRUE);
187
188 final PeriodicReloadingTrigger trigger = createTrigger();
189 trigger.start();
190 trigger.stop();
191 assertFalse(trigger.isRunning());
192
193 verifyScheduled();
194 verify(future).cancel(false);
195 verifyNoMoreInteractions(future, controller, executor);
196 }
197
198
199
200
201 @Test
202 void testStopNotRunning() {
203 createTrigger().stop();
204 }
205
206
207
208
209 private void verifyScheduled() {
210 verify(executor).scheduleAtFixedRate(any(), eq(PERIOD), eq(PERIOD), eq(UNIT));
211 }
212
213
214
215
216
217
218
219 private OngoingStubbing<ScheduledFuture<?>> whenScheduled() {
220 return when(executor.scheduleAtFixedRate(any(), eq(PERIOD), eq(PERIOD), eq(UNIT)));
221 }
222 }