[sim] Change StepTiming to wait for notifiers (#2603)

Old behavior is available via StepTimingAsync.

This makes it significantly easier to use simulation timing with notifiers.

Also update tests to use simulation framework.  This also speeds up the
timing-dependent tests by using simulation timing.  ResourceLock is used
in the Java tests to prevent parallel execution.

While we're here, tweak HAL Notifier implementation:
- Use wait_for instead of wait_until in WaitForNotifierAlarm
- Check for triggerTime = UINT64_MAX in UpdateNotifierAlarm
This commit is contained in:
Peter Johnson
2020-09-27 13:27:53 -07:00
committed by GitHub
parent 62731bea20
commit c3b3fb8b74
23 changed files with 278 additions and 185 deletions

View File

@@ -9,28 +9,41 @@ package edu.wpi.first.wpilibj;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.api.parallel.ResourceLock;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.simulation.SimHooks;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@DisabledOnOs(OS.MAC)
class WatchdogTest {
@BeforeEach
void setup() {
HAL.initialize(500, 0);
SimHooks.pauseTiming();
}
@AfterEach
void cleanup() {
SimHooks.resumeTiming();
}
@Test
@ResourceLock("timing")
void enableDisableTest() {
final AtomicInteger watchdogCounter = new AtomicInteger(0);
try (Watchdog watchdog = new Watchdog(0.4, () -> watchdogCounter.addAndGet(1))) {
try (Watchdog watchdog = new Watchdog(0.4, () -> {
watchdogCounter.addAndGet(1);
})) {
System.out.println("Run 1");
watchdog.enable();
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.2);
watchdog.disable();
assertEquals(0, watchdogCounter.get(), "Watchdog triggered early");
@@ -38,11 +51,7 @@ class WatchdogTest {
System.out.println("Run 2");
watchdogCounter.set(0);
watchdog.enable();
try {
Thread.sleep(600);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.6);
watchdog.disable();
assertEquals(1, watchdogCounter.get(),
@@ -51,11 +60,7 @@ class WatchdogTest {
// Run 3
watchdogCounter.set(0);
watchdog.enable();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(1);
watchdog.disable();
assertEquals(1, watchdogCounter.get(),
@@ -64,22 +69,17 @@ class WatchdogTest {
}
@Test
@ResourceLock("timing")
void resetTest() {
final AtomicInteger watchdogCounter = new AtomicInteger(0);
try (Watchdog watchdog = new Watchdog(0.4, () -> watchdogCounter.addAndGet(1))) {
try (Watchdog watchdog = new Watchdog(0.4, () -> {
watchdogCounter.addAndGet(1);
})) {
watchdog.enable();
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.2);
watchdog.reset();
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.2);
watchdog.disable();
assertEquals(0, watchdogCounter.get(), "Watchdog triggered early");
@@ -87,26 +87,21 @@ class WatchdogTest {
}
@Test
@ResourceLock("timing")
void setTimeoutTest() {
final AtomicInteger watchdogCounter = new AtomicInteger(0);
try (Watchdog watchdog = new Watchdog(1.0, () -> watchdogCounter.addAndGet(1))) {
try (Watchdog watchdog = new Watchdog(1.0, () -> {
watchdogCounter.addAndGet(1);
})) {
watchdog.enable();
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.2);
watchdog.setTimeout(0.2);
assertEquals(0.2, watchdog.getTimeout());
assertEquals(0, watchdogCounter.get(), "Watchdog triggered early");
try {
Thread.sleep(300);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.3);
watchdog.disable();
assertEquals(1, watchdogCounter.get(),
@@ -115,6 +110,7 @@ class WatchdogTest {
}
@Test
@ResourceLock("timing")
void isExpiredTest() {
try (Watchdog watchdog = new Watchdog(0.2, () -> {
})) {
@@ -122,11 +118,7 @@ class WatchdogTest {
watchdog.enable();
assertFalse(watchdog.isExpired());
try {
Thread.sleep(300);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.3);
assertTrue(watchdog.isExpired());
watchdog.disable();
@@ -138,24 +130,19 @@ class WatchdogTest {
}
@Test
@ResourceLock("timing")
void epochsTest() {
final AtomicInteger watchdogCounter = new AtomicInteger(0);
try (Watchdog watchdog = new Watchdog(0.4, () -> watchdogCounter.addAndGet(1))) {
try (Watchdog watchdog = new Watchdog(0.4, () -> {
watchdogCounter.addAndGet(1);
})) {
System.out.println("Run 1");
watchdog.enable();
watchdog.addEpoch("Epoch 1");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.1);
watchdog.addEpoch("Epoch 2");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.1);
watchdog.addEpoch("Epoch 3");
watchdog.disable();
@@ -164,17 +151,9 @@ class WatchdogTest {
System.out.println("Run 2");
watchdog.enable();
watchdog.addEpoch("Epoch 1");
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.2);
watchdog.reset();
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.2);
watchdog.addEpoch("Epoch 2");
watchdog.disable();
@@ -183,28 +162,25 @@ class WatchdogTest {
}
@Test
@ResourceLock("timing")
void multiWatchdogTest() {
final AtomicInteger watchdogCounter1 = new AtomicInteger(0);
final AtomicInteger watchdogCounter2 = new AtomicInteger(0);
try (Watchdog watchdog1 = new Watchdog(0.2, () -> watchdogCounter1.addAndGet(1));
Watchdog watchdog2 = new Watchdog(0.6, () -> watchdogCounter2.addAndGet(1))) {
try (Watchdog watchdog1 = new Watchdog(0.2, () -> {
watchdogCounter1.addAndGet(1);
});
Watchdog watchdog2 = new Watchdog(0.6, () -> {
watchdogCounter2.addAndGet(1);
})) {
watchdog2.enable();
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.25);
assertEquals(0, watchdogCounter1.get(), "Watchdog triggered early");
assertEquals(0, watchdogCounter2.get(), "Watchdog triggered early");
// Sleep enough such that only the watchdog enabled later times out first
watchdog1.enable();
try {
Thread.sleep(300);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
SimHooks.stepTiming(0.25);
watchdog1.disable();
watchdog2.disable();