1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.time;
18
19 import static org.hamcrest.MatcherAssert.assertThat;
20 import static org.hamcrest.Matchers.allOf;
21 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
22 import static org.hamcrest.Matchers.lessThan;
23 import static org.hamcrest.Matchers.lessThanOrEqualTo;
24 import static org.hamcrest.Matchers.not;
25 import static org.hamcrest.Matchers.startsWith;
26 import static org.junit.jupiter.api.Assertions.assertEquals;
27 import static org.junit.jupiter.api.Assertions.assertFalse;
28 import static org.junit.jupiter.api.Assertions.assertNotEquals;
29 import static org.junit.jupiter.api.Assertions.assertNull;
30 import static org.junit.jupiter.api.Assertions.assertThrows;
31 import static org.junit.jupiter.api.Assertions.assertTrue;
32
33 import java.time.Duration;
34 import java.util.concurrent.TimeUnit;
35
36 import org.apache.commons.lang3.AbstractLangTest;
37 import org.apache.commons.lang3.ThreadUtils;
38 import org.apache.commons.lang3.reflect.FieldUtils;
39 import org.junit.jupiter.api.Test;
40
41
42
43
44 public class StopWatchTest extends AbstractLangTest {
45
46 private static final Duration MILLIS_200 = Duration.ofMillis(200);
47 private static final Duration MILLIS_550 = Duration.ofMillis(550);
48 private static final String MESSAGE = "Baking cookies";
49 private static final Duration MIN_SLEEP = Duration.ofMillis(20);
50 private static final String ZERO_HOURS_PREFIX = "00:";
51 private static final String ZERO_TIME_ELAPSED = "00:00:00.000";
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 private StopWatch createMockStopWatch(final long nanos) {
73 final StopWatch watch = StopWatch.createStarted();
74 watch.suspend();
75 try {
76 final long currentNanos = System.nanoTime();
77 FieldUtils.writeField(watch, "startTimeNanos", currentNanos - nanos, true);
78 FieldUtils.writeField(watch, "stopTimeNanos", currentNanos, true);
79 } catch (final IllegalAccessException e) {
80 return null;
81 }
82 return watch;
83 }
84
85 private void sleep(final Duration duration) throws InterruptedException {
86 ThreadUtils.sleep(duration);
87 }
88
89
90 @Test
91 public void testBadStates() {
92 final StopWatch watch = new StopWatch();
93 assertThrows(IllegalStateException.class, watch::stop,
94 "Calling stop on an unstarted StopWatch should throw an exception. ");
95
96 assertThrows(IllegalStateException.class, watch::suspend,
97 "Calling suspend on an unstarted StopWatch should throw an exception. ");
98
99 assertThrows(IllegalStateException.class, watch::split,
100 "Calling split on a non-running StopWatch should throw an exception. ");
101
102 assertThrows(IllegalStateException.class, watch::unsplit,
103 "Calling unsplit on an unsplit StopWatch should throw an exception. ");
104
105 assertThrows(IllegalStateException.class, watch::resume,
106 "Calling resume on an unsuspended StopWatch should throw an exception. ");
107
108 watch.start();
109
110 assertThrows(IllegalStateException.class, watch::start,
111 "Calling start on a started StopWatch should throw an exception. ");
112
113 assertThrows(IllegalStateException.class, watch::unsplit,
114 "Calling unsplit on an unsplit StopWatch should throw an exception. ");
115
116 assertThrows(IllegalStateException.class, watch::getSplitTime,
117 "Calling getSplitTime on an unsplit StopWatch should throw an exception. ");
118
119 assertThrows(IllegalStateException.class, watch::resume,
120 "Calling resume on an unsuspended StopWatch should throw an exception. ");
121
122 watch.stop();
123
124 assertThrows(IllegalStateException.class, watch::start,
125 "Calling start on a stopped StopWatch should throw an exception as it needs to be reset. ");
126 }
127
128 @Test
129 public void testBooleanStates() {
130 final StopWatch watch = new StopWatch();
131 assertFalse(watch.isStarted());
132 assertFalse(watch.isSuspended());
133 assertTrue(watch.isStopped());
134
135 watch.start();
136 assertTrue(watch.isStarted());
137 assertFalse(watch.isSuspended());
138 assertFalse(watch.isStopped());
139
140 watch.suspend();
141 assertTrue(watch.isStarted());
142 assertTrue(watch.isSuspended());
143 assertFalse(watch.isStopped());
144
145 watch.stop();
146 assertFalse(watch.isStarted());
147 assertFalse(watch.isSuspended());
148 assertTrue(watch.isStopped());
149 }
150
151 @Test
152 public void testFormatSplitTime() {
153 final StopWatch watch = StopWatch.createStarted();
154 ThreadUtils.sleepQuietly(MIN_SLEEP);
155 watch.split();
156 final String formatSplitTime = watch.formatSplitTime();
157 assertNotEquals(ZERO_TIME_ELAPSED, formatSplitTime);
158 assertThat("formatSplitTime", formatSplitTime, startsWith(ZERO_HOURS_PREFIX));
159 }
160
161 @Test
162 public void testFormatSplitTimeWithMessage() {
163 final StopWatch watch = new StopWatch(MESSAGE);
164 watch.start();
165 ThreadUtils.sleepQuietly(MIN_SLEEP);
166 watch.split();
167 final String formatSplitTime = watch.formatSplitTime();
168 assertThat("formatSplitTime", formatSplitTime, not(startsWith(MESSAGE)));
169 assertThat("formatSplitTime", formatSplitTime, startsWith(ZERO_HOURS_PREFIX));
170 }
171
172 @Test
173 public void testFormatTime() {
174 final StopWatch watch = StopWatch.create();
175 final String formatTime = watch.formatTime();
176 assertEquals(ZERO_TIME_ELAPSED, formatTime);
177 assertThat("formatTime", formatTime, startsWith(ZERO_HOURS_PREFIX));
178 }
179
180 @Test
181 public void testFormatTimeWithMessage() {
182 final StopWatch watch = new StopWatch(MESSAGE);
183 final String formatTime = watch.formatTime();
184 assertThat("formatTime", formatTime, not(startsWith(MESSAGE)));
185 }
186
187 @Test
188 public void testGetStartTime() {
189 final long beforeStopWatchMillis = System.currentTimeMillis();
190 final StopWatch watch = new StopWatch();
191 assertThrows(IllegalStateException.class, watch::getStartTime,
192 "Calling getStartTime on an unstarted StopWatch should throw an exception");
193 watch.start();
194
195 watch.getStartTime();
196 assertThat("getStartTime", watch.getStartTime(), greaterThanOrEqualTo(beforeStopWatchMillis));
197
198 watch.reset();
199 assertThrows(IllegalStateException.class, watch::getStartTime,
200 "Calling getStartTime on a reset, but unstarted StopWatch should throw an exception");
201 }
202
203 @Test
204 public void testLang315() throws InterruptedException {
205 final StopWatch watch = StopWatch.createStarted();
206 sleep(MILLIS_200);
207 watch.suspend();
208 final long suspendTime = watch.getTime();
209 sleep(MILLIS_200);
210 watch.stop();
211 final long totalTime = watch.getTime();
212 assertEquals(suspendTime, totalTime);
213 }
214
215 @Test
216 public void testMessage() {
217 assertNull(StopWatch.create().getMessage());
218 final StopWatch stopWatch = new StopWatch(MESSAGE);
219 assertEquals(MESSAGE, stopWatch.getMessage());
220 assertThat("stopWatch.toString", stopWatch.toString(), startsWith(MESSAGE));
221 stopWatch.start();
222 stopWatch.split();
223 assertThat("stopWatch.toSplitString", stopWatch.toSplitString(), startsWith(MESSAGE));
224 }
225
226 @Test
227 public void testStopTimeSimple() throws InterruptedException {
228 final StopWatch watch = StopWatch.createStarted();
229 final long testStartMillis = System.currentTimeMillis();
230 sleep(MILLIS_550);
231 watch.stop();
232 final long testEndMillis = System.currentTimeMillis();
233 final long stopTime = watch.getStopTime();
234 assertEquals(stopTime, watch.getStopTime());
235
236 assertThat("stopTime", stopTime, allOf(greaterThanOrEqualTo(testStartMillis), lessThanOrEqualTo(testEndMillis)));
237 }
238
239 @Test
240 public void testStopWatchGetWithTimeUnit() {
241
242
243 final StopWatch watch = createMockStopWatch(
244 TimeUnit.HOURS.toNanos(2)
245 + TimeUnit.MINUTES.toNanos(59)
246 + TimeUnit.SECONDS.toNanos(1)
247 + TimeUnit.MILLISECONDS.toNanos(999));
248
249
250 assertEquals(2L, watch.getTime(TimeUnit.HOURS));
251 assertEquals(179L, watch.getTime(TimeUnit.MINUTES));
252 assertEquals(10741L, watch.getTime(TimeUnit.SECONDS));
253 assertEquals(10741999L, watch.getTime(TimeUnit.MILLISECONDS));
254 }
255
256 @Test
257 public void testStopWatchSimple() throws InterruptedException {
258 final StopWatch watch = StopWatch.createStarted();
259 sleep(MILLIS_550);
260 watch.stop();
261 final long time = watch.getTime();
262 assertEquals(time, watch.getTime());
263
264 assertThat("time", time, allOf(greaterThanOrEqualTo(500L), lessThan(700L)));
265
266 watch.reset();
267 assertEquals(0, watch.getTime());
268 }
269
270 @Test
271 public void testStopWatchSimpleGet() throws InterruptedException {
272 final StopWatch watch = new StopWatch();
273 assertEquals(0, watch.getTime());
274 assertEquals(ZERO_TIME_ELAPSED, watch.toString());
275
276 watch.start();
277 sleep(MILLIS_550);
278 assertThat("watch.getTime()", watch.getTime(), lessThan(2000L));
279 }
280
281 @Test
282 public void testStopWatchSplit() throws InterruptedException {
283 final StopWatch watch = StopWatch.createStarted();
284 sleep(MILLIS_550);
285 watch.split();
286 final long splitTime = watch.getSplitTime();
287 final String splitStr = watch.toSplitString();
288 sleep(MILLIS_550);
289 watch.unsplit();
290 sleep(MILLIS_550);
291 watch.stop();
292 final long totalTime = watch.getTime();
293
294 assertEquals(12, splitStr.length(), "Formatted split string not the correct length");
295 assertThat("splitTime", splitTime, allOf(greaterThanOrEqualTo(500L), lessThan(700L)));
296 assertThat("totalTime", totalTime, allOf(greaterThanOrEqualTo(1500L), lessThan(2000L)));
297 }
298
299 @Test
300 public void testStopWatchStatic() {
301 final StopWatch watch = StopWatch.createStarted();
302 assertTrue(watch.isStarted());
303 }
304
305 @Test
306 public void testStopWatchSuspend() throws InterruptedException {
307
308 final StopWatch watch = StopWatch.createStarted();
309 final long testStartMillis = System.currentTimeMillis();
310 final long testStartNanos = System.nanoTime();
311 sleep(MILLIS_550);
312 watch.suspend();
313 final long testSuspendMillis = System.currentTimeMillis();
314 final long testSuspendNanos = System.nanoTime();
315 final long testSuspendTimeNanos = testSuspendNanos - testStartNanos;
316 final long suspendTimeFromNanos = watch.getTime();
317 final long stopTimeMillis = watch.getStopTime();
318
319 assertThat("testStartMillis <= stopTimeMillis", testStartMillis, lessThanOrEqualTo(stopTimeMillis));
320 assertThat("testSuspendMillis <= stopTimeMillis", testSuspendMillis, lessThanOrEqualTo(stopTimeMillis));
321
322 sleep(MILLIS_550);
323 watch.resume();
324 sleep(MILLIS_550);
325 watch.stop();
326 final long totalTimeFromNanos = watch.getTime();
327
328 assertThat("suspendTimeFromNanos", suspendTimeFromNanos, greaterThanOrEqualTo(500L));
329 assertThat("suspendTimeFromNanos <= testSuspendTimeNanos", suspendTimeFromNanos, lessThanOrEqualTo(testSuspendTimeNanos));
330 assertThat("totalTimeFromNanos", totalTimeFromNanos, greaterThanOrEqualTo(1000L));
331
332 assertThat("totalTimeFromNanos", totalTimeFromNanos, lessThan(2500L));
333 }
334
335 @Test
336 public void testToSplitString() throws InterruptedException {
337 final StopWatch watch = StopWatch.createStarted();
338 sleep(MILLIS_550);
339 watch.split();
340 final String splitStr = watch.toSplitString();
341 assertEquals(12, splitStr.length(), "Formatted split string not the correct length");
342 }
343
344 @Test
345 public void testToSplitStringWithMessage() throws InterruptedException {
346 final StopWatch watch = new StopWatch(MESSAGE);
347 watch.start();
348 sleep(MILLIS_550);
349 watch.split();
350 final String splitStr = watch.toSplitString();
351 assertEquals(12 + MESSAGE.length() + 1, splitStr.length(), "Formatted split string not the correct length");
352 }
353
354 @Test
355 public void testToString() throws InterruptedException {
356
357 final StopWatch watch = StopWatch.createStarted();
358 sleep(MILLIS_550);
359 watch.split();
360 final String splitStr = watch.toString();
361 assertEquals(12, splitStr.length(), "Formatted split string not the correct length");
362 }
363
364 @Test
365 public void testToStringWithMessage() throws InterruptedException {
366 assertThat("message", new StopWatch(MESSAGE).toString(), startsWith(MESSAGE));
367
368 final StopWatch watch = new StopWatch(MESSAGE);
369 watch.start();
370 sleep(MILLIS_550);
371 watch.split();
372 final String splitStr = watch.toString();
373 assertEquals(12 + MESSAGE.length() + 1, splitStr.length(), "Formatted split string not the correct length");
374 }
375 }