Bug 8415 related: Make TestBundleDiag a lib 50/57650/4
authorMichael Vorburger <vorburger@redhat.com>
Mon, 22 May 2017 22:04:07 +0000 (00:04 +0200)
committerRobert Varga <nite@hq.sk>
Mon, 29 May 2017 11:40:42 +0000 (11:40 +0000)
This is the alternative to c/56848 requested by Robert.

We're changing this so that we can consume bundles-test-lib in the
infrautils.ready implementation as a service for both Karaf v3 and v4.

As a (VERY nice!) side effect, this allows us to remove the duplicated
Java code we had between bundles-test and bundles4-test.  That was,
originally, intended to only be like it still is for a short while, but
with the Karaf 4 situation being what it is, this code duplication is
still there - and the respective code has started diverging a bit; so
unifying this in the new bundles-test-lib is great.

Change-Id: I0fd2c954fdc4a6c84505bef51729d15e4ba2888c
Signed-off-by: Michael Vorburger <vorburger@redhat.com>
28 files changed:
bundles-test-lib/pom.xml [new file with mode: 0644]
bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/BundleDiagInfos.java [new file with mode: 0644]
bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/BundleDiagInfosImpl.java [moved from bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/BundleDiagInfos.java with 92% similarity]
bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/BundleServiceSummaryMatcher.java [moved from bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/BundleServiceSummaryMatcher.java with 70% similarity]
bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/ServiceReferenceUtil.java [moved from bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtil.java with 90% similarity]
bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/SystemState.java [moved from bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/SystemState.java with 91% similarity]
bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/SystemStateFailureException.java [new file with mode: 0644]
bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/TestBundleDiag.java [moved from bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/TestBundleDiag.java with 83% similarity]
bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/package-info.java [moved from bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/package-info.java with 86% similarity]
bundles-test-lib/src/test/java/org/opendaylight/odlparent/bundlestest/lib/ServiceReferenceUtilTest.java [moved from bundles-test/src/test/java/org/opendaylight/odlparent/bundlestest/ServiceReferenceUtilTest.java with 94% similarity]
bundles-test/pom.xml
bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/BundleDiagInfos.java [deleted file]
bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/BundleServiceSummaryMatcher.java [deleted file]
bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/ServiceReferenceUtil.java [deleted file]
bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/SystemState.java [deleted file]
bundles4-test/pom.xml
bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/SystemStateFailureException.java
bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/TestBundleDiag.java
bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/package-info.java [deleted file]
bundles4-test/src/test/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtilTest.java [deleted file]
feature-repo-parent/pom.xml
feature3-repo-parent/pom.xml
features-test/pom.xml
features-test/src/main/java/org/opendaylight/odlparent/featuretest/SingleFeatureTest.java
features4-test/pom.xml
features4-test/src/main/java/org/opendaylight/odlparent/featuretest/SingleFeatureTest.java
pom.xml
single-feature-parent/pom.xml

