diff --git a/maven/bnd-testing-maven-plugin/README.md b/maven/bnd-testing-maven-plugin/README.md
index e8be59e112..85a4ef6815 100644
--- a/maven/bnd-testing-maven-plugin/README.md
+++ b/maven/bnd-testing-maven-plugin/README.md
@@ -67,6 +67,7 @@ An *implicit repository* containing the project artifact and project dependencie
|`reportsDir` | The output directory for test reports. A subdirectory of `${bndrun}` will be created for each bndrun file supplied. _Defaults to `${project.build.directory}/test-reports`._|
|`cwd` | The current working directory of the test process. A subdirectory of `${bndrun}` will be created for each bndrun file supplied. _Defaults to `${project.build.directory}/test`._|
|`skipTests` OR `maven.test.skip`| Does not execute any tests. Used from the command line via `-D`. _Defaults to `false`._|
+|`testFailureIgnore`| Does not fail mojo if any tests fail. Used from the command line via `-Dbnd.testing.failure.ignore=true`. _Defaults to `false`._|
|`testingSelect` | A file path to a test file, overrides anything else. _Defaults to `${testing.select}`._ Override with property `testing.select`.|
|`testing` | A glob expression that is matched against the file name of the listed bndrun files. _Defaults to `${testing}`._ Override with property `testing`.|
|`test` | A comma separated list of the fully qualified names of test classes to run. If not set, or empty, then all the test classes listed in the `Test-Classes` manifest header are run. Use a colon (:) to specify a test method to run on the specified test class. Override with property `test`.|
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-failure/bnd.bnd b/maven/bnd-testing-maven-plugin/src/it/test-failure/bnd.bnd
new file mode 100644
index 0000000000..a8fdbe509b
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-failure/bnd.bnd
@@ -0,0 +1 @@
+Test-Cases: ${classes;CONCRETE;PUBLIC;NAMED;*Test}
\ No newline at end of file
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-failure/invoker.properties b/maven/bnd-testing-maven-plugin/src/it/test-failure/invoker.properties
new file mode 100644
index 0000000000..05974c3823
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-failure/invoker.properties
@@ -0,0 +1,10 @@
+invoker.goals=--no-transfer-progress integration-test
+
+# Run mvn with --debug for debug logging
+#invoker.debug=true
+
+# The expected result of the build, possible values are "success" (default) and "failure"
+invoker.buildResult=failure
+
+# Run mvn in debugging mode and wait for a debugger to attach
+#invoker.environmentVariables.MAVEN_DEBUG_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-failure/pom.xml b/maven/bnd-testing-maven-plugin/src/it/test-failure/pom.xml
new file mode 100644
index 0000000000..d3bc882549
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-failure/pom.xml
@@ -0,0 +1,49 @@
+
+ 4.0.0
+
+
+ biz.aQute.bnd-test
+ test
+ 0.0.1
+ ../parent
+
+
+ biz.aQute.bnd-test
+ test-failure
+ jar
+
+
+
+ org.osgi
+ osgi.core
+
+
+ biz.aQute.bnd
+ biz.aQute.junit
+
+
+ org.apache.felix
+ org.apache.felix.framework
+ runtime
+
+
+
+
+
+
+ biz.aQute.bnd
+ bnd-testing-maven-plugin
+
+
+ biz.aQute.bnd
+ bnd-indexer-maven-plugin
+
+
+ biz.aQute.bnd
+ bnd-maven-plugin
+
+
+
+
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-failure/src/main/java/bnd/test/FailingBndTest.java b/maven/bnd-testing-maven-plugin/src/it/test-failure/src/main/java/bnd/test/FailingBndTest.java
new file mode 100644
index 0000000000..d203e083ce
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-failure/src/main/java/bnd/test/FailingBndTest.java
@@ -0,0 +1,15 @@
+package bnd.test;
+
+import static org.junit.Assert.assertNull;
+import static org.osgi.framework.FrameworkUtil.getBundle;
+
+import org.junit.Test;
+
+public class FailingBndTest {
+
+ @Test
+ public void test() {
+ assertNull(getBundle(FailingBndTest.class).getBundleContext());
+ }
+
+}
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-failure/src/main/java/bnd/test/SimpleBndTest.java b/maven/bnd-testing-maven-plugin/src/it/test-failure/src/main/java/bnd/test/SimpleBndTest.java
new file mode 100644
index 0000000000..98d4b7d3bb
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-failure/src/main/java/bnd/test/SimpleBndTest.java
@@ -0,0 +1,15 @@
+package bnd.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.osgi.framework.FrameworkUtil.getBundle;
+
+import org.junit.Test;
+
+public class SimpleBndTest {
+
+ @Test
+ public void test() {
+ assertNotNull(getBundle(SimpleBndTest.class).getBundleContext());
+ }
+
+}
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-failure/test.bndrun b/maven/bnd-testing-maven-plugin/src/it/test-failure/test.bndrun
new file mode 100644
index 0000000000..ed988cbab8
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-failure/test.bndrun
@@ -0,0 +1,6 @@
+-standalone: target/index.xml
+
+-runfw: org.apache.felix.framework;version='[5.6.10,5.6.10]'
+-runee: JavaSE-1.8
+
+-runbundles: biz.aQute.junit, test-failure;version='[0.0.1,0.0.2)'
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/bnd.bnd b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/bnd.bnd
new file mode 100644
index 0000000000..a8fdbe509b
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/bnd.bnd
@@ -0,0 +1 @@
+Test-Cases: ${classes;CONCRETE;PUBLIC;NAMED;*Test}
\ No newline at end of file
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/invoker.properties b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/invoker.properties
new file mode 100644
index 0000000000..9c38ea264b
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/invoker.properties
@@ -0,0 +1,7 @@
+invoker.goals=--no-transfer-progress integration-test
+
+# Run mvn with --debug for debug logging
+#invoker.debug=true
+
+# Run mvn in debugging mode and wait for a debugger to attach
+#invoker.environmentVariables.MAVEN_DEBUG_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/pom.xml b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/pom.xml
new file mode 100644
index 0000000000..38e8bd1212
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/pom.xml
@@ -0,0 +1,52 @@
+
+ 4.0.0
+
+
+ biz.aQute.bnd-test
+ test
+ 0.0.1
+ ../parent
+
+
+ biz.aQute.bnd-test
+ test-ignore-failure
+ jar
+
+
+
+ org.osgi
+ osgi.core
+
+
+ biz.aQute.bnd
+ biz.aQute.junit
+
+
+ org.apache.felix
+ org.apache.felix.framework
+ runtime
+
+
+
+
+
+
+ biz.aQute.bnd
+ bnd-testing-maven-plugin
+
+ true
+
+
+
+ biz.aQute.bnd
+ bnd-indexer-maven-plugin
+
+
+ biz.aQute.bnd
+ bnd-maven-plugin
+
+
+
+
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/postbuild.groovy b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/postbuild.groovy
new file mode 100644
index 0000000000..9c22ffa4f2
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/postbuild.groovy
@@ -0,0 +1,9 @@
+import groovy.xml.XmlSlurper
+
+File testsuite_xml = new File(basedir, "target/test-reports/test/TEST-test-ignore-failure-0.0.1.xml")
+assert testsuite_xml.isFile();
+testsuite = new XmlSlurper().parse(testsuite_xml)
+assert testsuite.@name == "test.test-ignore-failure"
+assert testsuite.@tests == 2
+assert testsuite.@errors == 1
+assert testsuite.@failures == 0
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/src/main/java/bnd/test/FailingBndTest.java b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/src/main/java/bnd/test/FailingBndTest.java
new file mode 100644
index 0000000000..d203e083ce
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/src/main/java/bnd/test/FailingBndTest.java
@@ -0,0 +1,15 @@
+package bnd.test;
+
+import static org.junit.Assert.assertNull;
+import static org.osgi.framework.FrameworkUtil.getBundle;
+
+import org.junit.Test;
+
+public class FailingBndTest {
+
+ @Test
+ public void test() {
+ assertNull(getBundle(FailingBndTest.class).getBundleContext());
+ }
+
+}
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/src/main/java/bnd/test/SimpleBndTest.java b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/src/main/java/bnd/test/SimpleBndTest.java
new file mode 100644
index 0000000000..98d4b7d3bb
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/src/main/java/bnd/test/SimpleBndTest.java
@@ -0,0 +1,15 @@
+package bnd.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.osgi.framework.FrameworkUtil.getBundle;
+
+import org.junit.Test;
+
+public class SimpleBndTest {
+
+ @Test
+ public void test() {
+ assertNotNull(getBundle(SimpleBndTest.class).getBundleContext());
+ }
+
+}
diff --git a/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/test.bndrun b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/test.bndrun
new file mode 100644
index 0000000000..ad1187a6f4
--- /dev/null
+++ b/maven/bnd-testing-maven-plugin/src/it/test-ignore-failure/test.bndrun
@@ -0,0 +1,6 @@
+-standalone: target/index.xml
+
+-runfw: org.apache.felix.framework;version='[5.6.10,5.6.10]'
+-runee: JavaSE-1.8
+
+-runbundles: biz.aQute.junit, test-ignore-failure;version='[0.0.1,0.0.2)'
diff --git a/maven/bnd-testing-maven-plugin/src/main/java/aQute/bnd/maven/testing/plugin/TestingMojo.java b/maven/bnd-testing-maven-plugin/src/main/java/aQute/bnd/maven/testing/plugin/TestingMojo.java
index fc8fceca74..bbecfffd91 100644
--- a/maven/bnd-testing-maven-plugin/src/main/java/aQute/bnd/maven/testing/plugin/TestingMojo.java
+++ b/maven/bnd-testing-maven-plugin/src/main/java/aQute/bnd/maven/testing/plugin/TestingMojo.java
@@ -56,6 +56,9 @@ public class TestingMojo extends AbstractMojo {
@Parameter(property = "maven.test.skip", defaultValue = "false")
private boolean skip;
+ @Parameter(property = "bnd.testing.failure.ignore", defaultValue = "false")
+ private boolean testFailureIgnore;
+
@Parameter
private Bndruns bndruns = new Bndruns();
@@ -160,8 +163,9 @@ public void execute() throws MojoExecutionException, MojoFailureException {
throw new MojoExecutionException(e.getMessage(), e);
}
- if (errors > 0)
+ if (!isTestFailureIgnore() && (errors > 0)) {
throw new MojoFailureException(errors + " errors found");
+ }
}
private List getTests() {
@@ -173,6 +177,10 @@ private List getTests() {
return Strings.split(test);
}
+ private boolean isTestFailureIgnore() {
+ return testFailureIgnore;
+ }
+
private Operation getOperation() {
return (file, bndrun, run) -> {
if (!glob.matcher(file.getName())