[sim] Make SimDevice callbacks synchronous (#2861)

Asynchronous callbacks are more efficient but pose synchronization challenges;
other sim callbacks are synchronous but SimDevice ones were not.
This commit is contained in:
Peter Johnson
2020-11-14 21:04:51 -08:00
committed by GitHub
parent 6e76ab9c09
commit 47c59859ee
8 changed files with 286 additions and 213 deletions

View File

@@ -12,20 +12,77 @@ import org.junit.jupiter.api.Test;
import edu.wpi.first.hal.SimBoolean;
import edu.wpi.first.hal.SimDevice;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class SimDeviceSimTest {
@Test
void testBasic() {
SimDevice dev = SimDevice.create("test");
SimBoolean devBool = dev.createBoolean("bool", false, false);
try (SimDevice dev = SimDevice.create("test")) {
SimBoolean devBool = dev.createBoolean("bool", false, false);
SimDeviceSim sim = new SimDeviceSim("test");
SimBoolean simBool = sim.getBoolean("bool");
SimDeviceSim sim = new SimDeviceSim("test");
SimBoolean simBool = sim.getBoolean("bool");
assertFalse(simBool.get());
simBool.set(true);
assertTrue(devBool.get());
assertFalse(simBool.get());
simBool.set(true);
assertTrue(devBool.get());
}
}
@Test
void testDeviceCreatedCallback() {
AtomicInteger callback1Counter = new AtomicInteger(0);
AtomicInteger callback2Counter = new AtomicInteger(0);
try (SimDevice otherdev = SimDevice.create("testnotDC");
SimDevice dev1 = SimDevice.create("testDC1")) {
SimDeviceSim sim = new SimDeviceSim("testDC1");
try (
CallbackStore callback1 = sim.registerDeviceCreatedCallback("testDC", (name, handle) -> {
callback1Counter.addAndGet(1);
}, false);
CallbackStore callback2 = sim.registerDeviceCreatedCallback("testDC", (name, handle) -> {
callback2Counter.addAndGet(1);
}, true)) {
assertEquals(0, callback1Counter.get(), "Callback 1 called early");
assertEquals(1, callback2Counter.get(), "Callback 2 called early or not initalized with existing devices");
SimDevice dev2 = SimDevice.create("testDC2");
dev2.close();
assertEquals(1, callback1Counter.get(), "Callback 1 called either more than once or not at all");
assertEquals(2, callback2Counter.get(), "Callback 2 called either more or less than twice");
}
SimDevice dev3 = SimDevice.create("testDC3");
dev3.close();
assertEquals(1, callback1Counter.get(), "Callback 1 called after closure");
assertEquals(2, callback2Counter.get(), "Callback 2 called after closure");
}
}
@Test
void testDeviceFreedCallback() {
AtomicInteger counter = new AtomicInteger(0);
SimDevice dev1 = SimDevice.create("testDF1");
SimDeviceSim sim = new SimDeviceSim("testDF1");
try (CallbackStore callback = sim.registerDeviceFreedCallback("testDF", (name, handle) -> {
counter.addAndGet(1);
}, false)) {
assertEquals(0, counter.get(), "Callback called early");
dev1.close();
assertEquals(1, counter.get(), "Callback called either more than once or not at all");
}
SimDevice dev2 = SimDevice.create("testDF2");
dev2.close();
assertEquals(1, counter.get(), "Callback called after closure");
}
}