Topics

Advice requested on handing of connection shutdown in tests

Bob Jacobsen
 

jmri.jmrix.AbstractMRTrafficController is the basis for a lot of connection-specific logic in the jmrix.* system-specific packages.

It provides (abstract) support for handing various communications clean up operations when the program terminates via this in the AbstractMRTrafficController constructor:

// We use a shutdown hook here to make sure the connection is left
// in a clean state prior to exiting. This is required on systems
// which have a service mode to ensure we don't leave the system
// in an unusable state (This code predates the ShutdownTask
// mechanisim). Once the shutdown hook executes, the connection
// must be considered closed.
shutdownHook = new Thread(new CleanupHook(this));
Runtime.getRuntime().addShutdownHook(shutdownHook);

where the call to CleanupHook (defined as a static class within AbstractMRTrafficController) just provides a run() method that calls the locally-implemented terminate() method. Subclasses either user the default terminte to just exit service mode, or override terminate() to do what’s needed. A quick search finds just four reimplementations.

The problem is that this is leaving a _bunch_ of shutdown hooks in the Runtime during tests.

It’s pretty easy to move this code to JMRI’s standard ShutdownTask approach. That will still work at regular runtime quite nicely.

But it’s a lot of work to do this in _tests_, because many of the jrmix tests don’t initialize the shutdown manager and will fail.

So I’d like some advice on how to handle this. Good ideas welcome! Here are the things I’m considering, _none_ ideal:

1) Update the main code, run the tests, and update @Before with initShutDownManager() and @After with clearShutDownManager() until everything passes. Lots of updates. Might end up in odd places due to inheritance…

2) Create a much clearer inheritance structure in the jmrix tests that makes it possible to have @Before with initShutDownManager() and @After with clearShutDownManager() in just a few places. Very, very hard to get this right without breaking things…

3) Add initShutDownManager() and clearShutDownManager() to JUnitUtil.setUp() and JUnitUtil.tearDown() respectively. This fixes it throughout, at some cost to thousands of tests that don’t use shutdown hooks.

4) Like (3), but be smarter about creating the (mock) ShutDownManager only when code under test requests it. That’s nicely possible given the way InstanceManager handles creating objects, but still requires a bit of initialization/shutdown, just less.

I’m leaning toward (1), because it’s conceptually simple, but it unfortunately adds a lot of replicated code.

Any better ideas?

Bob



--
Bob Jacobsen
@BobJacobsen

Randall Wood <rhwood@...>
 

I think a MockShutDownManager is created in unit tests on demand, so you should be able to rely on it’s being available without needing anything in @Before.


Randall

On Oct 9, 2019, at 15:51, Bob Jacobsen <rgj1927@...> wrote:

jmri.jmrix.AbstractMRTrafficController is the basis for a lot of connection-specific logic in the jmrix.* system-specific packages.

It provides (abstract) support for handing various communications clean up operations when the program terminates via this in the AbstractMRTrafficController constructor:

       // We use a shutdown hook here to make sure the connection is left
       // in a clean state prior to exiting.  This is required on systems
       // which have a service mode to ensure we don't leave the system
       // in an unusable state (This code predates the ShutdownTask
       // mechanisim).  Once the shutdown hook executes, the connection
       // must be considered closed.
       shutdownHook = new Thread(new CleanupHook(this));
       Runtime.getRuntime().addShutdownHook(shutdownHook);

where the call to CleanupHook (defined as a static class within AbstractMRTrafficController) just provides a run() method that calls the locally-implemented terminate() method.  Subclasses either user the default terminte to just exit service mode, or override terminate() to do what’s needed. A quick search finds just four reimplementations.

The problem is that this is leaving a _bunch_ of shutdown hooks in the Runtime during tests.

It’s pretty easy to move this code to JMRI’s standard ShutdownTask approach. That will still work at regular runtime quite nicely.

But it’s a lot of work to do this in _tests_, because many of the jrmix tests don’t initialize the shutdown manager and will fail.

So I’d like some advice on how to handle this.  Good ideas welcome!  Here are the things I’m considering, _none_ ideal:

1) Update the main code, run the tests, and update @Before with initShutDownManager() and @After with clearShutDownManager() until everything passes.  Lots of updates.  Might end up in odd places due to inheritance…

