Skip to content

Commit eec8ee9

Browse files
authored
Merge pull request #173 from carterkozak/ckozak/gh172
fix #172: DeterministicScheduler supports customizable tick precision
2 parents 1200ba2 + 5a95f8a commit eec8ee9

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

jmock/src/main/java/org/jmock/lib/concurrent/DeterministicScheduler.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.Collection;
44
import java.util.List;
5+
import java.util.Objects;
56
import java.util.concurrent.Callable;
67
import java.util.concurrent.Delayed;
78
import java.util.concurrent.ExecutionException;
@@ -27,7 +28,22 @@
2728
*/
2829
public class DeterministicScheduler implements ScheduledExecutorService {
2930
private final DeltaQueue<ScheduledTask<?>> deltaQueue = new DeltaQueue<ScheduledTask<?>>();
31+
private final TimeUnit tickTimeUnit;
3032
private long passedTicks = 0;
33+
34+
public DeterministicScheduler() {
35+
this(TimeUnit.MILLISECONDS);
36+
}
37+
38+
/**
39+
* A {@link TimeUnit} may be provided for custom tick precision. This can be helpful when operating
40+
* with nanosecond or microsecond precision.
41+
*
42+
* @param tickTimeUnit Time unit to use for ticks.
43+
*/
44+
public DeterministicScheduler(TimeUnit tickTimeUnit) {
45+
this.tickTimeUnit = Objects.requireNonNull(tickTimeUnit, "TimeUnit is required");
46+
}
3147

3248
/**
3349
* Runs time forwards by a given duration, executing any commands scheduled for
@@ -219,7 +235,7 @@ public long getDelay(TimeUnit unit) {
219235
if (delay == null) {
220236
delay = ranAtTicks - passedTicks;
221237
}
222-
return unit.convert(delay, TimeUnit.MILLISECONDS);
238+
return unit.convert(delay, tickTimeUnit);
223239
}
224240

225241
public int compareTo(Delayed o) {
@@ -269,7 +285,7 @@ public void run() {
269285
}
270286

271287
private long toTicks(long duration, TimeUnit timeUnit) {
272-
return TimeUnit.MILLISECONDS.convert(duration, timeUnit);
288+
return tickTimeUnit.convert(duration, timeUnit);
273289
}
274290

275291
private UnsupportedSynchronousOperationException blockingOperationsNotSupported() {

jmock/src/test/java/org/jmock/test/unit/lib/concurrent/DeterministicSchedulerTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,19 @@ public void testGetDelayWithManyScheduledTasks() throws Exception {
135135
assertEquals(10, task3.getDelay(TimeUnit.SECONDS));
136136
}
137137

138+
public void testGetDelayWithManyScheduledTasksWithMicrosecondPrecision() throws Exception {
139+
DeterministicScheduler microsecondScheduler = new DeterministicScheduler(TimeUnit.MICROSECONDS);
140+
ScheduledFuture<?> task1 = microsecondScheduler.schedule(commandA, 10, TimeUnit.MICROSECONDS);
141+
ScheduledFuture<?> task2 = microsecondScheduler.schedule(commandA, 20, TimeUnit.MICROSECONDS);
142+
ScheduledFuture<?> task3 = microsecondScheduler.schedule(commandA, 15, TimeUnit.MICROSECONDS);
143+
144+
microsecondScheduler.tick(5, TimeUnit.MICROSECONDS);
145+
146+
assertEquals(5, task1.getDelay(TimeUnit.MICROSECONDS));
147+
assertEquals(15, task2.getDelay(TimeUnit.MICROSECONDS));
148+
assertEquals(10, task3.getDelay(TimeUnit.MICROSECONDS));
149+
}
150+
138151
public void testGetDelayOnPassedTasks() throws Exception {
139152
final Throwable thrown = new IllegalStateException();
140153

0 commit comments

Comments
 (0)