Nick Carroll

Metabolising caffeine into code

Archive for the ‘concurrency’ tag

Limiting integration tests to a time constraint

with 4 comments

I have recently had the need to restrict a test to run within a certain time limit. If the test does not complete within a specific time constraint then the test should fail. The approach that I took was to run the function under test in its own thread and use a CountDownLatch to specify the duration in which the process should complete within. The code for this is as follows.

public class TimeConstrainedIntegrationTest {

    private static final int RUN_ONCE = 1;

    @Test
    public void shouldVerifyGoogleIsAlive() throws Exception {
        CountDownLatch doneSignal = new CountDownLatch(RUN_ONCE);

        new Thread(new VerifyGoogleIsAliveWorker(doneSignal)).start();

        boolean finishedInTime = doneSignal.await(10, TimeUnit.SECONDS);
        assertTrue(finishedInTime);
    }

    private class VerifyGoogleIsAliveWorker implements Runnable {
        private final CountDownLatch doneSignal;

        VerifyGoogleIsAliveWorker(CountDownLatch doneSignal) {
            this.doneSignal = doneSignal;
        }

        public void run() {
            try {
                try {
                    verifyGoogleIsAlive();
                } catch (IOException e) {
                    throw new InterruptedException();
                }

                doneSignal.countDown();
            } catch (InterruptedException ex) {
            }
        }

        private void verifyGoogleIsAlive() throws IOException {
            WebClient webClient = new WebClient();
            Page page = webClient.getPage("http://google.com");
            assertTrue(StringUtils.contains(page.getTitleText(), "Google"));
        }
    }
}

In the code above I assert that Google is alive by checking the title text for http://google.com is in fact Google. Essentially I am asserting expected behaviour, which is what you would typically do. I have encapsulated this within the verifyGoogleIsAlive() method above.

To make sure that the test runs within a specific time, the verifyGoogleIsAlive() method is called within the run method of a class that implements Runnable. In this case I have called the class VerifyGoogleIsAliveWorker. The test case shouldVerifyGoogleIsAlive() should be quite self-explanatory. First a CountDownLatch is instantiated. Then a new VerifyGoogleIsAliveWorker thread is started. The CountDownLatch then awaits for the VerifyGoogleIsAliveWorker thread to run its course and complete.

Of interest though is that the awaits() method on the CountDownLatch allows you to specify the length of time in which the CountDownLatch should wait before ending the thread. If the process doesn’t complete within the specified time, then the awaits() method will return false, and therefore fail the assertion that the test will run within a specific time. If on the other hand the process completes within the allocated time frame then the test will pass.

The above concurrency pattern should be useful in making sure that your tests run within a specific time frame.

Written by Nick

January 28th, 2009 at 10:46 pm

Posted in Programming

Tagged with , , ,