2) Create a much clearer inheritance structure in the jmrix tests that makes it possible to have @Before with initShutDownManager() and @After with clearShutDownManager() in just a few places.  Very, very hard to get this right without breaking things…

3) Add initShutDownManager() and clearShutDownManager() to JUnitUtil.setUp() and JUnitUtil.tearDown() respectively.  This fixes it throughout, at some cost to thousands of tests that don’t use shutdown hooks.

4) Like (3), but be smarter about creating the (mock) ShutDownManager only when code under test requests it.  That’s nicely possible given the way InstanceManager handles creating objects, but still requires a bit of initialization/shutdown, just less.

I’m leaning toward (1), because it’s conceptually simple, but it unfortunately adds a lot of replicated code.

Any better ideas?

Bob



--
Bob Jacobsen
rgj1927@...






whmvd
 

Bob,

In cases like this, I'd go for #3 without a second's hesitation. It is obvious, it is clear, it is easy and the cost is born only by *tests*. Everything else will add complexity in code and/or object model. This solution uses existing code in the way it's meant to be used. Nobody needs to be aware of anything - it just happens and it just works.

The only thing I'd want to look at is whether there are tests that bring the test framework close to breaking point on any supported environment - that might now push it beyond. That could be a biggie, but would have to be done anyway with other solutions as well.

Wouter


On Wed, 9 Oct 2019 at 20:51, Bob Jacobsen <rgj1927@...> wrote:
jmri.jmrix.AbstractMRTrafficController is the basis for a lot of connection-specific logic in the jmrix.* system-specific packages.

It provides (abstract) support for handing various communications clean up operations when the program terminates via this in the AbstractMRTrafficController constructor:

        // We use a shutdown hook here to make sure the connection is left
        // in a clean state prior to exiting.  This is required on systems
        // which have a service mode to ensure we don't leave the system
        // in an unusable state (This code predates the ShutdownTask
        // mechanisim).  Once the shutdown hook executes, the connection
        // must be considered closed.
        shutdownHook = new Thread(new CleanupHook(this));
        Runtime.getRuntime().addShutdownHook(shutdownHook);

where the call to CleanupHook (defined as a static class within AbstractMRTrafficController) just provides a run() method that calls the locally-implemented terminate() method.  Subclasses either user the default terminte to just exit service mode, or override terminate() to do what’s needed. A quick search finds just four reimplementations.

The problem is that this is leaving a _bunch_ of shutdown hooks in the Runtime during tests.

It’s pretty easy to move this code to JMRI’s standard ShutdownTask approach. That will still work at regular runtime quite nicely.

But it’s a lot of work to do this in _tests_, because many of the jrmix tests don’t initialize the shutdown manager and will fail.

So I’d like some advice on how to handle this.  Good ideas welcome!  Here are the things I’m considering, _none_ ideal:

1) Update the main code, run the tests, and update @Before with initShutDownManager() and @After with clearShutDownManager() until everything passes.  Lots of updates.  Might end up in odd places due to inheritance…

2) Create a much clearer inheritance structure in the jmrix tests that makes it possible to have @Before with initShutDownManager() and @After with clearShutDownManager() in just a few places.  Very, very hard to get this right without breaking things…

3) Add initShutDownManager() and clearShutDownManager() to JUnitUtil.setUp() and JUnitUtil.tearDown() respectively.  This fixes it throughout, at some cost to thousands of tests that don’t use shutdown hooks.

4) Like (3), but be smarter about creating the (mock) ShutDownManager only when code under test requests it.  That’s nicely possible given the way InstanceManager handles creating objects, but still requires a bit of initialization/shutdown, just less.

I’m leaning toward (1), because it’s conceptually simple, but it unfortunately adds a lot of replicated code.

Any better ideas?

Bob



--
Bob Jacobsen
rgj1927@...






Bob Jacobsen
 

Looks like a cool mechanism, but I’m not entirely sure how it’s supposed to be set up.

When I remove the `JUnitUtil.initShutDownManager();` call from the @Before routine of e.g. java/test/jmri/jmrit/logix/WarrantTest.java, it fails with:

