Files
JIMRI/java/test/jmri/InstanceManagerTest.java
T
2026-06-17 14:00:51 +02:00

443 lines
18 KiB
Java

package jmri;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jmri.jmrit.display.layoutEditor.LayoutBlockManager;
import jmri.jmrit.logix.OBlockManager;
import jmri.jmrit.logix.WarrantManager;
import jmri.jmrit.roster.RosterIconFactory;
import jmri.managers.TurnoutManagerScaffold;
import jmri.progdebugger.DebugProgrammerManager;
import jmri.util.JUnitAppender;
import jmri.util.JUnitUtil;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test InstanceManager
*
* @author Bob Jacobsen
*/
public class InstanceManagerTest {
@Test
public void testDefaultPowerManager() {
PowerManager m = new PowerManagerScaffold();
InstanceManager.store(m, jmri.PowerManager.class);
assertTrue( InstanceManager.getDefault(jmri.PowerManager.class) == m, "power manager present");
}
@Test
public void testSecondDefaultPowerManager() {
PowerManager m1 = new PowerManagerScaffold();
PowerManager m2 = new PowerManagerScaffold();
InstanceManager.store(m1, jmri.PowerManager.class);
InstanceManager.store(m2, jmri.PowerManager.class);
assertTrue( InstanceManager.getDefault(jmri.PowerManager.class) == m2, "power manager present");
}
@Test
public void testDefaultProgrammerManagers() {
DebugProgrammerManager m = new DebugProgrammerManager();
InstanceManager.store(m, AddressedProgrammerManager.class);
InstanceManager.store(m, GlobalProgrammerManager.class);
assertTrue( InstanceManager.getDefault(GlobalProgrammerManager.class) == m, "global programmer manager was set");
assertTrue( InstanceManager.getDefault(AddressedProgrammerManager.class) == m, "addressed programmer manager was set");
}
@Test
public void testSecondDefaultProgrammerManager() {
DebugProgrammerManager m1 = new DebugProgrammerManager();
DebugProgrammerManager m2 = new DebugProgrammerManager();
InstanceManager.store(m1, AddressedProgrammerManager.class);
InstanceManager.store(m1, GlobalProgrammerManager.class);
InstanceManager.store(m2, AddressedProgrammerManager.class);
InstanceManager.store(m2, GlobalProgrammerManager.class);
assertTrue( InstanceManager.getDefault(GlobalProgrammerManager.class) == m2, "2nd global programmer manager is default");
assertTrue( InstanceManager.getDefault(AddressedProgrammerManager.class) == m2, "2nd addressed programmer manager is default");
}
@Test
public void testIsInitialized() {
// counts on the following test class to be loaded
assertFalse(InstanceManager.isInitialized(jmri.InstanceManagerTest.InstanceManagerInitCheck.class));
assertFalse(InstanceManager.isInitialized(jmri.InstanceManagerTest.InstanceManagerInitCheck.class));
assertNotNull(InstanceManager.getDefault(jmri.InstanceManagerTest.InstanceManagerInitCheck.class));
assertTrue(InstanceManager.isInitialized(jmri.InstanceManagerTest.InstanceManagerInitCheck.class));
}
public static class InstanceManagerInitCheck implements jmri.InstanceManagerAutoDefault {
public InstanceManagerInitCheck() {}
}
// the following test was moved from jmri.jmrit.symbolicprog.PackageTet when
// it was converted to JUnit4 format. It seemed out of place there.
// check configuring the programmer
@Test
public void testConfigProgrammer() {
// initialize the system
Programmer p = new jmri.progdebugger.ProgDebugger();
InstanceManager.store(new jmri.managers.DefaultProgrammerManager(p), GlobalProgrammerManager.class);
assertEquals(p.getConfigurator(),InstanceManager.getDefault(GlobalProgrammerManager.class).getGlobalProgrammer().getConfigurator());
}
// Testing new load store
@Test
public void testGenericStoreAndGet() {
PowerManager m1 = new PowerManagerScaffold();
PowerManager m2;
InstanceManager.store(m1, PowerManager.class);
m2 = InstanceManager.getDefault(PowerManager.class);
assertEquals( m1, m2, "retrieved same object");
}
@Test
public void testGenericStoreList() {
PowerManager m1 = new PowerManagerScaffold();
PowerManager m2 = new PowerManagerScaffold();
InstanceManager.store(m1, PowerManager.class);
InstanceManager.store(m2, PowerManager.class);
assertEquals( 2, InstanceManager.getList(PowerManager.class).size(),
"list length");
assertEquals( m1, InstanceManager.getList(PowerManager.class).get(0),
"retrieved 1st PowerManager");
assertEquals( m2, InstanceManager.getList(PowerManager.class).get(1),
"retrieved 2nd PowerManager");
assertTrue( InstanceManager.getList(PowerManager.class).equals(
InstanceManager.getList("jmri.PowerManager")),
"access by string");
}
@Test
public void testGenericStoreAndGetTwoDifferentTypes() {
PowerManager m1 = new PowerManagerScaffold();
PowerManager m2;
TurnoutManager t1 = new TurnoutManagerScaffold();
TurnoutManager t2;
InstanceManager.store(m1, PowerManager.class);
InstanceManager.store(t1, TurnoutManager.class);
m2 = InstanceManager.getDefault(PowerManager.class);
t2 = InstanceManager.getDefault(TurnoutManager.class);
assertEquals( m1, m2, "retrieved same PowerManager");
assertEquals( t1, t2, "retrieved same TurnoutManager");
assertEquals(
InstanceManager.getDefault(PowerManager.class),
InstanceManager.getDefault("jmri.PowerManager"),
"access by string"
);
}
@Test
public void testListTwoDifferentTypes() {
PowerManager m1 = new PowerManagerScaffold();
TurnoutManager t1 = new TurnoutManagerScaffold();
InstanceManager.store(m1, PowerManager.class);
InstanceManager.store(t1, TurnoutManager.class);
var set = InstanceManager.getInstanceClasses();
assertTrue( set.contains(PowerManager.class), "PowerManager");
assertTrue( set.contains(TurnoutManager.class), "TurnoutManager");
}
@Test
public void testGetInstance() throws ClassNotFoundException {
// for sync usage, check a predicate - Class.forName returns same object always
assertTrue( Class.forName("jmri.PowerManager") == Class.forName("jmri.PowerManager"),
"access by string");
// the rest of the checks are done via calls to getInstance
// embedded in various other tests
}
@Test
public void testGenericStoreAndReset() {
PowerManager m1 = new PowerManagerScaffold();
PowerManager m2;
InstanceManager.store(m1, PowerManager.class);
InstanceManager.reset(PowerManager.class);
m1 = new PowerManagerScaffold();
InstanceManager.store(m1, PowerManager.class);
m2 = InstanceManager.getDefault(PowerManager.class);
assertEquals( m1, m2, "retrieved second PowerManager");
}
public static class OkAutoCreate implements InstanceManagerAutoDefault {
public OkAutoCreate() {
}
}
@Test
public void testAutoCreateOK() {
OkAutoCreate obj1 = InstanceManager.getDefault(OkAutoCreate.class);
assertNotNull( obj1, "Created object 1");
OkAutoCreate obj2 = InstanceManager.getDefault(OkAutoCreate.class);
assertNotNull( obj2, "Created object 2");
assertTrue( obj1 == obj2, "same object");
}
public static class NoAutoCreate {
}
@Test
public void testAutoCreateNotOK() {
Exception ex = assertThrows(NullPointerException.class, () ->
InstanceManager.getDefault(NoAutoCreate.class) );
assertEquals("Required nonnull default for jmri.InstanceManagerTest$NoAutoCreate does not exist.",
ex.getMessage());
}
static volatile boolean avoidLoopAutoCreateCycle = true;
static synchronized void setavoidLoopAutoCreateCycle( boolean newVal) {
avoidLoopAutoCreateCycle = newVal;
}
public static class AutoCreateCycle implements InstanceManagerAutoDefault {
public AutoCreateCycle() {
if (InstanceManagerTest.avoidLoopAutoCreateCycle) {
InstanceManagerTest.setavoidLoopAutoCreateCycle(false);
InstanceManager.getDefault(AutoCreateCycle.class);
}
}
}
@Test
public void testAutoCreateCycle() {
InstanceManagerTest.setavoidLoopAutoCreateCycle(true);
InstanceManager.getDefault(AutoCreateCycle.class);
JUnitAppender.assertErrorMessage("Proceeding to initialize class jmri.InstanceManagerTest$AutoCreateCycle while already in initialization");
JUnitAppender.assertErrorMessage(" Prior initialization:");
}
public static class OkToDispose implements Disposable {
public static final String MESSAGE = "dispose called";
private static int times = 0;
private static void startUp() {
times = 0;
}
private static void increaseDisposedCount() {
OkToDispose.times++;
}
@Override
@SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT") // using constant to confirm message
public void dispose() {
increaseDisposedCount();
log.warn("{} {}", MESSAGE, times);
}
}
@Test
public void testDisposable() {
OkToDispose d1 = new OkToDispose();
// register d1 in single list
InstanceManager.store(d1, OkToDispose.class);
InstanceManager.deregister(d1, OkToDispose.class);
// dispose should have been called since registered in only one list
JUnitAppender.assertWarnMessage(OkToDispose.MESSAGE + 1);
// register d1 in two lists
InstanceManager.store(d1, OkToDispose.class);
InstanceManager.store(d1, Disposable.class);
InstanceManager.deregister(d1, OkToDispose.class);
// dispose should not have been called because removed from only one list
InstanceManager.deregister(d1, Disposable.class);
// dispose should be called again as removed from all lists
JUnitAppender.assertWarnMessage(OkToDispose.MESSAGE + 2);
}
@Test
public void testDisposeInClear() {
OkToDispose d1 = new OkToDispose();
// register d1 in single list
InstanceManager.store(d1, OkToDispose.class);
InstanceManager.getDefault().clear(OkToDispose.class);
// dispose should have been called since registered in only one list
JUnitAppender.assertWarnMessage(OkToDispose.MESSAGE + 1);
// register d1 in two lists
InstanceManager.store(d1, OkToDispose.class);
InstanceManager.store(d1, Disposable.class);
InstanceManager.getDefault().clear(OkToDispose.class);
// dispose should not have been called because removed from only one list
InstanceManager.getDefault().clear(Disposable.class);
// dispose should be called again as removed from all lists
JUnitAppender.assertWarnMessage(OkToDispose.MESSAGE + 2);
}
/**
* Test of types that have defaults, even with no system attached.
*/
@Test
public void testAllDefaults() {
assertNotNull(InstanceManager.getDefault(SensorManager.class));
assertNotNull(InstanceManager.getDefault(TurnoutManager.class));
assertNotNull(InstanceManager.getDefault(LightManager.class));
assertNotNull(InstanceManager.getDefault(jmri.SignalHeadManager.class));
assertNotNull(InstanceManager.getDefault(jmri.SignalMastManager.class));
assertNotNull(InstanceManager.getDefault(jmri.SignalSystemManager.class));
assertNotNull(InstanceManager.getDefault(jmri.SignalGroupManager.class));
assertNotNull(InstanceManager.getDefault(jmri.BlockManager.class));
assertNotNull(InstanceManager.getDefault(jmri.jmrit.logix.OBlockManager.class));
assertNotNull(InstanceManager.getDefault(WarrantManager.class));
assertNotNull(InstanceManager.getDefault(jmri.SectionManager.class));
assertNotNull(InstanceManager.getDefault(jmri.TransitManager.class));
assertNotNull(InstanceManager.getDefault(jmri.RouteManager.class));
assertNotNull(InstanceManager.getDefault(LayoutBlockManager.class));
assertNotNull(InstanceManager.getDefault(jmri.ConditionalManager.class));
assertNotNull(InstanceManager.getDefault(jmri.LogixManager.class));
assertNotNull(InstanceManager.getDefault(Timebase.class));
assertNotNull(InstanceManager.getDefault(jmri.ClockControl.class));
assertNotNull(InstanceManager.getDefault(jmri.SignalGroupManager.class));
assertNotNull(InstanceManager.getDefault(jmri.ReporterManager.class));
assertNotNull(InstanceManager.getDefault(CatalogTreeManager.class));
assertNotNull(InstanceManager.getDefault(MemoryManager.class));
assertNotNull(InstanceManager.getDefault(AudioManager.class));
assertNotNull(InstanceManager.getDefault(RosterIconFactory.class));
}
//
// Tests of individual types, to make sure they
// properly create defaults
//
@Test
public void testLayoutBlockManager() {
LayoutBlockManager obj = InstanceManager.getDefault(LayoutBlockManager.class);
assertNotNull(obj);
assertEquals(obj, InstanceManager.getDefault(LayoutBlockManager.class));
assertEquals(obj, InstanceManager.getDefault(LayoutBlockManager.class));
assertEquals(obj, InstanceManager.getDefault(LayoutBlockManager.class));
}
@Test
public void testWarrantManager() {
WarrantManager obj = InstanceManager.getDefault(WarrantManager.class);
assertNotNull(obj);
assertEquals(obj, InstanceManager.getDefault(WarrantManager.class));
assertEquals(obj, InstanceManager.getDefault(WarrantManager.class));
assertEquals(obj, InstanceManager.getDefault(WarrantManager.class));
}
@Test
public void testOBlockManager() {
OBlockManager obj = InstanceManager.getDefault(jmri.jmrit.logix.OBlockManager.class);
assertNotNull(obj);
assertEquals(obj, InstanceManager.getDefault(jmri.jmrit.logix.OBlockManager.class));
assertEquals(obj, InstanceManager.getDefault(OBlockManager.class));
assertEquals(obj, InstanceManager.getDefault(jmri.jmrit.logix.OBlockManager.class));
}
@Test
public void testClearAll() {
PowerManager pm1 = new PowerManagerScaffold();
PowerManager pm2 = new PowerManagerScaffold();
NoAutoCreate nac1 = new NoAutoCreate();
InstanceManager.store(pm1, PowerManager.class);
InstanceManager.store(pm2, PowerManager.class);
InstanceManager.store(nac1, NoAutoCreate.class);
// should contain two lists and calls for other lists should be empty
assertFalse(InstanceManager.getList(PowerManager.class).isEmpty());
assertFalse(InstanceManager.getList(NoAutoCreate.class).isEmpty());
assertTrue(InstanceManager.getList(OkAutoCreate.class).isEmpty());
InstanceManager.getDefault().clearAll();
// should contain only empty lists
assertTrue(InstanceManager.getList(PowerManager.class).isEmpty());
assertTrue(InstanceManager.getList(NoAutoCreate.class).isEmpty());
assertTrue(InstanceManager.getList(OkAutoCreate.class).isEmpty());
}
@Test
public void testClear() {
PowerManager pm1 = new PowerManagerScaffold();
PowerManager pm2 = new PowerManagerScaffold();
NoAutoCreate nac1 = new NoAutoCreate();
InstanceManager.store(pm1, PowerManager.class);
InstanceManager.store(pm2, PowerManager.class);
InstanceManager.store(nac1, NoAutoCreate.class);
// should contain two lists and calls for other lists should be empty
assertFalse(InstanceManager.getList(PowerManager.class).isEmpty());
assertFalse(InstanceManager.getList(NoAutoCreate.class).isEmpty());
assertTrue(InstanceManager.getList(OkAutoCreate.class).isEmpty());
InstanceManager.getDefault().clear(PowerManager.class);
// should contain one list and calls for other lists should be empty
assertTrue(InstanceManager.getList(PowerManager.class).isEmpty());
assertFalse(InstanceManager.getList(NoAutoCreate.class).isEmpty());
assertTrue(InstanceManager.getList(OkAutoCreate.class).isEmpty());
InstanceManager.getDefault().clear(NoAutoCreate.class);
// should contain only empty lists
assertTrue(InstanceManager.getList(PowerManager.class).isEmpty());
assertTrue(InstanceManager.getList(NoAutoCreate.class).isEmpty());
assertTrue(InstanceManager.getList(OkAutoCreate.class).isEmpty());
InstanceManager.getDefault().clear(OkAutoCreate.class);
// verify that no exception was thrown
assertTrue(InstanceManager.getList(PowerManager.class).isEmpty());
assertTrue(InstanceManager.getList(NoAutoCreate.class).isEmpty());
assertTrue(InstanceManager.getList(OkAutoCreate.class).isEmpty());
}
@Test
public void testContainsDefault() {
// verify not OkAutoCreate instances exist
InstanceManager.reset(OkAutoCreate.class);
assertFalse( InstanceManager.containsDefault(OkAutoCreate.class), "Should be empty");
// create a OkAutoCreate instance
assertNotNull(InstanceManager.getDefault(OkAutoCreate.class));
assertTrue( InstanceManager.containsDefault(OkAutoCreate.class), "Should not be empty");
// remote OkAutoCreate instance
InstanceManager.reset(OkAutoCreate.class);
assertFalse( InstanceManager.containsDefault(OkAutoCreate.class), "Should be empty");
}
@BeforeEach
public void setUp() {
JUnitUtil.setUp();
OkToDispose.startUp();
InstanceManager.getDefault().clearAll();
}
@AfterEach
public void tearDown() {
JUnitUtil.deregisterBlockManagerShutdownTask();
JUnitUtil.tearDown();
}
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(InstanceManagerTest.class);
}