Test Driven Development with OSGi

Balázs Zsoldos
Original motivation

Deployment time
2 minutes

Internet time
10 minutes
Coding time
Deployment time

Facebook time
“What was I doing?” time
Reduce
deployment
time

v3
“mvn package”
+

copy file

Iteration is faster, but not fast enough (compile + copy)
drop JAR

OR
Drop project

process
“target/classes”
Eclipse
+
maven-bundle-plugin
=
up-to-date “target/classes”
Richconsole deployment
OSGi container

StartLevel 10

Bundle A (startLevel=4)
Bundle B (startLevel=2)

A

StartLevel 2
B
Deployment time reduced

How can we have better quality?
The Three Laws of TDD
1.You are not allowed to write any production code until you have
2.You are not allowed to write more of a unit test than is sufficient

3.You are not allowed to write more production code that is suffici

The Clean Coder (Chapter 5)
External Blockers

External Test Engines
Framework Startup
Blocker

Blueprint
Blocker

JUnit4
TestEngine

Test runner
Blueprint / DS / creation from Acvtivator / ...
Test service
service.id=MyTest
service.testEngine=junit4

Test runner
JUnit4
TestEngine
I do not want to re-run all tests during
development
In development mode only tests with
@TestMethodInDevelopmentMode or
@TestClassInDevelopmentMode runs.
Test Code

Deploy / Run tests

Production code
Test Code

Deploy / Run tests

Production code

What will run the tests on Jenkins?
Maven repository

Get the dist package

eosgi-maven-plugin:dist
- Unpack dist package
- Parse with velocity
- Add the dependencies

File system
Maven repository

Get the dist package

eosgi-maven-plugin:integration-test
- Unpack dist package
- Parse with velocity
- Add the dependencies
- with testrunner
- as symbolic links

Start the container
Collect test results

File system
Maven plugin configuration
<plugin>
<groupId>org.everit.osgi.dev</groupId>
<artifactId>eosgi-maven-plugin</artifactId>
<version>1.1.3-SNAPSHOT</version>
<configuration>
<environments>
<environment>
<id>equinoxtest</id>
<framework>equinox</framework>
</environment>
</environments>
</configuration>
</plugin>

# Default environments in META-INF/eosgi-framework.properties
equinox=org.everit.osgi.dist:eosgi-dist-equinox:3.7.2-v201309190021
equinox-3.7.2=org.everit.osgi.dist:eosgi-dist-equinox:3.7.2-v201309190021
Maven plugin configuration
<plugin>
<groupId>org.everit.osgi.dev</groupId>
<artifactId>eosgi-maven-plugin</artifactId>
<version>1.1.3-SNAPSHOT</version>
<configuration>
<environments>
<environment>
<id>equinoxtest</id>
<framework>equinox</framework>
<vmOptions>
<vmOption>-Xdebug</vmOption>
<vmOption>-Xrunjdwp:server=y,transport=dt_socket,address=4000,suspend=n</vmOption>
</vmOptions>
</environment>
</environments>
</configuration>
</plugin>

<plugin>
<groupId>org.everit.osgi.dev</groupId>
<artifactId>eosgi-maven-plugin</artifactId>
<version>1.1.3-SNAPSHOT</version>
<configuration>
<environments>
<environment>
<id>equinoxtest</id>
<framework>equinox</framework>
<systemProperties>
<myProperty1>myValue1</myProperty1>
<myProperty2>myValue2</myProperty2>
</systemProperties>
</environment>
</environments>
</configuration>
</plugin>
Maven plugin configuration
<plugin>
<groupId>org.everit.osgi.dev</groupId>
<artifactId>eosgi-maven-plugin</artifactId>
<version>1.1.3-SNAPSHOT</version>
<configuration>
<environments>
<environment>
<id>equinoxtest</id>
<framework>equinox</framework>
<timeout>300000</timeout>
<bundleStartLevel>4</bundleStartLevel>
<frameworkStartLevel>4</frameworkStartLevel>
<bundleSettings>
<bundle>
<symbolicName>myBundle</symbolicName>
<version>1.0.0</version>
<startLevel>3</startLevel>
</bundle>
</bundleSettings>
</environment>
</environments>
</configuration>
</plugin>
Maven plugin configuration
<plugin>
<groupId>org.everit.osgi.dev</groupId>
<artifactId>eosgi-maven-plugin</artifactId>
<version>1.1.3-SNAPSHOT</version>
<executions>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
<configuration>
<jacoco>
<includes>org.everit.osgi.servicereference.*</includes>
<excludes>org.everit.osgi.servicereference.tests.*</excludes>
</jacoco>
<environments>
<environment>
<id>equinoxtest</id>
<framework>equinox</framework>
<vmOptions>
<vmOption>-Xdebug</vmOption>
<vmOption>-Xrunjdwp:server=y,transport=dt_socket,address=4000,suspend=n</vmOption>
</vmOptions>
</environment>
</environments>
</configuration>
</execution>
</executions>
</plugin>
100% coverage
Let's see it in practice
Creating your own dist package
●

Look at the sample equinox package

●

Look at the .eosgi.dist.xml file

Look for the XSD in eosgi-maven-plugin sources and
read the documentation
●

●

Velocity variables
– .eosgi.dist.xml
●

●

bundleArtifacts:
List<DistributableBundleArtifact>
environment: EnvironmentConfiguration

– Parseable

files
Thank you

balazs.zsoldos@everit.biz
E-mail:
http://github.com/everit-org
Source:
Maven repo: http://repository.everit.biz/nexus/content/groups/public

Test Driven Development with OSGi - Balázs Zsoldos