% ./runtest.csh java/test//jmri/jmrit/logix/WarrantTest.java
.Using org.netbeans.jemmy.drivers.APIDriverInstaller driver installer
ERROR - No ShutDownManager for WarrantRosterSpeedProfileCheck [Engineer(TestTrain)] jmri.jmrit.logix.WarrantManager.setSpeedProfiles()
E
Time: 4.381
There was 1 failure:
1) testWarrant(jmri.jmrit.logix.WarrantTest)
java.lang.AssertionError: Unexpected ERROR or higher messages emitted: null
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertFalse(Assert.java:64)
at jmri.util.JUnitUtil.tearDown(JUnitUtil.java:314)
at jmri.jmrit.logix.WarrantTest.tearDown(WarrantTest.java:265)


That ERROR is invoked in java/src//jmri/jmrit/logix/WarrantManager.java from

if (jmri.InstanceManager.getNullableDefault(jmri.ShutDownManager.class) != null) {
ShutDownTask shutDownTask = new WarrantShutdownTask("WarrantRosterSpeedProfileCheck");
jmri.InstanceManager.getDefault(jmri.ShutDownManager.class).register(shutDownTask);
} else {
log.error("No ShutDownManager for WarrantRosterSpeedProfileCheck");
}

So it looks like somehow the MockShutDownManager (or any other ShutDownManager implementation) is being provided.

The WarrantTest @Before method does do the basic initialization:

@Before
public void setUp() {
JUnitUtil.setUp();
}


Is anything else needed?

Thanks!

Bob


On Oct 9, 2019, at 1:32 PM, Randall Wood via Groups.Io <rhwood=mac.com@groups.io> wrote:

I think a MockShutDownManager is created in unit tests on demand, so you should be able to rely on it’s being available without needing anything in @Before.

See ShutDownManagerInitializer (https://github.com/JMRI/JMRI/blob/master/java/src/jmri/managers/ShutDownManagerInitializer.java) and https://github.com/JMRI/JMRI/commit/1963081d5f92f036a5839a07d31cd28874f8e9e2 for how that works.
--
Bob Jacobsen
@BobJacobsen

Bob Jacobsen
 

Or is the problem that the request shouldn’t be via InstanceManager.getNullableDefault and instead be via InstanceManager.getDefault?

Bob

On Oct 9, 2019, at 2:59 PM, Bob Jacobsen via Groups.Io <rgj1927=gmail.com@groups.io> wrote:

Looks like a cool mechanism, but I’m not entirely sure how it’s supposed to be set up.

When I remove the `JUnitUtil.initShutDownManager();` call from the @Before routine of e.g. java/test/jmri/jmrit/logix/WarrantTest.java, it fails with:

% ./runtest.csh java/test//jmri/jmrit/logix/WarrantTest.java
.Using org.netbeans.jemmy.drivers.APIDriverInstaller driver installer
ERROR - No ShutDownManager for WarrantRosterSpeedProfileCheck [Engineer(TestTrain)] jmri.jmrit.logix.WarrantManager.setSpeedProfiles()
E
Time: 4.381
There was 1 failure:
1) testWarrant(jmri.jmrit.logix.WarrantTest)
java.lang.AssertionError: Unexpected ERROR or higher messages emitted: null
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertFalse(Assert.java:64)
at jmri.util.JUnitUtil.tearDown(JUnitUtil.java:314)
at jmri.jmrit.logix.WarrantTest.tearDown(WarrantTest.java:265)


That ERROR is invoked in java/src//jmri/jmrit/logix/WarrantManager.java from

if (jmri.InstanceManager.getNullableDefault(jmri.ShutDownManager.class) != null) {
ShutDownTask shutDownTask = new WarrantShutdownTask("WarrantRosterSpeedProfileCheck");
jmri.InstanceManager.getDefault(jmri.ShutDownManager.class).register(shutDownTask);
} else {
log.error("No ShutDownManager for WarrantRosterSpeedProfileCheck");
}

So it looks like somehow the MockShutDownManager (or any other ShutDownManager implementation) is being provided.

The WarrantTest @Before method does do the basic initialization:

@Before
public void setUp() {
JUnitUtil.setUp();
}


Is anything else needed?

Thanks!

Bob


On Oct 9, 2019, at 1:32 PM, Randall Wood via Groups.Io <rhwood=mac.com@groups.io> wrote:

