This is an extension for the osgi-test library that provides an easy way to fire up an embedded framework.
To use it simply add the follwoing dependency to your pom:
<dependency>
<groupId>de.laeubisoft</groupId>
<artifactId>osgi-test-framework</artifactId>
<version>0.0.1</version>
</dependency>
org.osgi.test
itself assumes running inside an OSGI Framework and you can setup one
using BND, Tycho, Pax Exam or other techniques but this often requires carefull setup
and often mean all your tests run in the same setup or you spread them over different
test-artifacts.
With the FrameworkExtension
it is possible to start a so called Connect-Framework
that is directly feed from the classpath of your test, this makes it suitable for test-cases
where you have a small set of bundles (even though the number is not limited in any
way), want to run different configurations or run directly from your current module
(e.g. the usual maven setup where the test-code is next to your code and executed by
maven-surefire as part of that build).
The framework is configured using annotations described below.
Just in cases where you only need your test and will setup everything else using org.osgi.test
(e.g. installing other bundles, register
services, see below) then you can still use this standalone.
@ExtendWith(FrameworkExtension.class)
public class MyImplTest {
... your test code here ...
}
Often one wants additional stuff, so you can load it from the classpath of your test (e.g. adding it as a maven dependency):
@WithBundle("api-bundle")
@WithBundle("impl-bundle")
public class MyImplTest {
... your test code here ...
}
you simply pass the bundle name of the bundle and you are done.
If you like, you can even mark your bundle as beeing started (usually desired if the contain activators or DS components):
@WithBundle("api-bundle")
@WithBundle(value = "impl-bundle", start = true)
public class MyImplTest {
... your test code here ...
}
All bundles by default share the classloader with your test-probe, this is to ensure you can use the same classes in your test as in your bundle. If you like, you can mark a bundle as isolated then it will get an own (OSGi managed) classloader:
@WithBundle("api-bundle")
@WithBundle(value = "impl-bundle", isolated = true)
public class MyImplTest {
... your test code here ...
}
You usually want API interfaces you test to be shared, but implementation bundles you only access indirectly through a (shared) service interface are good candidates to use isolated classloaders.
In most cases your bundles under test will require additional packages (e.g. from APIs) and you can of course simply provide the API bundle as well to fullfill this requirements but depending how good you shape your system (and how good shaped the libraries are you are using), this can become a headache as those bundles might require additional packages or capabilities. You maybe simply want to restrict the set of bundles to the absoloute minimum.
As an alternative you can export arbitrary packages from your test-probe, this could also be used to make some things aviable from within your test-probe even though it is not a bundle at all, the package will simply be feed from your test classpath:
@WithExportedPackage("my.extra.package;version=\"1.0.0\"")
public class MyImplTest {
... your test code here ...
}
An OSGi framework is configured using framework properties, you can define additional ones in the follwoing way:
@WithFrameworkProperty(property = Constants.FRAMEWORK_BEGINNING_STARTLEVEL, value = "6")
public class MyImplTest {
... your test code here ...
}
For advanced use cases you can get the running framework injected into your test:
public class MyImplTest {
@InjectFramework
Framework framework;
... your test code here ...
}
Sometimes things getting wrong, or you even want to assert that something has gone wrong or simply need to inspect the framework state.
The extension provides some usefull methods to give you insights into the state of your framework.
The framework register a service FrameworkEvents
you can fetch to assert certain
things about framework events:
@InjectService //this is from the osgi.test library!
FrameworkEvents frameworkEvents;
@BeforeEach
public void checkService() {
frameworkEvents.assertErrorFree();
}
... your test code here ...
}
The FrameworkExtension
provides some useful methods to query the framework state
public class MyImplTest {
@BeforeEach
public void printFrameworkInfo(@InjectFramework Framework framework) {
FrameworkExtension.printBundles(framework, System.out::println);
}
... your test code here ...
}
There are some common tasks and configuration that might be repetive to many tests. For this the extension already provides some common composite annotations.
@UseFelixServiceComponentRuntime
public class MyImplTest {
... your test code here ...
}
For further support of testing OSGi items itself, take a look at https://github.com/osgi/osgi-test/tree/main/org.osgi.test.junit5