Mittwoch, 24. April 2013

Simple Table DSL in Groovy

Sometimes the best way to model data is as a table. A good example where you could use tables is the spock framework. Spock is a great testing framework for Java and Groovy. In spock the test parameters can be defined as a table. The spock framework use Groovy AST transformations to implement the DSL for the tables. I think about if there is a simpler way to parse an embedded table DSL in groovy. Not with the same features then the spock table DSL. My requirements for the DSL are to define a table and to have support for variables in the table.

Here a short example of such a table:

To implement the DSL parser in groovy I use two groovy languages feature:
  1. The category feature to define the OR operators, for the different types of the table values 
  2. The dynamic of groovy for the variable support, the getProperty is overwritten and creates a object of type Var for a undefined groovy variable
The code below contains a simple groovy implementation of a table DSL parser. The simple parser now can be used to parse the table DSL from the example above. How the DSL can be use in JUnit is show in the parameterized test in the listing below. Not a perfect example, because for testing you should use Spock instead.

Dienstag, 2. Oktober 2012

Overview Parameterized Tests with JUnit

Gerard Meszaros's describes in his great book with the title xUnit Test Patterns a pattern with the name Parameterized Test. This blog post describes how the pattern can be implemented in a JUnit 4.X test. The post compares three different options.

1. JUnit Parameterized Test

The JUnit framework comes with a runner for parameterized tests. The parameters are defined by a static function which is marked with the annotation @Parameters. The JUnit Runner is called Parameterized.

Example: 
Output - Eclipse JUnit View: 
Advantages
No extra framework or library for parameterized tests is needed. The JUnit view in eclipse and also in other IDEs works fine. One test with one defined parameter set can be invoked via the JUnit view in eclipse.

Disadvantages
The output from the tests is not clear. The output shows only the index number of the used test parameter. Only one test data model and parameter set per test class.

2. More JUnit Parameterized Test in a Test Class

It is possible to have more then one parameterized JUnit test in one test class by using the experimental runner "Enclosed".

Example: 
Output - Eclipse JUnit View:
Advantages
Grouping logic tests together in one class. Each test can be run from the JUnit view, a single test can be executed for debugging.

Disadvantages
Lots of boilerplate code of the embedded classes.

3. TwiP

TwiP is JUnit extension for parameterized tests. The library brings a JUnit runner, which is named "TwiP".

Example: 
Output - Eclipse JUnit View: 

Advantages
More then one parameterized test in a class is possible. Mixing parameterized and not parameterized tests is possible in one test class. Clear test output toString() method is used for the test parameters.

Disadvantages
A single test could not be chosen from the JUnit output (Eclipse JUnit view) and could not be invoked. This makes debugging the tests difficult because always all test combination must be executed to debug one failing test with one special combination.

4. JUnit Params

JUnit Params is another JUnit extension for parameterized tests like TwiP. The essential difference between TwiP and JUnit Params are the syntax how to define the parameterized tests.

Example: 
Output - Eclipse JUnit View: 


Advantages
Same advantages as TwiP and a little bit clearer test output then TwiP.

Disadvantages
Same disadvantages as TwiP a single test could not be invoked.

5. Summary

A perfect solution for a parameterized test in JUnit does not exists. TwiP and JUnitParams provided the way I like to write parameterized tests. But TwiP and also JUnitParams test cannot be debugged a single test can not be executed. I think the problems lies in the JUnit design for the descriptions and not in the TwiP or the JUnitParams project. Hope there will be a better solution in the future. So it's a difficult choice

Dienstag, 25. September 2012

Performance Apache Common StringUtils Split and Google Guava Splitter

Last Friday I have a discussion with a colleague at SEITENBAU about the semantic of the split method of the Apache common lang StringUtils class. At the end we have compared the Google Guava Splitter API with the Apache commons Lang StringUtils split methods. Our opinion after that is that the source code based on Guava could be better understood and is much clearer.

After comparing the APIs, we have thought about which of the two APIs has the faster split implementation. So I have build simple performance test for the two String split implementations. The result has surprised me. The StringUtils split method is in my test case much faster then the Guava Splitter split method.

Test setup is I generate 5000 random strings with a length of 10000. The test strings contains commas to split the strings in the test. I invoke the Apache common spilt method and the Guava Splitter with the same test data, the performance result is shown in the table bellow.

Test Runs 1 2 3 4
Apache Common
StringUtils.split(…)
126 ms 122 ms 121 ms 122 ms
Google Guava
splitter.split(…)
352 ms 350 ms 346 ms 349 ms


Here the source of my simple performance test:
Why
Has anybody an idea why the Guava API in my test is slower then the StringUtils split method? I read that the Guava Splitter performance should be very good. Therefore, I am surprised about the result.

Here the dependencies I have used for the performance test:

Sonntag, 9. September 2012

Equinox CM and ECF inconsistent Behavior

This evening I had a long OSGi debugging session with the Equinox Configuration Admin and ECF based Remote Services implementation. In the end I found out, it was my mistake used configuration admin wrong. And I update this blog post.

But the problem is that the behavior of the configuration admin depends on which bundles calls the createFactoryConfiguration(...) method and this makes debugging hard.

The problem was that when I create the first time a factory configuration via my remote bundle (which is running on the same system local in other OSGi framework), I become a exception. The remote bundle invokes the method "createWall(…)" see the code sample:

When the first caller of this method was the remote bundle I become the following exception (when the second caller of the configuration admin is a local bundle got the same exception, e.g. when a configuration is created via the apache webconsole):

When the same logic is called first time from a local bundle everything works fine. After some time of debugging, I found the issue. The point is not that the bundle is local or remote.

In the implementation of the method "createWall(...)" the Configuration Admin method "createFactoryConfiguration(...)" with location null is used. The JavaDoc of this method says, when this method is called the first time, with location null, then the location of the first bundle is used which register a service.

OSGi Compendium Specification JavaDoc for the createFactoryConfiguration says:
"The Configuration is bound to the location specified. If this location is null it will be bound to the location of the first bundle that registers a Managed Service Factory with a corresponding PID."

In my case the first bundle was sometimes indirect the remote bundle. So I have the problem and become the exception. My fix was to set the location to the bundle location of the bundle which creates the wall configuration, see the code sample:

In end I found out, that the two OSGi frameworks has the same configuration area, the same local directory. Provider an host are running on the same system. It was a coincidence that the fix work. If the PID for the configuration folder was not locked by the other OSGi instance everything works. So in the end I must say it is my mistake because the OSGi instances had the same directory configured as configuration area. But the design that the location depends on the first caller makes debugging crazy. Does anybody know if this is the expected behavior? This is really hard to debug, that the directory where the configuration is stored could depend on the first caller. What is the best practice set the location parameter always?

Freitag, 8. Juni 2012

Groovy Closures and Annotation Parameters

Since Groovy 1.8 there is support to have a closure as a parameter in annotations. A nice example how to use this feature is the GContracts project, a groovy design by contract framework, which use closure annotation parameters, to define pre and post conditions of a method.

The support of closures in annotations provides a simple way to have much more dynamic in annotations. This is cool and provides new areas where you now could use annotations. Here a simple example how a closure as annotation parameter could be used to group properties.


More details about closures in annotation see the groovy 1.8 release notes.

Links: