This problem was found in StartedRootOnTabletServiceTest, but it is actually more widespread.
TabletService's fiber invokes the guava AbstractService#notifyFailed method if there is an uncaught exception on that fiber. But, the test code never sees this exception, because nothing is listening for the failure state transition.
This was observed when a mock sub-object had a missing jmock expectation, causing an AssertionError on TabletService's fiber. TabletService then failed, and the only observable consequence was that an "assertEventually" in StartedRootOnTabletServiceTest timed out. But there was no explanation for why it timed out, and the AssertionError could only be observed by tracing through the code.
In general, if code tests any C5Module (or AbstractService, really), it should monitor the object's state for a failure, and report the failure cause.
This problem was found in StartedRootOnTabletServiceTest, but it is actually more widespread.
TabletService's fiber invokes the guava AbstractService#notifyFailed method if there is an uncaught exception on that fiber. But, the test code never sees this exception, because nothing is listening for the failure state transition.
This was observed when a mock sub-object had a missing jmock expectation, causing an AssertionError on TabletService's fiber. TabletService then failed, and the only observable consequence was that an "assertEventually" in StartedRootOnTabletServiceTest timed out. But there was no explanation for why it timed out, and the AssertionError could only be observed by tracing through the code.
In general, if code tests any C5Module (or AbstractService, really), it should monitor the object's state for a failure, and report the failure cause.