Saturday, September 22, 2007

I've added some timing information for running Impala in interactive test mode, and the numbers are quite interesting.

I start by firing up a JUnit test class, called WineDAOTest, which looks like the following:


public class WineDAOTest extends BaseDataTest {

public static void main(String[] args) {
PluginTestRunner.run(WineDAOTest.class);
}

public void testDAO() {

WineDAO dao = DynamicContextHolder.getBean(this, "wineDAO", WineDAO.class);

Wine wine = new Wine();
wine.setColor("red");
wine.setVineyard("Chateau X");
wine.setTitle("Cabernet");
wine.setVintage(1996);
dao.save(wine);

Collection winesOfVintage = dao.getWinesOfVintage(1996);
System.out.println("Wines of vintage 1996: " + winesOfVintage.size());
assertEquals(1, winesOfVintage.size());

wine.setVintage(2000);
wine.setColor("rose");
dao.update(wine);

Wine updated = dao.findById(wine.getId());
assertEquals(2000, updated.getVintage());

}

public PluginSpec getPluginSpec() {
return new PluginSpec("parent-context.xml", new String[] { "dao", "hibernate", "merchant" });
}

}






The Impala features have been added by

  • exposing a main method which calls PluginTestRunner
  • obtaining the Spring context bean using DynamicContextHolder.getBean(...)
  • providing an implementation of getPluginSpec(), which tells the PluginTestRunner which plugins to include as part of the test. Note that we have plugins for the basic Hibernate configuration, for the DAO implementations, and for the service classes (the merchant plugin)

We now run the class in interactive mode by running it as a Java application in Eclipse (instead of running it as a JUnit test. Here's the output.


--------------------------------
Enter u to show usage
>u
l [testClass] to load test class
[testName] to run test
reload [plugin name] to reload plugin
reload to reload parent context
s to show test methods
r to rerun last command
r to rerun last run test
e to exit
--------------------------------
Enter u to show usage
>s
Available test methods:
testDAO
--------------------------------
Enter u to show usage
>testDAO
Running test tests.WineDAOTest
.Wines of vintage 1996: 1
Time: 3.264
OK (1 test)

--------------------------------
Enter u to show usage
>reload
Parent context loaded in 0.551 seconds
Used memory: 3.4MB
Max available memory: 63.6MB

--------------------------------
Enter u to show usage
>reload
Parent context loaded in 0.34 seconds
Used memory: 4.2MB
Max available memory: 63.6MB

--------------------------------
Enter u to show usage
>reload
Parent context loaded in 0.521 seconds
Used memory: 3.8MB
Max available memory: 63.6MB

--------------------------------
Enter u to show usage
>reload hibernate
Plugin hibernate loaded in 0.21 seconds
Used memory: 4.3MB
Max available memory: 63.6MB

--------------------------------
Enter u to show usage
>reload merchant
Plugin merchant loaded in 0.16 seconds
Used memory: 4.6MB
Max available memory: 63.6MB

--------------------------------
Enter u to show usage
>reload dao
Plugin dao loaded in 0.141 seconds
Used memory: 4.5MB
Max available memory: 63.6MB

--------------------------------
Enter u to show usage
>reload
Parent context loaded in 0.511 seconds
Used memory: 4.1MB
Max available memory: 63.6MB

--------------------------------
Enter u to show usage
>reload
Parent context loaded in 0.43 seconds
Used memory: 3.9MB
Max available memory: 63.6MB

--------------------------------
Enter u to show usage
>testDAO
Running test tests.WineDAOTest
.Wines of vintage 1996: 1
Time: 0.081
OK (1 test)

--------------------------------
Enter u to show usage
>testDAO
Running test tests.WineDAOTest
.Wines of vintage 1996: 1
Time: 0.07
OK (1 test)

--------------------------------
Enter u to show usage
>



Notice how the initial test run took 3.2 seconds, which is how long we'd expect a small Spring/Hibernate test run to take. After that it gets more interesting.

Subsequent reloads of the application context (shown by the reload call) take only a fraction of the time: 0.55 seconds, 0.34 seconds, 0.51 seconds and 0.34 seconds. This is only a fraction of the time it takes to load the application context the first time.

Reloading individual plugins in much quicker: hibernate took 0.21 seconds, dao took 0.14 and merchant took 0.16 seconds. This means, at least for a small application, we can reflect changes almost instantly. Even for an application which loads 10 times more slowly, the numbers are still quite acceptable.

Running the test without doing the reload is also extremely fast: compare 0.07 and 0.08 seconds with the original 3.2 seconds.

No comments: