// Copyright (c) FIRST and other WPILib contributors. // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. package org.wpilib.simulation; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.concurrent.atomic.AtomicInteger; import org.junit.jupiter.api.Test; import org.wpilib.hardware.hal.SimBoolean; import org.wpilib.hardware.hal.SimDevice; import org.wpilib.hardware.hal.SimDevice.Direction; import org.wpilib.hardware.hal.SimValue; class SimDeviceSimTest { @Test void testBasic() { try (SimDevice dev = SimDevice.create("test")) { SimBoolean devBool = dev.createBoolean("bool", Direction.kBidir, false); SimDeviceSim sim = new SimDeviceSim("test"); SimBoolean simBool = sim.getBoolean("bool"); assertFalse(simBool.get()); simBool.set(true); assertTrue(devBool.get()); assertEquals(dev.getName(), "test"); } } @Test void testDeviceCreatedCallback() { AtomicInteger callback1Counter = new AtomicInteger(0); AtomicInteger callback2Counter = new AtomicInteger(0); try (SimDevice otherdev = SimDevice.create("testnotDC"); SimDevice dev1 = SimDevice.create("testDC1")) { try (CallbackStore callback1 = SimDeviceSim.registerDeviceCreatedCallback( "testDC", (name, handle) -> callback1Counter.addAndGet(1), false); CallbackStore callback2 = SimDeviceSim.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 initialized 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"); try (CallbackStore callback = SimDeviceSim.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"); } @Test void testValueCreatedCallback() { AtomicInteger callback1Counter = new AtomicInteger(0); AtomicInteger callback2Counter = new AtomicInteger(0); try (SimDevice dev1 = SimDevice.create("testVM1")) { dev1.createBoolean("v1", Direction.kBidir, false); SimDeviceSim sim = new SimDeviceSim("testVM1"); try (CallbackStore callback1 = sim.registerValueCreatedCallback( (name, handle, readonly, value) -> callback1Counter.addAndGet(1), false); CallbackStore callback2 = sim.registerValueCreatedCallback( (name, handle, readonly, value) -> callback2Counter.addAndGet(1), true)) { assertEquals(0, callback1Counter.get(), "Callback 1 called early"); assertEquals( 1, callback2Counter.get(), "Callback 2 called early or not initialized with existing devices"); dev1.createDouble("v2", Direction.kBidir, 0); 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"); } dev1.createBoolean("v3", Direction.kBidir, false); assertEquals(1, callback1Counter.get(), "Callback 1 called after closure"); assertEquals(2, callback2Counter.get(), "Callback 2 called after closure"); } } @Test void testValueChangedCallback() { AtomicInteger callback1Counter = new AtomicInteger(0); AtomicInteger callback2Counter = new AtomicInteger(0); try (SimDevice dev1 = SimDevice.create("testVM1")) { SimBoolean val = dev1.createBoolean("v1", Direction.kBidir, false); SimDeviceSim sim = new SimDeviceSim("testVM1"); SimValue simVal = sim.getValue("v1"); try (CallbackStore callback1 = sim.registerValueChangedCallback( simVal, (name, handle, readonly, value) -> callback1Counter.addAndGet(1), false); CallbackStore callback2 = sim.registerValueChangedCallback( simVal, (name, handle, readonly, value) -> callback2Counter.addAndGet(1), true)) { assertEquals(0, callback1Counter.get(), "Callback 1 called early"); assertEquals( 1, callback2Counter.get(), "Callback 2 called early or not initialized with existing devices"); val.set(true); 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"); } val.set(false); assertEquals(1, callback1Counter.get(), "Callback 1 called after closure"); assertEquals(2, callback2Counter.get(), "Callback 2 called after closure"); } } }