Search code examples
javatestingjunitapache-karafsmoke-testing

JUnitTest for Karaf Startup


I want to write a JUnitTest, which ensures that my Karaf Server is started fine and all (needed) Bundles are installed and active.

For this I have a Test, calling a helper method "assertBundleState" which ensures, that the given Bundle is in the given State. The test looks like following:

@Test (timeout=30000L)    
public void testBundlesStarted() throws Exception {
    assertBundleState("bundle.Name", BundleLifecycleState.Active);
... <other bundles in similar way>
}

This worked fine in the past. The timeout was never reached.

Unfortunately I now have to load a bundle, which need a bit longer for startup. So the Bundles are not yet started, when the test is executed. And so the test fails.

I have tried it with a sleep in a BeforeClass method, but I am not really happy with this solution. Because I can't ensure that the given sleep time is enough on every machine at every time. So I am looking for some event-based solution to interact with Karaf.

@BeforeClass
public static void init() throws Exception {
    Thread.sleep(120000L);
}

Does anybody have an idea how I can solve it in a better way? Thanks


Solution

  • It sounds like assertBundleState can successfully determine whether the Karaf server has started and 'is ready'. But the issue is that you don't know how long to wait before checking this; if you don't wait long enough you risk a false negative, if you wait too long then your build elapsed time is falsely prolonged.

    I presume you cannot register some sort of listener or callback hook which the Karaf server will invoke when it 'is ready'. Indeed, even if that was possible you would still have to cater for the failure case i.e. where the Karaf server does not start (and hence could never invoke a listener).

    So, I think you just have to wait for the Karaf server to become available and hide the ugliness of Thread.sleep calls and the potential lost time in waiting too long. You could use Awaitility to tick those boxes. For example:

    @Test
    public void aTest() {
        // run your test
    
        // this will wait until Karaf is available for at most 10 seconds
        // and will check every 100ms so if Karaf becomes available earlier 
        // than 10 seconds then the test will complete almost as soon as
        // it becomes available but if Karaf does not become available 
        // within 10 seconds then the test will fail
        await().atMost(10, SECONDS).until(karafIsAvailable());
    
        // assert 
        // ...
    }
    
    private Callable<Boolean> karafIsAvailable() {
        return new Callable<Boolean>() {
            public Boolean call() throws Exception {
                // return true if your condition has been met
                // e.g. assertBundleState
                return ...;
            }
        };
    }