ops4j / org.ops4j.pax.exam2

Pax Exam is a testing framework for OSGi
https://ops4j1.jira.com/wiki/spaces/PAXEXAM4/
Apache License 2.0
84 stars 100 forks source link

Configuration Method is called twice when run with maven surefire [PAXEXAM-848] #421

Open ops4j-issues opened 7 years ago

ops4j-issues commented 7 years ago

Christoph Läubrich created PAXEXAM-848

Given a single Test-Class with one @Configuration-method this method is called twice.

PaxExam should only call the Method once and keep it cached then.


Affects: 5.0.0 Votes: 0, Watches: 2

ops4j-issues commented 7 years ago

Toni Menzel commented

I will try to have a look at this tonight.

ops4j-issues commented 7 years ago

Toni Menzel commented

Cannot reproduce in a test like this:

@RunWith(PaxExam.class)
public class ExampleIntegrationTest {

    @Configuration
    public Option[] config() {
        System.out.println("CALL----");
        return options(
                junitBundles()
        );
    }

    @Test
    public void testExample() {
    }

}
ops4j-issues commented 7 years ago

Toni Menzel commented

Christoph Läubrich can you provide an example?

ops4j-issues commented 7 years ago

Christoph Läubrich commented

@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class DoubleTest {

    public DoubleTest() {
        System.out.println("DoubleTest.DoubleTest(): " + getClass().getClassLoader());
    }

    @Configuration
    public Option[] config() {
        System.out.println("DoubleTest.config()");
        return CoreOptions.options(CoreOptions.junitBundles());
    }

    @Test
    public void oneTest() {
        System.out.println("DoubleTest.oneTest()");

    }

    @Test
    public void anotherTest() {
        System.out.println("DoubleTest.anotherTest()");
    }
}

Ouput:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
DoubleTest.DoubleTest(): sun.misc.Launcher$AppClassLoader@75b84c92
47 [main] INFO org.ops4j.pax.exam.junit.DriverExtension - creating PaxExam runner for class org.ops4j.pax.exam.nat.internal.DoubleTest
94 [main] INFO org.ops4j.pax.exam.spi.DefaultExamSystem - Pax Exam System (Version: 5.0.0-SNAPSHOT) created.
DoubleTest.config()
594 [main] INFO org.ops4j.pax.exam.junit.DriverExtension - creating PaxExam runner for class org.ops4j.pax.exam.nat.internal.DoubleTest
Running org.ops4j.pax.exam.nat.internal.DoubleTest
DoubleTest.DoubleTest(): sun.misc.Launcher$AppClassLoader@75b84c92
DoubleTest.config()
[org.ops4j.pax.swissbox.extender.BundleWatcher] : Creating bundle watcher with scanner [org.ops4j.pax.swissbox.extender.BundleManifestScanner@5f6d23b6]...
[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.eclipse.osgi]
[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.exam]
[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.exam.extender.service]
[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [osgi.cmpn]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Enabling SLF4J API support.
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Enabling Jakarta Commons Logging API support.
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Enabling Log4J API support.
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Enabling Avalon Logger API support.
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Enabling JULI Logger API support.
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Enabling Log4J v2 API support. Ignored FQCN: org.apache.logging.log4j.spi.AbstractLogger
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.logging.pax-logging-api]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.base]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.swissbox.core]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.swissbox.extender]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.swissbox.framework]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.swissbox.lifecycle]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.swissbox.tracker]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.apache.geronimo.specs.geronimo-atinject_1.0_spec]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.tipi.junit]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.tipi.hamcrest.core]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [org.ops4j.pax.exam.invoker.junit]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Scanning bundle [PAXEXAM-PROBE-805571fe-9eb1-4f0a-8d02-f42f5e659418]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Found resources [ManifestEntry{ key=PaxExam-Executable, value= }]
org.ops4j.pax.exam.invoker.junit[org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner] : running oneTest in reactor
DoubleTest.DoubleTest(): org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@223f3642[PAXEXAM-PROBE-805571fe-9eb1-4f0a-8d02-f42f5e659418:0.0.0(id=15)]
DoubleTest.oneTest()
org.ops4j.pax.exam.invoker.junit[org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner] : running anotherTest in reactor
DoubleTest.DoubleTest(): org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@223f3642[PAXEXAM-PROBE-805571fe-9eb1-4f0a-8d02-f42f5e659418:0.0.0(id=15)]
DoubleTest.anotherTest()
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [PAXEXAM-PROBE-805571fe-9eb1-4f0a-8d02-f42f5e659418]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Un-registering [ManifestEntry{ key=PaxExam-Executable, value= }]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.exam.raw.extender.intern.TestBundleObserver] : Unregistered ProbeInvoker for bundle PAXEXAM-PROBE-805571fe-9eb1-4f0a-8d02-f42f5e659418_0.0.0 [15]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.exam.invoker.junit]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.tipi.hamcrest.core]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.tipi.junit]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.apache.geronimo.specs.geronimo-atinject_1.0_spec]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.swissbox.tracker]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.swissbox.lifecycle]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.swissbox.framework]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.swissbox.extender]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.swissbox.core]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.base]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Disabling SLF4J API support.
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Disabling Jakarta Commons Logging API support.
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Disabling Log4J API support.
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Disabling Avalon Logger API support.
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Disabling JULI Logger API support.
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.logging.internal.Activator] : Disabling Log4J v2 API support. Ignored FQCN: org.apache.logging.log4j.spi.AbstractLogger
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.logging.pax-logging-api]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [osgi.cmpn]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.eclipse.osgi]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.exam]
org.ops4j.pax.logging.pax-logging-api[org.ops4j.pax.swissbox.extender.BundleWatcher] : Releasing bundle [org.ops4j.pax.exam.extender.service]
2389 [main] INFO org.ops4j.pax.exam.spi.reactors.ReactorManager - suite finished
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.795 sec - in org.ops4j.pax.exam.nat.internal.DoubleTest

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

