Fix sporadic assertion failure in SingleThreadEventLoopTest
Motivation: SingleThreadEventLoopTest.testScheduleTaskAtFixedRate() fails often due to: - too little tolerance - incorrect assertion (it compares only with the previous timestamp) Modifications: - Increase the timestamp difference tolerance from 10ms to 20ms - Improve the timestamp assertion so that the comparison is performed against the first recorded timestamp - Misc: Fix broken Javadoc tag Result: More build stability
This commit is contained in:
parent
069c052e2c
commit
49988a6821
@ -44,7 +44,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class SingleThreadEventLoopTest {
|
public class SingleThreadEventLoopTest {
|
||||||
@ -158,10 +158,8 @@ public class SingleThreadEventLoopTest {
|
|||||||
endTime.set(System.nanoTime());
|
endTime.set(System.nanoTime());
|
||||||
}
|
}
|
||||||
}, 500, TimeUnit.MILLISECONDS).get();
|
}, 500, TimeUnit.MILLISECONDS).get();
|
||||||
|
assertThat(endTime.get() - startTime,
|
||||||
long delta = endTime.get() - startTime;
|
is(greaterThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(500))));
|
||||||
String message = String.format("delta: %d, minDelta: %d", delta, TimeUnit.MILLISECONDS.toNanos(500));
|
|
||||||
assertTrue(message, delta >= TimeUnit.MILLISECONDS.toNanos(500));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -191,8 +189,26 @@ public class SingleThreadEventLoopTest {
|
|||||||
assertTrue(f.cancel(true));
|
assertTrue(f.cancel(true));
|
||||||
assertEquals(5, timestamps.size());
|
assertEquals(5, timestamps.size());
|
||||||
|
|
||||||
// Check if the task was run without lag.
|
// Check if the task was run without a lag.
|
||||||
verifyTimestampDeltas(timestamps, 90);
|
verifyTimestampRate(timestamps, 100, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void verifyTimestampRate(Queue<Long> timestamps, long rateMillis, long toleranceMillis) {
|
||||||
|
Long firstTimestamp = null;
|
||||||
|
int cnt = 0;
|
||||||
|
for (Long t: timestamps) {
|
||||||
|
if (firstTimestamp == null) {
|
||||||
|
firstTimestamp = t;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cnt ++;
|
||||||
|
|
||||||
|
long timepoint = t - firstTimestamp;
|
||||||
|
assertThat(timepoint,
|
||||||
|
is(greaterThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(rateMillis * cnt - toleranceMillis))));
|
||||||
|
assertThat(timepoint, is(lessThan(TimeUnit.MILLISECONDS.toNanos(rateMillis * cnt + toleranceMillis))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -234,13 +250,11 @@ public class SingleThreadEventLoopTest {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
long delta = t.longValue() - previousTimestamp.longValue();
|
long diff = t.longValue() - previousTimestamp.longValue();
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
String message = String.format("delta: %d, minDelta: %d", delta, TimeUnit.MILLISECONDS.toNanos(400));
|
assertThat(diff, is(greaterThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(400))));
|
||||||
assertTrue(message, delta >= TimeUnit.MILLISECONDS.toNanos(400));
|
|
||||||
} else {
|
} else {
|
||||||
String message = String.format("delta: %d, maxDelta: %d", delta, TimeUnit.MILLISECONDS.toNanos(10));
|
assertThat(diff, is(lessThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(10))));
|
||||||
assertTrue(message, delta <= TimeUnit.MILLISECONDS.toNanos(10));
|
|
||||||
}
|
}
|
||||||
previousTimestamp = t;
|
previousTimestamp = t;
|
||||||
i ++;
|
i ++;
|
||||||
@ -274,8 +288,18 @@ public class SingleThreadEventLoopTest {
|
|||||||
assertTrue(f.cancel(true));
|
assertTrue(f.cancel(true));
|
||||||
assertEquals(3, timestamps.size());
|
assertEquals(3, timestamps.size());
|
||||||
|
|
||||||
// Check if the task was run without lag.
|
// Check if the task was run without a lag.
|
||||||
verifyTimestampDeltas(timestamps, TimeUnit.MILLISECONDS.toNanos(150));
|
Long previousTimestamp = null;
|
||||||
|
for (Long t: timestamps) {
|
||||||
|
if (previousTimestamp == null) {
|
||||||
|
previousTimestamp = t;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(t.longValue() - previousTimestamp.longValue(),
|
||||||
|
is(greaterThanOrEqualTo(TimeUnit.MILLISECONDS.toNanos(150))));
|
||||||
|
previousTimestamp = t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -407,9 +431,8 @@ public class SingleThreadEventLoopTest {
|
|||||||
loopA.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
|
loopA.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
long delta = System.nanoTime() - startTime;
|
assertThat(System.nanoTime() - startTime,
|
||||||
String message = String.format("delta: %d, minDelta: %d", delta, TimeUnit.MILLISECONDS.toNanos(1));
|
is(greaterThanOrEqualTo(TimeUnit.SECONDS.toNanos(1))));
|
||||||
assertTrue(message, delta >= TimeUnit.SECONDS.toNanos(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 5000)
|
@Test(timeout = 5000)
|
||||||
@ -601,7 +624,8 @@ public class SingleThreadEventLoopTest {
|
|||||||
assertSame(loopA, channel.eventLoop().unwrap());
|
assertSame(loopA, channel.eventLoop().unwrap());
|
||||||
|
|
||||||
ScheduledFuture<?> scheduleFuture;
|
ScheduledFuture<?> scheduleFuture;
|
||||||
if (PeriodicScheduleMethod.FIXED_RATE == method) {
|
switch (method) {
|
||||||
|
case FIXED_RATE:
|
||||||
scheduleFuture = channel.eventLoop().scheduleAtFixedRate(new Runnable() {
|
scheduleFuture = channel.eventLoop().scheduleAtFixedRate(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -609,7 +633,8 @@ public class SingleThreadEventLoopTest {
|
|||||||
timestamps.add(System.nanoTime());
|
timestamps.add(System.nanoTime());
|
||||||
}
|
}
|
||||||
}, 100, 200, TimeUnit.MILLISECONDS);
|
}, 100, 200, TimeUnit.MILLISECONDS);
|
||||||
} else {
|
break;
|
||||||
|
case FIXED_DELAY:
|
||||||
scheduleFuture = channel.eventLoop().scheduleWithFixedDelay(new Runnable() {
|
scheduleFuture = channel.eventLoop().scheduleWithFixedDelay(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -617,6 +642,9 @@ public class SingleThreadEventLoopTest {
|
|||||||
timestamps.add(System.nanoTime());
|
timestamps.add(System.nanoTime());
|
||||||
}
|
}
|
||||||
}, 100, 200, TimeUnit.MILLISECONDS);
|
}, 100, 200, TimeUnit.MILLISECONDS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(((PausableEventExecutor) channel.eventLoop()).isAcceptingNewTasks());
|
assertTrue(((PausableEventExecutor) channel.eventLoop()).isAcceptingNewTasks());
|
||||||
@ -647,7 +675,15 @@ public class SingleThreadEventLoopTest {
|
|||||||
|
|
||||||
message = String.format("size: %d, minSize: 5", timestamps.size());
|
message = String.format("size: %d, minSize: 5", timestamps.size());
|
||||||
assertTrue(message, timestamps.size() >= 5);
|
assertTrue(message, timestamps.size() >= 5);
|
||||||
verifyTimestampDeltas(timestamps, TimeUnit.MILLISECONDS.toNanos(190));
|
|
||||||
|
switch (method) {
|
||||||
|
case FIXED_DELAY:
|
||||||
|
verifyTimestampDeltas(timestamps, TimeUnit.MILLISECONDS.toNanos(190));
|
||||||
|
break;
|
||||||
|
case FIXED_RATE:
|
||||||
|
verifyTimestampRate(timestamps, 200, 40);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum PeriodicScheduleMethod {
|
private enum PeriodicScheduleMethod {
|
||||||
|
Loading…
Reference in New Issue
Block a user