You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2017/10/28 10:02:56 UTC

[2/7] brooklyn-server git commit: BROOKLYN-546: add unit test

BROOKLYN-546: add unit test

Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/2a539c0d
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/2a539c0d
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/2a539c0d

Branch: refs/heads/master
Commit: 2a539c0dc181c7b82e0e8e8c1b2345b464325d10
Parents: bfabe7c
Author: Aled Sage <al...@gmail.com>
Authored: Mon Oct 23 17:37:05 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Fri Oct 27 12:31:20 2017 +0100

----------------------------------------------------------------------
 .../brooklyn/core/mgmt/ha/OsgiManager.java      |  11 ++
 .../AbstractBrooklynLauncherRebindTest.java     |  10 +-
 .../BrooklynLauncherRebindCatalogOsgiTest.java  | 100 ++++++++++++++++++-
 3 files changed, 119 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2a539c0d/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
index 995f7ed..9f47a44 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
@@ -76,6 +76,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -326,6 +327,16 @@ public class OsgiManager {
         brooklynBundlesCacheDir = null;
     }
 
+    @VisibleForTesting
+    public static Maybe<Framework> tryPeekFrameworkForReuse() {
+        synchronized (OSGI_FRAMEWORK_CONTAINERS_FOR_REUSE) {
+            if (!OSGI_FRAMEWORK_CONTAINERS_FOR_REUSE.isEmpty()) {
+                return Maybe.of(OSGI_FRAMEWORK_CONTAINERS_FOR_REUSE.get(0));
+            }
+        }
+        return Maybe.absent();
+    }
+    
     /** Map of bundles by UID */
     public Map<String, ManagedBundle> getManagedBundles() {
         return managedBundlesRecord.getManagedBundles();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2a539c0d/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
----------------------------------------------------------------------
diff --git a/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java b/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
index 0369862..89bcae0 100644
--- a/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
+++ b/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
@@ -25,6 +25,7 @@ import static org.testng.Assert.assertNull;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.net.URI;
 import java.nio.charset.StandardCharsets;
@@ -138,7 +139,14 @@ public abstract class AbstractBrooklynLauncherRebindTest {
         Files.write(contents, file, Charsets.UTF_8);
         return file;
     }
-
+    
+    protected File newTmpCopy(File orig) throws Exception {
+        File file = java.nio.file.Files.createTempFile("brooklynLauncherRebindTest-"+Identifiers.makeRandomId(4), "txt").toFile();
+        tmpFiles.add(file);
+        Streams.copyClose(new FileInputStream(orig), new FileOutputStream(file));
+        return file;
+    }
+    
     protected File newTmpBundle(Map<String, byte[]> files, VersionedName bundleName) {
         return newTmpBundle(files, bundleName, ImmutableMap.of());
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2a539c0d/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java
----------------------------------------------------------------------
diff --git a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java
index 2e9c78e..d4e8c75 100644
--- a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java
+++ b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java
@@ -18,15 +18,30 @@
  */
 package org.apache.brooklyn.launcher;
 
+import static org.testng.Assert.assertEquals;
+
 import java.io.File;
 import java.nio.charset.StandardCharsets;
+import java.io.FileInputStream;
+import java.net.URI;
+import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Set;
 
+import org.apache.brooklyn.api.typereg.ManagedBundle;
+import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
 import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
+import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.entity.stock.BasicEntity;
 import org.apache.brooklyn.test.support.TestResourceUnavailableException;
+import org.apache.brooklyn.util.core.osgi.Osgis;
+import org.apache.brooklyn.util.os.Os;
 import org.apache.brooklyn.util.osgi.OsgiTestResources;
 import org.apache.brooklyn.util.osgi.VersionedName;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.launch.Framework;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -38,6 +53,8 @@ import com.google.common.collect.Iterables;
 
 public class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBrooklynLauncherRebindTest {
 
+    private static final String CATALOG_EMPTY_INITIAL = "classpath://rebind-test-empty-catalog.bom";
+
     private static final VersionedName COM_EXAMPLE_BUNDLE_ID = new VersionedName(
             OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_COM_EXAMPLE_SYMBOLIC_NAME_FULL, 
             OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_COM_EXAMPLE_VERSION);
@@ -45,6 +62,8 @@ public class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBrooklynLaunc
     private static final Set<VersionedName> COM_EXAMPLE_BUNDLE_CATALOG_IDS = ImmutableSet.of(
             new VersionedName("com.example.simpleTest", "0.0.0-SNAPSHOT"));
 
+    private boolean reuseOsgi = false;
+    
     @BeforeMethod(alwaysRun=true)
     @Override
     public void setUp() throws Exception {
@@ -58,7 +77,7 @@ public class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBrooklynLaunc
     
     @Override
     protected boolean reuseOsgi() {
-        return false;
+        return reuseOsgi;
     }
 
     private BrooklynLauncher newLauncherForTests(String catalogInitial) {
@@ -88,6 +107,79 @@ public class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBrooklynLaunc
         assertManagedBundle(newLauncher, bundleName, bundleItems);
     }
 
+    /**
+     * See https://issues.apache.org/jira/browse/BROOKLYN-546.
+     * 
+     * We built up to launcher3, which will have three things:
+     *  1. a pre-installed "system bundle"
+     *  2. an initial catalog that references this same system bundle (hence the bundle will be "managed")
+     *  3. persisted state that references this same system bundle.
+     *
+     * At the end of this, we want only one version of that "system bundle" to be installed, but also for
+     * it to be a "brooklyn managed bundle".
+     *
+     * This scenario isn't quite the same as BROOKLYN-546. To make it fail, we'd need to have bundle URLs like:
+     *     "mvn:org.apache.brooklyn/brooklyn-software-cm-ansible/1.0.0-SNAPSHOT"
+     * (as is used in brooklyn-library/karaf/catalog/target/classes/catalog.bom).
+     *
+     * When that is used, the "osgi unique url" is the same as for the system library, so when it tries
+     * to replace the library by calling "installBundle" then it fails.
+     *
+     * We ensure this isn't happening by asserting that our manually installed "system bundle" is still the same.
+     */
+    @Test
+    public void testRebindWithSystemBundleInCatalog() throws Exception {
+        Set<VersionedName> bundleItems = ImmutableSet.of(VersionedName.fromString("one:1.0.0-SNAPSHOT"));
+        String bundleBom = createCatalogYaml(ImmutableList.of(), bundleItems);
+        VersionedName bundleName = new VersionedName("org.example.testRebindWithSystemBundleInCatalog", "1.0.0.SNAPSHOT");
+        File bundleFile = newTmpBundle(ImmutableMap.of(BasicBrooklynCatalog.CATALOG_BOM, bundleBom.getBytes(StandardCharsets.UTF_8)), bundleName);
+        File bundleFileCopy = newTmpCopy(bundleFile);
+
+        File initialBomFile = newTmpFile(createCatalogYaml(ImmutableList.of(bundleFile.toURI()), ImmutableList.of()));
+
+        Framework reusedFamework = null;
+        Bundle pseudoSystemBundle = null;
+        try {
+            reuseOsgi = true;
+            
+            // Launch and terminate brooklyn to ensure there is a reusable OSGi Framework
+            BrooklynLauncher launcher = newLauncherForTests(CATALOG_EMPTY_INITIAL);
+            launcher.start();
+            launcher.terminate();
+            Os.deleteRecursively(persistenceDir);
+            
+            // Add our bundle, so it feels for all intents and purposes like a "system bundle"
+            reusedFamework = OsgiManager.tryPeekFrameworkForReuse().get();
+            pseudoSystemBundle = installBundle(reusedFamework, bundleFileCopy);
+            
+            // Launch brooklyn, where initial catalog includes a duplicate of the system bundle
+            BrooklynLauncher launcher2 = newLauncherForTests(initialBomFile.getAbsolutePath());
+            launcher2.start();
+            assertCatalogConsistsOfIds(launcher2, bundleItems);
+            assertManagedBundle(launcher2, bundleName, bundleItems);
+            launcher2.terminate();
+
+            // Launch brooklyn, where persisted state now includes the initial catalog's bundle
+            BrooklynLauncher launcher3 = newLauncherForTests(initialBomFile.getAbsolutePath());
+            launcher3.start();
+            assertCatalogConsistsOfIds(launcher3, bundleItems);
+            assertManagedBundle(launcher3, bundleName, bundleItems);
+            
+            // Should not have replaced the original "system bundle"
+            reusedFamework.getBundleContext().getBundles();
+            List<Bundle> matchingBundles = Osgis.bundleFinder(reusedFamework).symbolicName(bundleName.getSymbolicName()).version(bundleName.getOsgiVersionString()).findAll();
+            assertEquals(matchingBundles, ImmutableList.of(pseudoSystemBundle));
+
+            launcher3.terminate();
+
+        } finally {
+            reuseOsgi = false;
+            if (pseudoSystemBundle != null && pseudoSystemBundle.getState() != Bundle.UNINSTALLED) {
+                pseudoSystemBundle.uninstall();
+            }
+        }
+    }
+
     @Test
     public void testRebindUpgradesBundleWithSameItems() throws Exception {
         Set<VersionedName> bundleItems = ImmutableSet.of(VersionedName.fromString("one:1.0.0"));
@@ -169,4 +261,10 @@ public class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBrooklynLaunc
         assertCatalogConsistsOfIds(newLauncher, COM_EXAMPLE_BUNDLE_CATALOG_IDS);
         assertManagedBundle(newLauncher, COM_EXAMPLE_BUNDLE_ID, COM_EXAMPLE_BUNDLE_CATALOG_IDS);
     }
+    
+    private Bundle installBundle(Framework framework, File bundle) throws Exception {
+        try (FileInputStream stream = new FileInputStream(bundle)) {
+            return framework.getBundleContext().installBundle(bundle.toURI().toString(), stream);
+        }
+    }
 }