Called with mvn clean install, it creates the test class twice and calls option method twice.....

ops4j-issues commented 7 years ago

Toni Menzel commented

ah two tests.. yes for sure. Thats a simplification when there was a possibility in very early paxexam versions that you could have had many Configurations and many Tests and there was a way to map them.
I think now its only possible to have exactly one configuration per Test Class, so.. yes there might be room for optimisation. Still, Configurations should be only containers of value objects, where the "resolve" phase should only be done once per container (meaning when configuration is turned into actual container instance).
But this is already not true anymore with the Bndtools Options, who use Bnd Operations like "resolve" upon configuration, which is considered to be a heavyweight operation.

Yes you are right, we should think about caching. Still i'd consider this an Improvement and not a Bug. (because it was intended behaviour early on)

ops4j-issues commented 7 years ago

Christoph Läubrich commented

Okay, it seems this only happens when run from maven surefire (it dosen't matter if one or more methods), running from eclipse it is only called once...

ops4j-issues commented 7 years ago

Christoph Läubrich commented

Toni Menzel One idea for exam 5 (related to multi-container tests) is to offload as much work as possible into the "configuration-phase" so

  1. containers can start/restart quickly (e.g. with @PerMethod strategy the container must otherwise resolve the same req. over and over again)
  2. we can provide generic "forked" support (i'm currently evaluating how this can be done nicely)
  3. We cut down dependecies that must be installed in the test-container, e.g. currently it seems not be possible to use the wrap-protocoll in karaf OotB because the time the test-features are installed the protcoll is not avaiable since it reuires a running OSGi-Framework (as well as some other dependecies like osgi url service)

This also would help in your suggestion of making the resolver process pluggable so we can have maven, gradle, ivy, ... or a combination of all witout pulling in all dependencies.