I think a MockShutDownManager is created in unit tests on demand, so you should be able to rely on it’s being available without needing anything in @Before.

See ShutDownManagerInitializer (https://github.com/JMRI/JMRI/blob/master/java/src/jmri/managers/ShutDownManagerInitializer.java) and https://github.com/JMRI/JMRI/commit/1963081d5f92f036a5839a07d31cd28874f8e9e2 for how that works.
--
Bob Jacobsen
@BobJacobsen





--
Bob Jacobsen
@BobJacobsen

Randall Wood <rhwood@...>
 

Two possibilities off the top of my head without really looking at it:

- it doesn’t need to be called via getNullableDefault
- I may have missed a target for adding the jmri.shutdownmanager property in some test path

Randall

On Oct 9, 2019, at 18:01, Bob Jacobsen <@BobJacobsen> wrote:

Or is the problem that the request shouldn’t be via InstanceManager.getNullableDefault and instead be via InstanceManager.getDefault?

Bob

On Oct 9, 2019, at 2:59 PM, Bob Jacobsen via Groups.Io <rgj1927=gmail.com@groups.io> wrote:

Looks like a cool mechanism, but I’m not entirely sure how it’s supposed to be set up.

When I remove the `JUnitUtil.initShutDownManager();` call from the @Before routine of e.g. java/test/jmri/jmrit/logix/WarrantTest.java, it fails with:

% ./runtest.csh java/test//jmri/jmrit/logix/WarrantTest.java
.Using org.netbeans.jemmy.drivers.APIDriverInstaller driver installer
ERROR - No ShutDownManager for WarrantRosterSpeedProfileCheck [Engineer(TestTrain)] jmri.jmrit.logix.WarrantManager.setSpeedProfiles()
E
Time: 4.381
There was 1 failure:
1) testWarrant(jmri.jmrit.logix.WarrantTest)
java.lang.AssertionError: Unexpected ERROR or higher messages emitted: null
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertFalse(Assert.java:64)
at jmri.util.JUnitUtil.tearDown(JUnitUtil.java:314)
at jmri.jmrit.logix.WarrantTest.tearDown(WarrantTest.java:265)


That ERROR is invoked in java/src//jmri/jmrit/logix/WarrantManager.java from

if (jmri.InstanceManager.getNullableDefault(jmri.ShutDownManager.class) != null) {
ShutDownTask shutDownTask = new WarrantShutdownTask("WarrantRosterSpeedProfileCheck");
jmri.InstanceManager.getDefault(jmri.ShutDownManager.class).register(shutDownTask);
} else {
log.error("No ShutDownManager for WarrantRosterSpeedProfileCheck");
}

So it looks like somehow the MockShutDownManager (or any other ShutDownManager implementation) is being provided.

The WarrantTest @Before method does do the basic initialization:

@Before
public void setUp() {
JUnitUtil.setUp();
}


Is anything else needed?

Thanks!

Bob


On Oct 9, 2019, at 1:32 PM, Randall Wood via Groups.Io <rhwood=mac.com@groups.io> wrote:
I think a MockShutDownManager is created in unit tests on demand, so you should be able to rely on it’s being available without needing anything in @Before.