diff --git a/bundles-test-lib/pom.xml b/bundles-test-lib/pom.xml
new file mode 100644 (file)
index 0000000..fe02b84
--- /dev/null
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent</artifactId>
+    <version>1.9.0-SNAPSHOT</version>
+    <relativePath>../odlparent</relativePath>
+  </parent>
+
+  <artifactId>bundles-test-lib</artifactId>
+  <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.karaf.bundle</groupId>
+      <artifactId>org.apache.karaf.bundle.core</artifactId>
+      <!-- karaf.version & karaf4.version are API compatible (for karaf.bundle.core) -->
+      <version>${karaf.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.awaitility</groupId>
+      <artifactId>awaitility</artifactId>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>cglib</groupId>
+          <artifactId>cglib-nodep</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.objenesis</groupId>
+          <artifactId>objenesis</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <!-- BEWARE of adding additional dependencies here...
+         It will cause weird issues e.g. in integration/distribution/features/repos/distribution -->
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+          <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <configuration>
+          <failOnError>true</failOnError>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <!--
+    Maven Site Configuration
+
+    The following configuration is necessary for maven-site-plugin to
+    correctly identify the correct deployment path for OpenDaylight Maven
+    sites.
+  -->
+  <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+  <distributionManagement>
+    <site>
+      <id>opendaylight-site</id>
+      <url>${nexus.site.url}/${project.artifactId}/</url>
+    </site>
+  </distributionManagement>
+
+</project>
diff --git a/bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/BundleDiagInfos.java b/bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/BundleDiagInfos.java
new file mode 100644 (file)
index 0000000..5610d91
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.odlparent.bundlestest.lib;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * System readiness diagnostic summary information.
+ *
+ * @author Michael Vorburger.ch
+ */
+public interface BundleDiagInfos extends Serializable {
+
+    SystemState getSystemState();
+
+    String getFullDiagnosticText();
+
+    String getSummaryText();
+
+    List<String> getNokBundleStateInfoTexts();
+
+    List<String> getOkBundleStateInfoTexts();
+
+    List<String> getWhitelistedBundleStateInfoTexts();
+
+}
\ No newline at end of file
similarity index 92%
rename from bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/BundleDiagInfos.java
rename to bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/BundleDiagInfosImpl.java
index 7d55f74845fe0791152f02a6c4e04b96a9463440..991db10108f17244b4918d9b28b83445ed9705ec 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.odlparent.bundles4test;
+package org.opendaylight.odlparent.bundlestest.lib;
 
 import static org.apache.karaf.bundle.core.BundleState.Active;
 import static org.apache.karaf.bundle.core.BundleState.Installed;
@@ -24,11 +24,12 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 
 /**
- * System readiness diagnostic summary information.
+ * {@link BundleDiagInfos} implementation.
  *
  * @author Michael Vorburger.ch
  */
-public final class BundleDiagInfos implements Serializable {
+// intentionally just package-local
+final class BundleDiagInfosImpl implements BundleDiagInfos, Serializable {
     private static final long serialVersionUID = 1L;
 
     private static final Map<String, BundleState> WHITELISTED_BUNDLES;
@@ -43,7 +44,7 @@ public final class BundleDiagInfos implements Serializable {
     private final List<String> whitelistedBundleStateInfoTexts;
     private final Map<BundleState, Integer> bundleStatesCounters;
 
-    private BundleDiagInfos(List<String> okBundleStateInfoTexts, List<String> nokBundleStateInfoTexts,
+    private BundleDiagInfosImpl(List<String> okBundleStateInfoTexts, List<String> nokBundleStateInfoTexts,
             List<String> whitelistedBundleStateInfoTexts, Map<BundleState, Integer> bundleStatesCounters) {
         this.okBundleStateInfoTexts = immutableCopyOf(okBundleStateInfoTexts);
         this.nokBundleStateInfoTexts = immutableCopyOf(nokBundleStateInfoTexts);
@@ -51,7 +52,7 @@ public final class BundleDiagInfos implements Serializable {
         this.bundleStatesCounters = immutableCopyOf(bundleStatesCounters);
     }
 
-    public static BundleDiagInfos forContext(BundleContext bundleContext, BundleService bundleService) {
+    public static BundleDiagInfosImpl forContext(BundleContext bundleContext, BundleService bundleService) {
         List<String> okBundleStateInfoTexts = new ArrayList<>();
         List<String> nokBundleStateInfoTexts = new ArrayList<>();
         List<String> whitelistedBundleStateInfoTexts = new ArrayList<>();
@@ -96,7 +97,7 @@ public final class BundleDiagInfos implements Serializable {
             }
         }
 
-        return new BundleDiagInfos(okBundleStateInfoTexts, nokBundleStateInfoTexts,
+        return new BundleDiagInfosImpl(okBundleStateInfoTexts, nokBundleStateInfoTexts,
                 whitelistedBundleStateInfoTexts, bundleStatesCounters);
     }
 
@@ -119,6 +120,7 @@ public final class BundleDiagInfos implements Serializable {
         }
     }
 
+    @Override
     public SystemState getSystemState() {
         if (bundleStatesCounters.get(BundleState.Failure) > 0) {
             return SystemState.Failure;
@@ -139,6 +141,7 @@ public final class BundleDiagInfos implements Serializable {
         }
     }
 
+    @Override
     public String getFullDiagnosticText() {
         StringBuilder sb = new StringBuilder(getSummaryText());
         int failureNumber = 1;
@@ -151,18 +154,22 @@ public final class BundleDiagInfos implements Serializable {
         return sb.toString();
     }
 
+    @Override
     public String getSummaryText() {
         return "diag: " + getSystemState() + " " + bundleStatesCounters.toString();
     }
 
+    @Override
     public List<String> getNokBundleStateInfoTexts() {
         return immutableCopyOf(nokBundleStateInfoTexts);
     }
 
+    @Override
     public List<String> getOkBundleStateInfoTexts() {
         return immutableCopyOf(okBundleStateInfoTexts);
     }
 
+    @Override
     public List<String> getWhitelistedBundleStateInfoTexts() {
         return immutableCopyOf(whitelistedBundleStateInfoTexts);
     }
similarity index 70%
rename from bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/BundleServiceSummaryMatcher.java
rename to bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/BundleServiceSummaryMatcher.java
index 6facb4f1b3b1303654249adc49d89a95792b57d0..dc6c1d94810d9710cf7b2ae1f9dddd0e18351783 100644 (file)
@@ -5,26 +5,26 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.odlparent.bundles4test;
+package org.opendaylight.odlparent.bundlestest.lib;
 
-import static org.opendaylight.odlparent.bundles4test.SystemState.Active;
-import static org.opendaylight.odlparent.bundles4test.SystemState.Failure;
-import static org.opendaylight.odlparent.bundles4test.SystemState.Stopping;
+import static org.opendaylight.odlparent.bundlestest.lib.SystemState.Active;
+import static org.opendaylight.odlparent.bundlestest.lib.SystemState.Failure;
+import static org.opendaylight.odlparent.bundlestest.lib.SystemState.Stopping;
 
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 
 /**
- * Hamcrest Matcher for {@link BundleDiagInfos}.
+ * Hamcrest Matcher for BundleDiagInfosImpl.
  *
  * @author Michael Vorburger.ch
  */
 // intentionally just package-local
-class BundleServiceSummaryMatcher extends BaseMatcher<BundleDiagInfos> {
+class BundleServiceSummaryMatcher extends BaseMatcher<BundleDiagInfosImpl> {
 
     @Override
     public boolean matches(Object item) {
-        SystemState systemState = ((BundleDiagInfos) item).getSystemState();
+        SystemState systemState = ((BundleDiagInfosImpl) item).getSystemState();
         return systemState.equals(Active) || systemState.equals(Stopping) || systemState.equals(Failure);
     }
 
similarity index 90%
rename from bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtil.java
rename to bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/ServiceReferenceUtil.java
index 9b9ab2e9de7293560bd5c44157f6882d403e1fad..9370050639b1c41fc2750c66ef2eb93be415c494 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.odlparent.bundles4test;
+package org.opendaylight.odlparent.bundlestest.lib;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -15,8 +15,6 @@ import java.util.Map;
 import java.util.stream.Collectors;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Utilities for OSGi's {@link ServiceReference}.
@@ -26,8 +24,6 @@ import org.slf4j.LoggerFactory;
 // intentionally just package-local
 class ServiceReferenceUtil {
 
-    private static final Logger LOG = LoggerFactory.getLogger(ServiceReferenceUtil.class);
-
     public Map<String, Object> getProperties(ServiceReference<?> serviceRef) {
         String[] propertyKeys = serviceRef.getPropertyKeys();
         Map<String, Object> properties = new HashMap<>(propertyKeys.length);
similarity index 91%
rename from bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/SystemState.java
rename to bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/SystemState.java
index 47a331423233f20b3c1135868ab54ec03b9222f3..c228f987e1d13ae4211d82aa2873b710b188f178 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.odlparent.bundles4test;
+package org.opendaylight.odlparent.bundlestest.lib;
 
 import org.apache.karaf.bundle.core.BundleState;
 
diff --git a/bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/SystemStateFailureException.java b/bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/SystemStateFailureException.java
new file mode 100644 (file)
index 0000000..b1ff26d
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.odlparent.bundlestest.lib;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+
+/**
+ * Exception thrown (only) by
+ * {@link TestBundleDiag#checkBundleDiagInfos(long, java.util.concurrent.TimeUnit)}
+ * if there are any OSGi bundles that failed to start.  This is based on not only {@link Bundle#getState()}'s
+ * {@link Bundle#ACTIVE}, but also DI wiring systems such as blueprint containers.  The Exceptions' message
+ * will likely contain a longer multi-line String with extensive technical details including all failed
+ * bundles' states, detailed technical information related to OSGi bundle and blueprint resolution,
+ * and possibly exceptions incl. stack traces thrown by {@link BundleActivator} start() methods and
+ * dependency injection object wiring {@literal @}PostConstruct "init" type methods.
+ *
+ * @author Michael Vorburger.ch
+ */
+public class SystemStateFailureException extends Exception {
+    private static final long serialVersionUID = 1L;
+
+    private final BundleDiagInfos bundleDiagInfos;
+
+    public SystemStateFailureException(String message, BundleDiagInfos bundleDiagInfos, Throwable cause) {
+        super(getExtendedMessage(message, bundleDiagInfos), cause);
+        this.bundleDiagInfos = bundleDiagInfos;
+    }
+
+    public SystemStateFailureException(String message, BundleDiagInfos bundleDiagInfos) {
+        super(getExtendedMessage(message, bundleDiagInfos));
+        this.bundleDiagInfos = bundleDiagInfos;
+    }
+
+    private static String getExtendedMessage(String message, BundleDiagInfos bundleDiagInfos) {
+        return message + "\n" + bundleDiagInfos.getFullDiagnosticText();
+    }
+
+    public BundleDiagInfos getBundleDiagInfos() {
+        return bundleDiagInfos;
+    }
+}
similarity index 83%
rename from bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/TestBundleDiag.java
rename to bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/TestBundleDiag.java
index 56b2f38da34bfef75994ab728267e142f48a8a25..775fafd5563d02d83380a364549c1b0fd1ee8aaf 100644 (file)
@@ -5,11 +5,10 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.odlparent.bundlestest;
+package org.opendaylight.odlparent.bundlestest.lib;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.junit.Assert.fail;
 
 import java.util.concurrent.TimeUnit;
 import org.apache.karaf.bundle.core.BundleService;
@@ -23,7 +22,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Utility to verify bundle diagnostic state from OSGi integration tests.
+ * Utility to verify bundle diagnostic state.
  *
  * @author Michael Vorburger.ch
  */
@@ -40,7 +39,8 @@ public class TestBundleDiag {
     }
 
     /**
-     * Does the equivalent of the "diag" CLI command, and fails the test if anything incl. bundle wiring is NOK.
+     * Does something similar to Karaf's "diag" CLI command,
+     * and throws a {@link SystemStateFailureException} if anything incl. bundle wiring is NOK.
      *
      * <p>The implementation is based on Karaf's BundleService, and not the BundleStateService,
      * because each Karaf supported DI system (such as Blueprint and Declarative Services, see String constants
@@ -49,7 +49,8 @@ public class TestBundleDiag {
      *
      * @author Michael Vorburger, based on guidance from Christian Schneider
      */
-    public void checkBundleDiagInfos(long timeout, TimeUnit timeoutUnit) {
+    public void checkBundleDiagInfos(long timeout, TimeUnit timeoutUnit) throws SystemStateFailureException {
+        LOG.info("checkBundleDiagInfos() started...");
         try {
             Awaitility.await("checkBundleDiagInfos")
                 .pollDelay(0, MILLISECONDS)
@@ -58,17 +59,17 @@ public class TestBundleDiag {
                     .conditionEvaluationListener(
                         condition -> LOG.info("checkBundleDiagInfos: Elapsed time {}s, remaining time {}s, {}",
                             condition.getElapsedTimeInMS() / 1000, condition.getRemainingTimeInMS() / 1000,
-                            ((BundleDiagInfos) condition.getValue()).getFullDiagnosticText()))
+                            ((BundleDiagInfosImpl) condition.getValue()).getFullDiagnosticText()))
                     .until(this::getBundleDiagInfos, new BundleServiceSummaryMatcher());
 
             // If we're here then either BundleServiceSummaryMatcher quit because of Active, Failure or Stopping..
-            BundleDiagInfos bundleInfos = getBundleDiagInfos();
+            BundleDiagInfosImpl bundleInfos = getBundleDiagInfos();
             SystemState systemState = bundleInfos.getSystemState();
             if (systemState.equals(SystemState.Failure) || systemState.equals(SystemState.Stopping)) {
                 LOG.error("diag failure; BundleService reports bundle(s) which failed or are already stopping"
                         + " (details in following INFO and ERROR log messages...)");
                 logBundleDiagInfos(bundleInfos);
-                fail(bundleInfos.getFullDiagnosticText());
+                throw new SystemStateFailureException("diag failed; some bundles failed to start", bundleInfos);
 
             } else {
                 // Inform the developer of the green SystemState.Active
@@ -80,13 +81,13 @@ public class TestBundleDiag {
             // typically due to bundles still in BundleState GracePeriod or Waiting
             LOG.error("diag failure; BundleService reports bundle(s) which are still not active"
                     + " (details in following INFO and ERROR log messages...)");
-            BundleDiagInfos bundleInfos = getBundleDiagInfos();
+            BundleDiagInfosImpl bundleInfos = getBundleDiagInfos();
             logBundleDiagInfos(bundleInfos);
-            throw e; // fail the test!
+            throw new SystemStateFailureException("diag timeout; some bundles are still not active:", bundleInfos, e);
         }
     }
 
-    private void logBundleDiagInfos(BundleDiagInfos bundleInfos) {
+    private void logBundleDiagInfos(BundleDiagInfosImpl bundleInfos) {
         try {
             logOSGiServices();
         } catch (IllegalStateException e) {
@@ -103,8 +104,8 @@ public class TestBundleDiag {
         }
     }
 
-    private BundleDiagInfos getBundleDiagInfos() {
-        return BundleDiagInfos.forContext(bundleContext, bundleService);
+    private BundleDiagInfosImpl getBundleDiagInfos() {
+        return BundleDiagInfosImpl.forContext(bundleContext, bundleService);
     }
 
     private void logOSGiServices() {
similarity index 86%
rename from bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/package-info.java
rename to bundles-test-lib/src/main/java/org/opendaylight/odlparent/bundlestest/lib/package-info.java
index db3ec9e812f7dec9c4466e74ff6002f53241d5f0..410ddab7dcf3da0dd08845cbf340c73079d07e4c 100644 (file)
@@ -6,4 +6,4 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 @org.eclipse.jdt.annotation.NonNullByDefault
-package org.opendaylight.odlparent.bundlestest;
+package org.opendaylight.odlparent.bundlestest.lib;
similarity index 94%
rename from bundles-test/src/test/java/org/opendaylight/odlparent/bundlestest/ServiceReferenceUtilTest.java
rename to bundles-test-lib/src/test/java/org/opendaylight/odlparent/bundlestest/lib/ServiceReferenceUtilTest.java
index 23a18fd705d41fe5b7118013d370b301fe4fb415..9aa34cb76e27e2e52f7594b7492e756a2739d666 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.odlparent.bundlestest;
+package org.opendaylight.odlparent.bundlestest.lib;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -43,7 +43,7 @@ public class ServiceReferenceUtilTest {
 
     private static final class TestServiceReference implements ServiceReference<Object> {
 
-        private Map<String, Object> properties = Maps.newHashMap();
+        private final Map<String, Object> properties = Maps.newHashMap();
 
         TestServiceReference() {
             properties.put("property1", "value1");
index 6207a44324dfd3dbc99c67b32add2846ccc1a5be..66926dd1aa81acc1d2d56c6a50c4e9ada61c42ea 100644 (file)
 
   <dependencies>
     <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-      <scope>compile</scope>
+      <groupId>org.opendaylight.odlparent</groupId>
+      <artifactId>bundles-test-lib</artifactId>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
       <groupId>org.apache.karaf.bundle</groupId>
       <artifactId>org.apache.karaf.bundle.core</artifactId>
       <version>${karaf.version}</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.hamcrest</groupId>
-      <artifactId>hamcrest-library</artifactId>
-      <scope>compile</scope>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.hamcrest</groupId>
       <groupId>org.awaitility</groupId>
       <artifactId>awaitility</artifactId>
       <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.truth</groupId>
-      <artifactId>truth</artifactId>
-      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>cglib</groupId>
+          <artifactId>cglib-nodep</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.objenesis</groupId>
+          <artifactId>objenesis</artifactId>
+        </exclusion>
+      </exclusions>
     </dependency>
   </dependencies>
 
   <build>
     <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Embed-Dependency>*;scope=compile</Embed-Dependency>
+            <Embed-Transitive>true</Embed-Transitive>
+            <Import-Package>!net.sf.cglib.proxy,!org.objenesis,*</Import-Package>
+            <_exportcontents>org.opendaylight.odlparent.bundlestest.lib.*</_exportcontents>
+          </instructions>
+        </configuration>
+      </plugin>
       <plugin>
         <artifactId>maven-checkstyle-plugin</artifactId>
         <configuration>
diff --git a/bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/BundleDiagInfos.java b/bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/BundleDiagInfos.java
deleted file mode 100644 (file)
index 7f030fc..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.odlparent.bundlestest;
-
-import static org.apache.karaf.bundle.core.BundleState.Active;
-import static org.apache.karaf.bundle.core.BundleState.Installed;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.karaf.bundle.core.BundleInfo;
-import org.apache.karaf.bundle.core.BundleService;
-import org.apache.karaf.bundle.core.BundleState;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-
-/**
- * System readiness diagnostic summary information.
- *
- * @author Michael Vorburger.ch
- */
-public final class BundleDiagInfos {
-
-    private final List<String> okBundleStateInfoTexts;
-    private final List<String> nokBundleStateInfoTexts;
-    private final List<String> whitelistedBundleStateInfoTexts;
-    private final Map<BundleState, Integer> bundleStatesCounters;
-
-    private static final Map<String, BundleState> WHITELISTED_BUNDLES = ImmutableMap.of(
-            "slf4j.log4j12", Installed);
-
-    private BundleDiagInfos(List<String> okBundleStateInfoTexts, List<String> nokBundleStateInfoTexts,
-            List<String> whitelistedBundleStateInfoTexts, Map<BundleState, Integer> bundleStatesCounters) {
-        this.okBundleStateInfoTexts = ImmutableList.copyOf(okBundleStateInfoTexts);
-        this.nokBundleStateInfoTexts = ImmutableList.copyOf(nokBundleStateInfoTexts);
-        this.whitelistedBundleStateInfoTexts = ImmutableList.copyOf(whitelistedBundleStateInfoTexts);
-        this.bundleStatesCounters = ImmutableMap.copyOf(bundleStatesCounters);
-    }
-
-    public static BundleDiagInfos forContext(BundleContext bundleContext, BundleService bundleService) {
-        List<String> okBundleStateInfoTexts = new ArrayList<>();
-        List<String> nokBundleStateInfoTexts = new ArrayList<>();
-        List<String> whitelistedBundleStateInfoTexts = new ArrayList<>();
-        Map<BundleState, Integer> bundleStatesCounters = new EnumMap<>(BundleState.class);
-        for (BundleState bundleState : BundleState.values()) {
-            bundleStatesCounters.put(bundleState, 0);
-        }
-
-        for (Bundle bundle : bundleContext.getBundles()) {
-            String bundleSymbolicName = bundle.getSymbolicName();
-            BundleInfo karafBundleInfo = bundleService.getInfo(bundle);
-            BundleState karafBundleState = karafBundleInfo.getState();
-
-            String bundleStateDiagText = "OSGi state = " + bundleStatetoText(bundle.getState())
-                + ", Karaf bundleState = " + karafBundleState;
-            String diagText = bundleService.getDiag(bundle);
-            if (!Strings.isNullOrEmpty(diagText)) {
-                bundleStateDiagText += ", due to: " + diagText;
-            }
-
-            if (WHITELISTED_BUNDLES.get(bundleSymbolicName) != null) {
-                if (WHITELISTED_BUNDLES.get(bundleSymbolicName).equals(karafBundleState)) {
-                    String msg = "WHITELISTED " + bundleSymbolicName + ": " + bundleStateDiagText;
-                    whitelistedBundleStateInfoTexts.add(msg);
-                    continue;
-                }
-            }
-
-            bundleStatesCounters.compute(karafBundleState, (key, counter) -> counter + 1);
-
-            // BundleState comparison as in Karaf's "diag" command,
-            // see https://github.com/apache/karaf/blob/master/bundle/core/src/main/java/org/apache/karaf/bundle/command/Diag.java
-            // but we intentionally, got a little further than Karaf's "diag" command,
-            // and instead of only checking some states, we check what's really Active,
-            // but accept that some remain just Resolved:
-            if (karafBundleState != Active && !(karafBundleState == BundleState.Resolved)) {
-                String msg = "NOK " + bundleSymbolicName + ": " + bundleStateDiagText;
-                nokBundleStateInfoTexts.add(msg);
-            } else {
-                String msg = "OK " + bundleSymbolicName + ": " + bundleStateDiagText;
-                okBundleStateInfoTexts.add(msg);
-            }
-        }
-
-        return new BundleDiagInfos(okBundleStateInfoTexts, nokBundleStateInfoTexts,
-                whitelistedBundleStateInfoTexts, bundleStatesCounters);
-    }
-
-    private static String bundleStatetoText(int state) {
-        switch (state) {
-            case Bundle.INSTALLED:
-                return "Installed";
-            case Bundle.RESOLVED:
-                return "Resolved";
-            case Bundle.STARTING:
-                return "Starting";
-            case Bundle.ACTIVE:
-                return "Active";
-            case Bundle.STOPPING:
-                return "Stopping";
-            case Bundle.UNINSTALLED:
-                return "Uninstalled";
-            default:
-                return state + "???";
-        }
-    }
-
-    public SystemState getSystemState() {
-        if (bundleStatesCounters.get(BundleState.Failure) > 0) {
-            return SystemState.Failure;
-        } else if (bundleStatesCounters.get(BundleState.Stopping) > 0) {
-            return SystemState.Stopping;
-        } else if (bundleStatesCounters.get(BundleState.Installed) == 0
-                // No, just Resolved is OK, so do not: && bundleStatesCounters.get(BundleState.Resolved) == 0
-                && bundleStatesCounters.get(BundleState.Unknown) == 0
-                && bundleStatesCounters.get(BundleState.GracePeriod) == 0
-                && bundleStatesCounters.get(BundleState.Waiting) == 0
-                && bundleStatesCounters.get(BundleState.Starting) == 0
-                // BundleState.Active *should* be ~= total # of bundles (minus Resolved, and whitelisted installed)
-                && bundleStatesCounters.get(BundleState.Stopping) == 0
-                && bundleStatesCounters.get(BundleState.Failure) == 0) {
-            return SystemState.Active;
-        } else {
-            return SystemState.Booting;
-        }
-    }
-
-    public String getFullDiagnosticText() {
-        StringBuilder sb = new StringBuilder(getSummaryText());
-        int failureNumber = 1;
-        for (String nokBundleStateInfoText : getNokBundleStateInfoTexts()) {
-            sb.append('\n');
-            sb.append(failureNumber++);
-            sb.append(". ");
-            sb.append(nokBundleStateInfoText);
-        }
-        return sb.toString();
-    }
-
-    public String getSummaryText() {
-        return "diag: " + getSystemState() + " " + bundleStatesCounters.toString();
-    }
-
-    public List<String> getNokBundleStateInfoTexts() {
-        return ImmutableList.copyOf(nokBundleStateInfoTexts);
-    }
-
-    public List<String> getOkBundleStateInfoTexts() {
-        return ImmutableList.copyOf(okBundleStateInfoTexts);
-    }
-
-    public List<String> getWhitelistedBundleStateInfoTexts() {
-        return ImmutableList.copyOf(whitelistedBundleStateInfoTexts);
-    }
-
-    @Override
-    public String toString() {
-        return getFullDiagnosticText();
-    }
-}
diff --git a/bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/BundleServiceSummaryMatcher.java b/bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/BundleServiceSummaryMatcher.java
deleted file mode 100644 (file)
index aede1ac..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.odlparent.bundlestest;
-
-import static org.opendaylight.odlparent.bundlestest.SystemState.Active;
-import static org.opendaylight.odlparent.bundlestest.SystemState.Failure;
-import static org.opendaylight.odlparent.bundlestest.SystemState.Stopping;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-
-/**
- * Hamcrest Matcher for {@link BundleDiagInfos}.
- *
- * @author Michael Vorburger.ch
- */
-class BundleServiceSummaryMatcher extends BaseMatcher<BundleDiagInfos> {
-
-    @Override
-    public boolean matches(Object item) {
-        SystemState systemState = ((BundleDiagInfos) item).getSystemState();
-        return systemState.equals(Active) || systemState.equals(Stopping) || systemState.equals(Failure);
-    }
-
-    @Override
-    public void describeTo(Description description) {
-        description.appendText("system either ready with all bundles Active, "
-                + "or Stopping or Failure (but not still booting in GracePeriod, Waiting, Starting, Unknown;"
-                + "but just Resolved and some exceptional Installed is OK)");
-    }
-}
diff --git a/bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/ServiceReferenceUtil.java b/bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/ServiceReferenceUtil.java
deleted file mode 100644 (file)
index f47b557..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.odlparent.bundlestest;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utilities for OSGi's {@link ServiceReference}.
- *
- * @author Michael Vorburger.ch
- */
-public class ServiceReferenceUtil {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ServiceReferenceUtil.class);
-
-    public Map<String, Object> getProperties(ServiceReference<?> serviceRef) {
-        String[] propertyKeys = serviceRef.getPropertyKeys();
-        Map<String, Object> properties = new HashMap<>(propertyKeys.length);
-        for (String propertyKey : propertyKeys) {
-            Object propertyValue = serviceRef.getProperty(propertyKey);
-            if (propertyValue != null) {
-                if (propertyValue.getClass().isArray()) {
-                    propertyValue = Arrays.asList((Object[]) propertyValue);
-                }
-            }
-            // maintain the null value in the property map anyway
-            properties.put(propertyKey, propertyValue);
-        }
-        return properties;
-    }
-
-    public List<String> getUsingBundleSymbolicNames(ServiceReference<?> serviceRef) {
-        Bundle[] usingBundles = serviceRef.getUsingBundles();
-        if (usingBundles == null) {
-            return Collections.emptyList();
-        } else {
-            return Arrays.stream(usingBundles).map(Bundle::getSymbolicName).collect(Collectors.toList());
-        }
-    }
-
-}
diff --git a/bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/SystemState.java b/bundles-test/src/main/java/org/opendaylight/odlparent/bundlestest/SystemState.java
deleted file mode 100644 (file)
index 4f67778..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.odlparent.bundlestest;
-
-import org.apache.karaf.bundle.core.BundleState;
-
-/**
- * Karaf OSGi System State.
- *
- * @see BundleState
- *
- * @author Michael Vorburger.ch
- */
-public enum SystemState {
-
-    Booting,
-
-    Active,
-
-    Stopping,
-
-    Failure
-
-}
index 94a49226b24b55a7e91e77b9c82256534bbe3890..5964ff3da08f2441e8e1631071bdff3db41482a3 100644 (file)
@@ -24,9 +24,9 @@
 
   <dependencies>
     <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-      <scope>provided</scope>
+      <groupId>org.opendaylight.odlparent</groupId>
+      <artifactId>bundles-test-lib</artifactId>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
       <groupId>org.apache.karaf.bundle</groupId>
       <version>${karaf4.version}</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
     <dependency>
       <groupId>org.hamcrest</groupId>
       <artifactId>hamcrest-core</artifactId>
         </exclusion>
       </exclusions>
     </dependency>
-    <!-- BEWARE of adding additional dependencies here...
-         It will cause weird issues e.g. in integration/distribution/features/repos/distribution -->
-    <dependency>
-      <groupId>com.google.truth</groupId>
-      <artifactId>truth</artifactId>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 
   <build>
     <plugins>
       <plugin>
-          <groupId>org.apache.felix</groupId>
-          <artifactId>maven-bundle-plugin</artifactId>
-          <configuration>
-            <instructions>
-              <Embed-Dependency>*;scope=compile</Embed-Dependency>
-              <Embed-Transitive>true</Embed-Transitive>
-              <Import-Package>!net.sf.cglib.proxy,!org.objenesis,*</Import-Package>
-            </instructions>
-          </configuration>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Embed-Dependency>*;scope=compile</Embed-Dependency>
+            <Embed-Transitive>true</Embed-Transitive>
+            <Import-Package>!net.sf.cglib.proxy,!org.objenesis,*</Import-Package>
+            <_exportcontents>org.opendaylight.odlparent.bundlestest.lib.*</_exportcontents>
+          </instructions>
+        </configuration>
       </plugin>
       <plugin>
         <artifactId>maven-checkstyle-plugin</artifactId>
index 2e9377c6052d420e7adf121694412bfe22674e5d..f1c25cd28b5376f89baebe80a8e2ec022f3c7fe5 100644 (file)
@@ -7,41 +7,24 @@
  */
 package org.opendaylight.odlparent.bundles4test;
 
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import org.opendaylight.odlparent.bundlestest.lib.BundleDiagInfos;
 
-/**
- * Exception thrown (only) by
- * {@link TestBundleDiag#checkBundleDiagInfos(org.osgi.framework.BundleContext, long, java.util.concurrent.TimeUnit)}
- * if there are any OSGi bundles that failed to start.  This is based on not only {@link Bundle#getState()}'s
- * {@link Bundle#ACTIVE}, but also DI wiring systems such as blueprint containers.  The Exceptions' message
- * will likely contain a longer multi-line String with extensive technical details including all failed
- * bundles' states, detailed technical information related to OSGi bundle and blueprint resolution,
- * and possibly exceptions incl. stack traces thrown by {@link BundleActivator} start() methods and
- * dependency injection object wiring {@literal @}PostConstruct "init" type methods.
- *
- * @author Michael Vorburger.ch
- */
-public class SystemStateFailureException extends Exception {
-    private static final long serialVersionUID = 1L;
+@Deprecated
+@SuppressFBWarnings("NM_SAME_SIMPLE_NAME_AS_SUPERCLASS")
+public class SystemStateFailureException
+        extends org.opendaylight.odlparent.bundlestest.lib.SystemStateFailureException {
 
-    private final BundleDiagInfos bundleDiagInfos;
+    // TODO remove along with @Deprecated TestBundleDiag
 
-    public SystemStateFailureException(String message, BundleDiagInfos bundleDiagInfos, Throwable cause) {
-        super(getExtendedMessage(message, bundleDiagInfos), cause);
-        this.bundleDiagInfos = bundleDiagInfos;
-    }
+    private static final long serialVersionUID = 1L;
 
     public SystemStateFailureException(String message, BundleDiagInfos bundleDiagInfos) {
-        super(getExtendedMessage(message, bundleDiagInfos));
-        this.bundleDiagInfos = bundleDiagInfos;
+        super(message, bundleDiagInfos);
     }
 
-    private static String getExtendedMessage(String message, BundleDiagInfos bundleDiagInfos) {
-        return message + "\n" + bundleDiagInfos.getFullDiagnosticText();
+    public SystemStateFailureException(String message, BundleDiagInfos bundleDiagInfos, Throwable cause) {
+        super(message, bundleDiagInfos, cause);
     }
 
-    public BundleDiagInfos getBundleDiagInfos() {
-        return bundleDiagInfos;
-    }
 }
index f1497e233d9d951c116623506d1a08f22cb8986f..b218d9bfcdb05ae38a576c8c5857cee310e89b7e 100644 (file)
  */
 package org.opendaylight.odlparent.bundles4test;
 
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
-
 import java.util.concurrent.TimeUnit;
 import org.apache.karaf.bundle.core.BundleService;
-import org.awaitility.Awaitility;
-import org.awaitility.core.ConditionTimeoutException;
-import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
- * Utility to verify bundle diagnostic state from OSGi integration tests.
+ * Utility for OSGi bundles' diagnostics.
+ *
+ * @deprecated use the non-static {@link TestBundleDiag} instead of this.
  *
  * @author Michael Vorburger.ch
  */
-public class TestBundleDiag implements AutoCloseable {
+@Deprecated
+public final class TestBundleDiag {
 
-    private static final Logger LOG = LoggerFactory.getLogger(TestBundleDiag.class);
+    // TODO This @Deprecated class is about to be removed, it's just kept here so not to cause a compilation error
+    // in infrautils.ready, which already uses this, but which will be changed ASAP
 
-    private final BundleContext bundleContext;
-    private final ServiceReference<BundleService> bundleServiceReference;
-    private final BundleService bundleService;
-
-    private TestBundleDiag(BundleContext bundleContext) {
-        this.bundleContext = bundleContext;
-        this.bundleServiceReference = bundleContext.getServiceReference(BundleService.class);
-        this.bundleService = bundleContext.getService(bundleServiceReference);
-    }
+    private TestBundleDiag() { }
 
-    @Override
-    public void close() {
-        bundleContext.ungetService(bundleServiceReference);
-    }
-
-    /**
-     * Does something similar to Karaf's "diag" CLI command,
-     * and throws a {@link SystemStateFailureException} if anything incl. bundle wiring is NOK.
-     *
-     * <p>The implementation is based on Karaf's BundleService, and not the BundleStateService,
-     * because each Karaf supported DI system (such as Blueprint and Declarative Services, see String constants
-     * in BundleStateService), will have a separate BundleStateService.  The BundleService however will
-     * contain the combined status of all BundleStateServices.
-     *
-     * @author Michael Vorburger, based on guidance from Christian Schneider
-     */
     public static void checkBundleDiagInfos(BundleContext bundleContext, long timeout, TimeUnit timeoutUnit)
             throws SystemStateFailureException {
-        try (TestBundleDiag diag = new TestBundleDiag(bundleContext)) {
-            diag.checkBundleDiagInfos(timeout, timeoutUnit);
-        }
-    }
-
-    private void checkBundleDiagInfos(long timeout, TimeUnit timeoutUnit) throws SystemStateFailureException {
-        LOG.info("checkBundleDiagInfos() started...");
-        try {
-            Awaitility.await("checkBundleDiagInfos")
-                .pollDelay(0, MILLISECONDS)
-                .pollInterval(1, SECONDS)
-                .atMost(timeout, timeoutUnit)
-                    .conditionEvaluationListener(
-                        condition -> LOG.info("checkBundleDiagInfos: Elapsed time {}s, remaining time {}s, {}",
-                            condition.getElapsedTimeInMS() / 1000, condition.getRemainingTimeInMS() / 1000,
-                            ((BundleDiagInfos) condition.getValue()).getFullDiagnosticText()))
-                    .until(this::getBundleDiagInfos, new BundleServiceSummaryMatcher());
-
-            // If we're here then either BundleServiceSummaryMatcher quit because of Active, Failure or Stopping..
-            BundleDiagInfos bundleInfos = getBundleDiagInfos();
-            SystemState systemState = bundleInfos.getSystemState();
-            if (systemState.equals(SystemState.Failure) || systemState.equals(SystemState.Stopping)) {
-                LOG.error("diag failure; BundleService reports bundle(s) which failed or are already stopping"
-                        + " (details in following INFO and ERROR log messages...)");
-                logBundleDiagInfos(bundleInfos);
-                throw new SystemStateFailureException("diag failed; some bundles failed to start", bundleInfos);
-
-            } else {
-                // Inform the developer of the green SystemState.Active
-                LOG.info(bundleInfos.getFullDiagnosticText());
-            }
-
-        } catch (ConditionTimeoutException e) {
-            // If this happens then it got stuck waiting in SystemState.Booting,
-            // typically due to bundles still in BundleState GracePeriod or Waiting
-            LOG.error("diag failure; BundleService reports bundle(s) which are still not active"
-                    + " (details in following INFO and ERROR log messages...)");
-            BundleDiagInfos bundleInfos = getBundleDiagInfos();
-            logBundleDiagInfos(bundleInfos);
-            throw new SystemStateFailureException("diag timeout; some bundles are still not active:", bundleInfos, e);
-        }
-    }
-
-    private void logBundleDiagInfos(BundleDiagInfos bundleInfos) {
-        try {
-            logOSGiServices();
-        } catch (IllegalStateException e) {
-            LOG.warn("logOSGiServices() failed (never mind); too late during shutdown already?", e);
-        }
-        for (String okBundleStateInfo : bundleInfos.getOkBundleStateInfoTexts()) {
-            LOG.info(okBundleStateInfo);
-        }
-        for (String whitelistedBundleStateInfo : bundleInfos.getWhitelistedBundleStateInfoTexts()) {
-            LOG.warn(whitelistedBundleStateInfo);
-        }
-        for (String nokBundleStateInfo : bundleInfos.getNokBundleStateInfoTexts()) {
-            LOG.error(nokBundleStateInfo);
-        }
-    }
-
-    private BundleDiagInfos getBundleDiagInfos() {
-        return BundleDiagInfos.forContext(bundleContext, bundleService);
-    }
-
-    private void logOSGiServices() {
-        ServiceReferenceUtil util = new ServiceReferenceUtil();
-        LOG.info("Now going to log all known services, to help diagnose root cause of "
-                + "diag failure BundleService reported bundle(s) which are not active");
+        ServiceReference<BundleService> bundleServiceReference = bundleContext.getServiceReference(BundleService.class);
         try {
-            for (ServiceReference<?> serviceRef : bundleContext.getAllServiceReferences(null, null)) {
-                Bundle bundle = serviceRef.getBundle();
-                // serviceRef.getBundle() can return null if the bundle was destroyed
-                if (bundle != null) {
-                    LOG.info("{} defines OSGi Service {} used by {}", bundle.getSymbolicName(),
-                            util.getProperties(serviceRef), util.getUsingBundleSymbolicNames(serviceRef));
-                } else {
-                    LOG.trace("skipping reporting service reference as the underlying bundle is null");
-                }
+            BundleService bundleService = bundleContext.getService(bundleServiceReference);
+            org.opendaylight.odlparent.bundlestest.lib.TestBundleDiag diag =
+                    new org.opendaylight.odlparent.bundlestest.lib.TestBundleDiag(bundleContext, bundleService);
+            diag.checkBundleDiagInfos(timeout, timeoutUnit);
+        } catch (org.opendaylight.odlparent.bundlestest.lib.SystemStateFailureException e) {
+            throw new SystemStateFailureException(e.getMessage(), e.getBundleDiagInfos(), e.getCause());
+        } finally {
+            if (bundleServiceReference != null) {
+                bundleContext.ungetService(bundleServiceReference);
             }
-        } catch (InvalidSyntaxException e) {
-            LOG.error("logOSGiServices() failed due to InvalidSyntaxException", e);
         }
     }
 
diff --git a/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/package-info.java b/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/package-info.java
deleted file mode 100644 (file)
index 3629e2b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-@org.eclipse.jdt.annotation.NonNullByDefault
-package org.opendaylight.odlparent.bundles4test;
diff --git a/bundles4-test/src/test/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtilTest.java b/bundles4-test/src/test/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtilTest.java
deleted file mode 100644 (file)
index 99dbdff..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.odlparent.bundles4test;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.util.Arrays;
-import java.util.Map;
-import org.junit.Test;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Unit test for ServiceReferenceUtil.
- *
- * @author Michael Vorburger.ch
- */
-public class ServiceReferenceUtilTest {
-
-    @Test
-    public void testGetUsingBundleSymbolicNames() {
-        assertThat(new ServiceReferenceUtil().getUsingBundleSymbolicNames(getServiceReference())).isEmpty();
-    }
-
-    @Test
-    public void testGetProperties() {
-        assertThat(new ServiceReferenceUtil().getProperties(getServiceReference())).containsExactly(
-                "property1", "value1",
-                "property2", Arrays.asList(new String[] { "value2.1", "value2.2" }),
-                "property3", null);
-    }
-
-    private static ServiceReference<?> getServiceReference() {
-        return new TestServiceReference();
-    }
-
-    private static final class TestServiceReference implements ServiceReference<Object> {
-
-        private Map<String, Object> properties = Maps.newHashMap();
-
-        TestServiceReference() {
-            properties.put("property1", "value1");
-            properties.put("property2", Lists.newArrayList("value2.1", "value2.2"));
-            properties.put("property3", null);
-        }
-
-        @Override
-        public Object getProperty(String key) {
-            return properties.get(key);
-        }
-
-        @Override
-        public String[] getPropertyKeys() {
-            return properties.keySet().stream().toArray(String[]::new);
-        }
-
-        @Override
-        public Bundle getBundle() {
-            return null;
-        }
-
-        @Override
-        public Bundle[] getUsingBundles() {
-            return null;
-        }
-
-        @Override
-        public boolean isAssignableTo(Bundle bundle, String className) {
-            return false;
-        }
-
-        @Override
-        public int compareTo(Object reference) {
-            return 0;
-        }
-    }
-
-}
index 9f7951369fdcd607e9edf1ba688cf7341b0592b3..1fa82b45edfdc80fe4c657bc3567a1dd32105d76 100644 (file)
             <version>1.9.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.odlparent</groupId>
+            <artifactId>bundles-test-lib</artifactId>
+            <version>1.9.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.bundle</groupId>
+            <artifactId>org.apache.karaf.bundle.core</artifactId>
+            <version>${karaf4.version}</version>
+            <scope>test</scope>
+        </dependency>
         <!-- Force SLF4J to test scope -->
         <dependency>
             <groupId>org.slf4j</groupId>
index e52f703bbd225b22eeb4495cc3b765ae7840a7cc..cb4822f87392e45ddffdbf2e12e7919e9d683c18 100644 (file)
             <version>1.9.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.odlparent</groupId>
+            <artifactId>bundles-test-lib</artifactId>
+            <version>1.9.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.bundle</groupId>
+            <artifactId>org.apache.karaf.bundle.core</artifactId>
+            <version>${karaf.version}</version>
+            <scope>test</scope>
+        </dependency>
         <!-- Force SLF4J to test scope -->
         <dependency>
             <groupId>org.slf4j</groupId>
         </site>
     </distributionManagement>
 
-</project>
\ No newline at end of file
+</project>
index bdd5f451a4c75c4c70976d2702ede9b62b4f9f80..393847cbe90a500634fac29e5bc12deb2d5659f2 100644 (file)
             <artifactId>bundles-test</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.bundle</groupId>
+            <artifactId>org.apache.karaf.bundle.core</artifactId>
+            <version>${karaf.version}</version>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 
     <build>
index 27d16c7a6d37bae9c5de6a1a93ad90fb558895ac..2ebfda0f5b77681e11d4b038949d0d5019a45029 100644 (file)
@@ -15,7 +15,6 @@ import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_
 import static org.ops4j.pax.exam.CoreOptions.maven;
 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
 import static org.ops4j.pax.exam.CoreOptions.when;
-import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
@@ -46,7 +45,7 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.opendaylight.odlparent.bundlestest.TestBundleDiag;
+import org.opendaylight.odlparent.bundlestest.lib.TestBundleDiag;
 import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.CoreOptions;
 import org.ops4j.pax.exam.Option;
@@ -158,8 +157,10 @@ public class SingleFeatureTest {
             logLevel(LogLevel.WARN),
             mvnLocalRepoOption(),
             standardKarafFeatures(),
-            wrappedBundle(maven("org.awaitility", "awaitility").versionAsInProject()), // req. by bundles-test
-            mavenBundle(maven("com.google.guava", "guava").versionAsInProject()),      // req. by bundles-test
+            // Guava is used by this SingleFeatureTest class itself (not, anymore, by by bundles-test),
+            // in (at least) the BLACKLISTED_BROKEN_FEATURES ImmutableList at the end, so we need to
+            // add Guava so that this class can run in Karaf under OSGi, as it compiled here
+            mavenBundle(maven("com.google.guava", "guava").versionAsInProject()),
             mavenBundle(maven("org.opendaylight.odlparent", "bundles-test").versionAsInProject()),
             editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG, LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST,
                     LogLevel.INFO.name()),
index 67d757200be359b7bb2c4dcb4a7214fbcef03b91..3ad8156e9c5ac55340ec727a471f8eddf09bd55e 100644 (file)
             <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.bundle</groupId>
+            <artifactId>org.apache.karaf.bundle.core</artifactId>
+            <version>${karaf4.version}</version>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
           <groupId>com.google.guava</groupId>
           <artifactId>guava</artifactId>
index 50567939eec9b6a1b61544f47f2eafb13015cf17..80acc56a5191762578497a30b7ee7b3436f88457 100644 (file)
@@ -34,6 +34,7 @@ import java.util.EnumSet;
 import java.util.List;
 import java.util.Properties;
 import javax.inject.Inject;
+import org.apache.karaf.bundle.core.BundleService;
 import org.apache.karaf.features.Feature;
 import org.apache.karaf.features.FeaturesService;
 import org.apache.karaf.features.Repository;
@@ -43,7 +44,7 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.opendaylight.odlparent.bundles4test.TestBundleDiag;
+import org.opendaylight.odlparent.bundlestest.lib.TestBundleDiag;
 import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.ProbeBuilder;
@@ -114,6 +115,9 @@ public class SingleFeatureTest {
     @Inject @NonNull
     private BundleContext bundleContext;
 
+    @Inject @NonNull
+    private BundleService bundleService; // NOT BundleStateService, see checkBundleStatesDiag()
+
     @Inject @NonNull
     private FeaturesService featuresService;
 
@@ -384,7 +388,7 @@ public class SingleFeatureTest {
                     || !BLACKLISTED_BROKEN_FEATURES.contains(getFeatureName()))) {
             LOG.info("new TestBundleDiag().checkBundleDiagInfos() STARTING");
             Integer timeOutInSeconds = Integer.getInteger(BUNDLES_DIAG_TIMEOUT_PROP, 5 * 60);
-            TestBundleDiag.checkBundleDiagInfos(bundleContext, timeOutInSeconds, SECONDS);
+            new TestBundleDiag(bundleContext, bundleService).checkBundleDiagInfos(timeOutInSeconds, SECONDS);
             LOG.info("new TestBundleDiag().checkBundleDiagInfos() ENDED");
         } else {
             LOG.warn("SKIPPING TestBundleDiag because system property {} is true or feature is blacklisted: {}",
diff --git a/pom.xml b/pom.xml
index c90230f1e444335f7c20bc03d437ea4d8a4f63ee..da7187c89c8b5ff04093b64279bbafac48a7bd43 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -31,6 +31,8 @@
         <module>checkstyle</module>
         <module>findbugs</module>
         <module>license</module>
+
+        <module>bundles-test-lib</module>
         <module>bundles-test</module>
         <module>bundles4-test</module>
         <module>features-test</module>
index aebb9c1d4e9d5725574b57bd8dc93ec7ff992815..52405b6a641c08c027b73beab251df68ade39ee6 100644 (file)
             <version>1.9.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.odlparent</groupId>
+            <artifactId>bundles-test-lib</artifactId>
+            <version>1.9.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.bundle</groupId>
+            <artifactId>org.apache.karaf.bundle.core</artifactId>
+            <version>${karaf4.version}</version>
+            <scope>test</scope>
+        </dependency>
         <!-- Force SLF4J to test scope -->
         <dependency>
             <groupId>org.slf4j</groupId>