See ShutDownManagerInitializer (https://github.com/JMRI/JMRI/blob/master/java/src/jmri/managers/ShutDownManagerInitializer.java) and https://github.com/JMRI/JMRI/commit/1963081d5f92f036a5839a07d31cd28874f8e9e2 for how that works.
--
Bob Jacobsen
@BobJacobsen





--
Bob Jacobsen
@BobJacobsen





Bob Jacobsen
 

One question solved: If getNullableDefault is used _and_ you want it to find something in the test (that could go either way), then an explicit call to initShutDownManager() _or_ a call to InstanceManager.getDefault is needed before hand.

I’ll add that to the documentation.

Thanks!

Bob

On Oct 9, 2019, at 3:36 PM, Randall Wood via Groups.Io <rhwood=mac.com@groups.io> wrote:

Two possibilities off the top of my head without really looking at it:

- it doesn’t need to be called via getNullableDefault
- I may have missed a target for adding the jmri.shutdownmanager property in some test path

Randall
On Oct 9, 2019, at 18:01, Bob Jacobsen <@BobJacobsen> wrote:

Or is the problem that the request shouldn’t be via InstanceManager.getNullableDefault and instead be via InstanceManager.getDefault?

Bob

On Oct 9, 2019, at 2:59 PM, Bob Jacobsen via Groups.Io <rgj1927=gmail.com@groups.io> wrote:

Looks like a cool mechanism, but I’m not entirely sure how it’s supposed to be set up.

When I remove the `JUnitUtil.initShutDownManager();` call from the @Before routine of e.g. java/test/jmri/jmrit/logix/WarrantTest.java, it fails with:

% ./runtest.csh java/test//jmri/jmrit/logix/WarrantTest.java
.Using org.netbeans.jemmy.drivers.APIDriverInstaller driver installer
ERROR - No ShutDownManager for WarrantRosterSpeedProfileCheck [Engineer(TestTrain)] jmri.jmrit.logix.WarrantManager.setSpeedProfiles()
E
Time: 4.381
There was 1 failure:
1) testWarrant(jmri.jmrit.logix.WarrantTest)
java.lang.AssertionError: Unexpected ERROR or higher messages emitted: null
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertFalse(Assert.java:64)
at jmri.util.JUnitUtil.tearDown(JUnitUtil.java:314)
at jmri.jmrit.logix.WarrantTest.tearDown(WarrantTest.java:265)


That ERROR is invoked in java/src//jmri/jmrit/logix/WarrantManager.java from

if (jmri.InstanceManager.getNullableDefault(jmri.ShutDownManager.class) != null) {
ShutDownTask shutDownTask = new WarrantShutdownTask("WarrantRosterSpeedProfileCheck");
jmri.InstanceManager.getDefault(jmri.ShutDownManager.class).register(shutDownTask);
} else {
log.error("No ShutDownManager for WarrantRosterSpeedProfileCheck");
}

So it looks like somehow the MockShutDownManager (or any other ShutDownManager implementation) is being provided.

The WarrantTest @Before method does do the basic initialization:

@Before
public void setUp() {
JUnitUtil.setUp();
}


Is anything else needed?

Thanks!

Bob


On Oct 9, 2019, at 1:32 PM, Randall Wood via Groups.Io <rhwood=mac.com@groups.io> wrote:
I think a MockShutDownManager is created in unit tests on demand, so you should be able to rely on it’s being available without needing anything in @Before.

See ShutDownManagerInitializer (https://github.com/JMRI/JMRI/blob/master/java/src/jmri/managers/ShutDownManagerInitializer.java) and https://github.com/JMRI/JMRI/commit/1963081d5f92f036a5839a07d31cd28874f8e9e2 for how that works.
--
Bob Jacobsen
@BobJacobsen





--
Bob Jacobsen
@BobJacobsen







--
Bob Jacobsen
@BobJacobsen

Randall Wood <rhwood@...>
 

That’s interesting. I know getDefault(...) creates a default if it is missing. Should getNullableDefault(...) also create a default if missing and an initializer exists (or the class implements AutoDefault)?

But for items requesting a ShutDownManager, since the initializer was added, getNullableDefault(ShutDownManager.class) can be directly replaced with getDefault(ShutDownManager.class) with the expectation there will be a ShutDownManager.

Randall

On Oct 9, 2019, at 19:09, Bob Jacobsen <@BobJacobsen> wrote:

One question solved: If getNullableDefault is used _and_ you want it to find something in the test (that could go either way), then an explicit call to initShutDownManager() _or_ a call to InstanceManager.getDefault is needed before hand.

I’ll add that to the documentation.

Thanks!

Bob

On Oct 9, 2019, at 3:36 PM, Randall Wood via Groups.Io <rhwood=mac.com@groups.io> wrote:

Two possibilities off the top of my head without really looking at it:

- it doesn’t need to be called via getNullableDefault
- I may have missed a target for adding the jmri.shutdownmanager property in some test path

Randall
On Oct 9, 2019, at 18:01, Bob Jacobsen <@BobJacobsen> wrote:
Or is the problem that the request shouldn’t be via InstanceManager.getNullableDefault and instead be via InstanceManager.getDefault?

Bob

On Oct 9, 2019, at 2:59 PM, Bob Jacobsen via Groups.Io <rgj1927=gmail.com@groups.io> wrote:

Looks like a cool mechanism, but I’m not entirely sure how it’s supposed to be set up.

When I remove the `JUnitUtil.initShutDownManager();` call from the @Before routine of e.g. java/test/jmri/jmrit/logix/WarrantTest.java, it fails with:

% ./runtest.csh java/test//jmri/jmrit/logix/WarrantTest.java
.Using org.netbeans.jemmy.drivers.APIDriverInstaller driver installer
ERROR - No ShutDownManager for WarrantRosterSpeedProfileCheck [Engineer(TestTrain)] jmri.jmrit.logix.WarrantManager.setSpeedProfiles()
E
Time: 4.381
There was 1 failure:
1) testWarrant(jmri.jmrit.logix.WarrantTest)
java.lang.AssertionError: Unexpected ERROR or higher messages emitted: null
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertFalse(Assert.java:64)
at jmri.util.JUnitUtil.tearDown(JUnitUtil.java:314)
at jmri.jmrit.logix.WarrantTest.tearDown(WarrantTest.java:265)


That ERROR is invoked in java/src//jmri/jmrit/logix/WarrantManager.java from

if (jmri.InstanceManager.getNullableDefault(jmri.ShutDownManager.class) != null) {
ShutDownTask shutDownTask = new WarrantShutdownTask("WarrantRosterSpeedProfileCheck");
jmri.InstanceManager.getDefault(jmri.ShutDownManager.class).register(shutDownTask);
} else {
log.error("No ShutDownManager for WarrantRosterSpeedProfileCheck");
}

So it looks like somehow the MockShutDownManager (or any other ShutDownManager implementation) is being provided.

The WarrantTest @Before method does do the basic initialization:

@Before
public void setUp() {
JUnitUtil.setUp();
}


Is anything else needed?

Thanks!

Bob


On Oct 9, 2019, at 1:32 PM, Randall Wood via Groups.Io <rhwood=mac.com@groups.io> wrote:
I think a MockShutDownManager is created in unit tests on demand, so you should be able to rely on it’s being available without needing anything in @Before.

See ShutDownManagerInitializer (https://github.com/JMRI/JMRI/blob/master/java/src/jmri/managers/ShutDownManagerInitializer.java) and https://github.com/JMRI/JMRI/commit/1963081d5f92f036a5839a07d31cd28874f8e9e2 for how that works.
--
Bob Jacobsen
@BobJacobsen





--
Bob Jacobsen
@BobJacobsen







--
Bob Jacobsen
@BobJacobsen





Pete Cressman
 

If the code

>>>>        if (jmri.InstanceManager.getNullableDefault(jmri.ShutDownManager.class) != null) {
>>>>            ShutDownTask shutDownTask = new WarrantShutdownTask("WarrantRosterSpeedProfileCheck");
>>>>                    jmri.InstanceManager.getDefault(jmri.ShutDownManager.class).register(shutDownTask);
>>>>        } else {
>>>>            log.error("No ShutDownManager for WarrantRosterSpeedProfileCheck");
>>>>        }

is causing a problem and something other than jmri.InstanceManager.getNullableDefault() should be called, please change it to some preferred alternative.  Undoubtedly I copied it from someone else since I don't understand the involved subtleties.

Pete


On Wednesday, October 9, 2019, 06:44:23 PM PDT, Randall Wood via Groups.Io <rhwood@...> wrote:


That’s interesting. I know getDefault(...) creates a default if it is missing. Should getNullableDefault(...) also create a default if missing and an initializer exists (or the class implements AutoDefault)?

But for items requesting a ShutDownManager, since the initializer was added, getNullableDefault(ShutDownManager.class) can be directly replaced with getDefault(ShutDownManager.class) with the expectation there will be a ShutDownManager.

Randall
> On Oct 9, 2019, at 19:09, Bob Jacobsen <rgj1927@...> wrote:
>
> One question solved:  If getNullableDefault is used _and_ you want it to find something in the test (that could go either way), then an explicit call to initShutDownManager() _or_ a call to InstanceManager.getDefault is needed before hand.
>
> I’ll add that to the documentation.
>
> Thanks!
>
> Bob
>
>> On Oct 9, 2019, at 3:36 PM, Randall Wood via Groups.Io <rhwood=mac.com@groups.io> wrote:
>>
>> Two possibilities off the top of my head without really looking at it:
>>
>> - it doesn’t need to be called via getNullableDefault
>> - I may have missed a target for adding the jmri.shutdownmanager property in some test path
>>
>> Randall
>>>> On Oct 9, 2019, at 18:01, Bob Jacobsen <rgj1927@...> wrote:
>>>
>>> Or is the problem that the request shouldn’t be via InstanceManager.getNullableDefault and instead be via InstanceManager.getDefault?
>>>
>>> Bob
>>>
>>>> On Oct 9, 2019, at 2:59 PM, Bob Jacobsen via Groups.Io <rgj1927=gmail.com@groups.io> wrote:
>>>>
>>>> Looks like a cool mechanism, but I’m not entirely sure how it’s supposed to be set up.
>>>>
>>>> When I remove the `JUnitUtil.initShutDownManager();` call from the @Before routine of e.g. java/test/jmri/jmrit/logix/WarrantTest.java, it fails with:
>>>>
>>>> %  ./runtest.csh java/test//jmri/jmrit/logix/WarrantTest.java
>>>> .Using org.netbeans.jemmy.drivers.APIDriverInstaller driver installer
>>>> ERROR - No ShutDownManager for WarrantRosterSpeedProfileCheck [Engineer(TestTrain)] jmri.jmrit.logix.WarrantManager.setSpeedProfiles()
>>>> E
>>>> Time: 4.381
>>>> There was 1 failure:
>>>> 1) testWarrant(jmri.jmrit.logix.WarrantTest)
>>>> java.lang.AssertionError: Unexpected ERROR or higher messages emitted: null
>>>>  at org.junit.Assert.fail(Assert.java:88)
>>>>  at org.junit.Assert.assertTrue(Assert.java:41)
>>>>  at org.junit.Assert.assertFalse(Assert.java:64)
>>>>  at jmri.util.JUnitUtil.tearDown(JUnitUtil.java:314)
>>>>  at jmri.jmrit.logix.WarrantTest.tearDown(WarrantTest.java:265)
>>>>
>>>>
>>>> That ERROR is invoked in java/src//jmri/jmrit/logix/WarrantManager.java from
>>>>
>>>>        if (jmri.InstanceManager.getNullableDefault(jmri.ShutDownManager.class) != null) {
>>>>            ShutDownTask shutDownTask = new WarrantShutdownTask("WarrantRosterSpeedProfileCheck");
>>>>                    jmri.InstanceManager.getDefault(jmri.ShutDownManager.class).register(shutDownTask);
>>>>        } else {
>>>>            log.error("No ShutDownManager for WarrantRosterSpeedProfileCheck");
>>>>        }
>>>>
>>>> So it looks like somehow the MockShutDownManager (or any other ShutDownManager implementation) is being provided.
>>>>
>>>> The WarrantTest @Before method does do the basic initialization:
>>>>
>>>> @Before
>>>> public void setUp() {
>>>>    JUnitUtil.setUp();
>>>> }
>>>>
>>>>
>>>> Is anything else needed?
>>>>
>>>> Thanks!
>>>>
>>>> Bob
>>>>
>>>>
>>>>>> On Oct 9, 2019, at 1:32 PM, Randall Wood via Groups.Io <rhwood=mac.com@groups.io> wrote:
>>>>>
>>>>> I think a MockShutDownManager is created in unit tests on demand, so you should be able to rely on it’s being available without needing anything in @Before.
>>>>>
>>>>> See ShutDownManagerInitializer (https://github.com/JMRI/JMRI/blob/master/java/src/jmri/managers/ShutDownManagerInitializer.java) and https://github.com/JMRI/JMRI/commit/1963081d5f92f036a5839a07d31cd28874f8e9e2 for how that works.
>>>>>
>>>>
>>>> --
>>>> Bob Jacobsen
>>>> rgj1927@...
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>> --
>>> Bob Jacobsen
>>> rgj1927@...
>>>
>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>>
>
> --
> Bob Jacobsen
> rgj1927@...
>
>
>
>
>
>