parse upgrade maps and test that

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

Branch: refs/heads/master
Commit: af3f5f511b44d0248acd7fd254f6aee8783ad811
Parents: 8473fb4
Author: Alex Heneveld <[email protected]>
Authored: Tue Oct 31 12:36:55 2017 +0000
Committer: Alex Heneveld <[email protected]>
Committed: Tue Oct 31 12:36:55 2017 +0000

----------------------------------------------------------------------
 .../core/typereg/BundleUpgradeParser.java       | 203 ++++++++++++++---
 .../core/typereg/BundleUpgradeParserTest.java   | 223 +++++++++++++++++--
 .../BrooklynLauncherUpgradeCatalogOsgiTest.java |   2 +-
 3 files changed, 372 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/af3f5f51/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java 
b/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java
index 73327e9..437fc5a 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java
@@ -27,6 +27,7 @@ import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.typereg.RegisteredType;
@@ -42,6 +43,7 @@ import org.osgi.framework.VersionRange;
 
 import com.google.common.annotations.Beta;
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
 import com.google.common.base.Objects;
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableList;
@@ -167,7 +169,7 @@ public class BundleUpgradeParser {
      * 
      * The format is as per {@link #MANIFEST_HEADER_UPGRADE_FOR_BUNDLES}, with 
two differences in interpretation.
      * 
-     * If {@code =value} is omitted, the ugprade target is assumed to be the 
same type as the corresonding key but at the
+     * If {@code =value} is omitted, the upgrade target is assumed to be the 
same type as the corresponding key but at the
      * version of the bundle.
      * 
      * A wildcard can be given as the key, without a version ({@code *}) or 
with ({@code *:[0,1)}) to refer to
@@ -252,7 +254,7 @@ public class BundleUpgradeParser {
         }
 
         public boolean isEmpty() {
-            return removedLegacyItems.isEmpty() && removedBundles.isEmpty();
+            return removedLegacyItems.isEmpty() && removedBundles.isEmpty() && 
upgradesProvidedByBundles.isEmpty() && upgradesProvidedByTypes.isEmpty();
         }
 
         public Set<VersionRangedName> getRemovedLegacyItems() {
@@ -404,37 +406,77 @@ public class BundleUpgradeParser {
         //   section "Bundle Upgrade Metadata"
         
         Dictionary<String, String> headers = bundle.getHeaders();
-        Multimap<VersionedName,VersionRangedName> upgradesForBundles = 
parseUpgradeForBundlesHeader(headers.get(MANIFEST_HEADER_UPGRADE_FOR_BUNDLES), 
bundle);
+        String upgradesForBundlesHeader = 
headers.get(MANIFEST_HEADER_UPGRADE_FOR_BUNDLES);
+        Multimap<VersionedName,VersionRangedName> upgradesForBundles = 
parseUpgradeForBundlesHeader(upgradesForBundlesHeader, bundle);
         return CatalogUpgrades.builder()
                 
.removedLegacyItems(parseForceRemoveLegacyItemsHeader(headers.get(MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS),
 bundle, typeSupplier))
                 
.removedBundles(parseForceRemoveBundlesHeader(headers.get(MANIFEST_HEADER_FORCE_REMOVE_BUNDLES),
 bundle))
                 .upgradeBundles(upgradesForBundles)
-                
.upgradeTypes(parseUpgradeForTypesHeader(headers.get(MANIFEST_HEADER_UPGRADE_FOR_TYPES),
 bundle, upgradesForBundles))
+                
.upgradeTypes(parseUpgradeForTypesHeader(headers.get(MANIFEST_HEADER_UPGRADE_FOR_TYPES),
 bundle, typeSupplier, 
+                    upgradesForBundlesHeader==null ? null : 
upgradesForBundles))
                 .build();
     }
 
-    private static Multimap<VersionedName, VersionRangedName> 
parseUpgradeForBundlesHeader(String input, Bundle bundle) {
-        return LinkedHashMultimap.<VersionedName, VersionRangedName>create();
+    @VisibleForTesting
+    static List<VersionRangedName> parseForceRemoveLegacyItemsHeader(String 
input, Bundle bundle, Supplier<? extends Iterable<? extends RegisteredType>> 
typeSupplier) {
+        return parseVersionRangedNameList(input, false, 
getTypeNamesInBundle(typeSupplier), "[0,"+bundle.getVersion()+")");
     }
-    private static Multimap<VersionedName, VersionRangedName> 
parseUpgradeForTypesHeader(String input, Bundle bundle, Multimap<VersionedName, 
VersionRangedName> upgradesForBundles) {
-        return LinkedHashMultimap.<VersionedName, VersionRangedName>create();
+    
+    @VisibleForTesting
+    static List<VersionRangedName> parseForceRemoveBundlesHeader(String input, 
Bundle bundle) {
+        if (input == null) return ImmutableList.of();
+        return parseVersionRangedNameList(input, false, 
MutableList.of(bundle.getSymbolicName()), getDefaultSourceVersionRange(bundle));
     }
 
+    private static Multimap<VersionedName, VersionRangedName> 
parseUpgradeForBundlesHeader(String input, Bundle bundle) {
+        return parseVersionRangedNameEqualsVersionedNameList(input, false,
+            // wildcard means this bundle, all lower versions
+            MutableList.of(bundle.getSymbolicName()), 
MutableList.of(getDefaultSourceVersionRange(bundle)),
+            // default target is this bundle
+            (i) -> { return new VersionedName(bundle); });
+    }
+    private static Multimap<VersionedName, VersionRangedName> 
parseUpgradeForTypesHeader(String input, Bundle bundle, Supplier<? extends 
Iterable<? extends RegisteredType>> typeSupplier, Multimap<VersionedName, 
VersionRangedName> upgradesForBundles) {
+        List<String> sourceVersions = null;
+        if (upgradesForBundles!=null) {
+            Collection<VersionRangedName> acceptableRanges = 
upgradesForBundles.get(new VersionedName(bundle));
+            if (acceptableRanges!=null && !acceptableRanges.isEmpty()) {
+                for (VersionRangedName n: acceptableRanges) {
+                    if (n.getSymbolicName().equals(bundle.getSymbolicName())) {
+                        if (sourceVersions==null) {
+                            sourceVersions = MutableList.of();
+                        }
+                        sourceVersions.add(n.getOsgiVersionRange().toString());
+                    }
+                }
+            }
+        }
+        Set<VersionedName> typeSupplierNames = 
MutableList.copyOf(typeSupplier.get()).stream().map(
+            (t) -> 
VersionedName.toOsgiVersionedName(t.getVersionedName())).collect(Collectors.toSet());
+        return parseVersionRangedNameEqualsVersionedNameList(input, false,
+            // wildcard means all types, all versions of this bundle this 
bundle replaces
+            getTypeNamesInBundle(typeSupplier), sourceVersions,
+            // default target is same type at version of this bundle
+            (i) -> { 
+                VersionedName targetTypeAtBundleVersion = new 
VersionedName(i.getSymbolicName(), bundle.getVersion());
+                if 
(!typeSupplierNames.contains(VersionedName.toOsgiVersionedName(targetTypeAtBundleVersion)))
 {
+                    throw new IllegalStateException("Bundle manifest declares 
it upgrades "+i+" "
+                        + "but does not declare an explicit target and does 
not contain inferred target "+targetTypeAtBundleVersion);
+                }
+                return targetTypeAtBundleVersion; 
+            });
+    }
+    
     @VisibleForTesting
-    static List<VersionRangedName> parseForceRemoveLegacyItemsHeader(String 
input, Bundle bundle, Supplier<? extends Iterable<? extends RegisteredType>> 
typeSupplier) {
-        if (input == null) return ImmutableList.of();
+    static List<String> getTypeNamesInBundle(Supplier<? extends Iterable<? 
extends RegisteredType>> typeSupplier) {
         List<String> wildcardItems = MutableList.of();
         for (RegisteredType item : typeSupplier.get()) {
             wildcardItems.add(item.getSymbolicName());
         }
-        return parseVersionRangedNameList(input, false, wildcardItems, 
"[0,"+bundle.getVersion()+")");
+        return wildcardItems;
     }
     
-
     @VisibleForTesting
-    static List<VersionRangedName> parseForceRemoveBundlesHeader(String input, 
Bundle bundle) {
-        if (input == null) return ImmutableList.of();
-        
+    static String getDefaultSourceVersionRange(Bundle bundle) {
         String bundleVersion = bundle.getVersion().toString();
         String maxVersion;
         if (BrooklynVersionSyntax.isSnapshot(bundleVersion)) {
@@ -442,8 +484,8 @@ public class BundleUpgradeParser {
         } else {
             maxVersion = bundleVersion;
         }
-        
-        return parseVersionRangedNameList(input, false, 
MutableList.of(bundle.getSymbolicName()), "[0,"+maxVersion+")");
+        String defaultSourceVersion = "[0,"+maxVersion+")";
+        return defaultSourceVersion;
     }
     
     @VisibleForTesting
@@ -459,23 +501,29 @@ public class BundleUpgradeParser {
         
         List<VersionRangedName> versionedItems = new ArrayList<>();
         for (String val : vals) {
-            try {
-                val = val.trim();
-                if (val.startsWith("*")) {
-                    String r;
-                    if ("*".equals(val)) {
-                        r = wildcardVersion;
-                    } else if (val.startsWith("*:")) {
-                        r = val.substring(2);
-                    } else {
-                        throw new IllegalArgumentException("Wildcard entry 
must be of the form \"*\" or \"*:range\"");
-                    }
-                    for (String item: wildcardNames) {
-                        versionedItems.add(new VersionRangedName(item, r, 
false));
-                    }
+            val = val.trim();
+            if (val.startsWith("*")) {
+                String r;
+                if ("*".equals(val)) {
+                    r = wildcardVersion;
+                } else if (val.startsWith("*:")) {
+                    r = val.substring(2);
                 } else {
-                    versionedItems.add(VersionRangedName.fromString(val, 
singleVersionIsOsgiRange));
+                    throw new IllegalArgumentException("Wildcard entry must be 
of the form \"*\" or \"*:range\"");
                 }
+                for (String item: wildcardNames) {
+                    versionedItems.add(parseVersionRangedName(item, r, false));
+                }
+            } else {
+                versionedItems.add(parseVersionRangedName(val, 
singleVersionIsOsgiRange));
+            }
+        }
+        return versionedItems;
+    }
+
+        private static VersionRangedName parseVersionRangedName(String val, 
boolean singleVersionIsOsgiRange) {
+            try {
+                return VersionRangedName.fromString(val, 
singleVersionIsOsgiRange);
             } catch (Exception e) {
                 if (Strings.containsAny(val, "(", ")", "[", "]") &&
                         !Strings.containsAny(val, "'", "\"")) {
@@ -484,7 +532,93 @@ public class BundleUpgradeParser {
                 throw Exceptions.propagate(e);
             }
         }
-        return versionedItems;
+        
+        private static VersionRangedName parseVersionRangedName(String name, 
String range, boolean singleVersionIsOsgiRange) {
+            try {
+                return new VersionRangedName(name, range, 
singleVersionIsOsgiRange);
+            } catch (Exception e) {
+                if (Strings.containsAny(range, "(", ")", "[", "]") &&
+                        !Strings.containsAny(range, "'", "\"")) {
+                    throw Exceptions.propagateAnnotated("Entry cannot be 
parsed. If defining a range on an entry you must quote the entry.", e);
+                }
+                throw Exceptions.propagate(e);
+            }
+        }
+        
+    @VisibleForTesting
+    static Multimap<VersionedName,VersionRangedName> 
parseVersionRangedNameEqualsVersionedNameList(String input, boolean 
singleVersionIsOsgiRange,
+            List<String> wildcardNames, List<String> wildcardVersions,
+            Function<VersionRangedName,VersionedName> defaultTargetFunction) {
+        LinkedHashMultimap<VersionedName,VersionRangedName> result = 
LinkedHashMultimap.create();
+        if (input == null) return result;
+        
+        List<String> vals = QuotedStringTokenizer.builder()
+                .delimiterChars(",")
+                .includeQuotes(false)
+                .includeDelimiters(false)
+                .buildList(input);
+        
+        for (String entry : vals) {
+            entry = entry.trim();
+            String key, val;
+            String[] keVals = entry.split("=");
+            if (keVals.length>2) {
+                throw new IllegalArgumentException("Max one = permitted in 
entry (\""+entry+"\"). If defining a range on an entry you must quote the 
entry.");
+            } else if (keVals.length==2) {
+                key = keVals[0];
+                val = keVals[1];
+            } else {
+                key = keVals[0];
+                val = null;
+            }
+            
+            List<String> sourceNames, sourceVersions;
+            if (key.startsWith("*")) {
+                if (wildcardNames==null) {
+                    throw new IllegalArgumentException("Wildcard cannot be 
inferred");
+                }
+                if  ("*".equals(key)) {
+                    if (wildcardVersions==null) {
+                        throw new IllegalArgumentException("Version for 
wildcard cannot be inferred");
+                    }
+                    sourceVersions = wildcardVersions;
+                } else if (key.startsWith("*:")) {
+                    sourceVersions = MutableList.of(key.substring(2));
+                } else {
+                    throw new IllegalArgumentException("Wildcard entry key 
must be of the form \"*\" or \"*:range\"");
+                }
+                sourceNames = MutableList.copyOf(wildcardNames);
+            } else {
+                String[] parts = key.split(":");
+                if (parts.length==1) {
+                    if (wildcardVersions==null) {
+                        throw new IllegalArgumentException("Version for 
"+key+" cannot be inferred");
+                    }
+                    sourceNames = MutableList.of(key);
+                    sourceVersions = wildcardVersions;
+                } else if (parts.length==2) {
+                    sourceNames = MutableList.of(parts[0]);
+                    sourceVersions = MutableList.of(parts[1]);
+                } else {
+                    throw new IllegalArgumentException("Entry '"+entry+"' 
should be of form 'name[:versionRange][=name[:version]]'");
+                }
+            }
+            for (String item: sourceNames) {
+                for (String v: sourceVersions) {
+                    VersionRangedName source = parseVersionRangedName(item, v, 
false);
+                    VersionedName target;
+                    if (val!=null) {
+                        target = VersionedName.fromString(val);
+                    } else if (defaultTargetFunction!=null) {
+                        target = defaultTargetFunction.apply(source);
+                    } else {
+                        throw new IllegalArgumentException("Wildcard entry key 
must be of the form \"*\" or \"*:range\"");
+                    }
+                    result.put(target, source);
+                }
+            }
+        }
+        return result;
     }
     
     @VisibleForTesting
@@ -494,4 +628,5 @@ public class BundleUpgradeParser {
                 && quoteChars.contains(input.substring(input.length() - 1));
         return (quoted ? input.substring(1, input.length() - 1) : input);
     }
-}
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/af3f5f51/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java
 
b/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java
index 64c8a6e..16f87b7 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java
@@ -26,6 +26,7 @@ import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.typereg.RegisteredType;
@@ -39,15 +40,23 @@ import org.mockito.Mockito;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Version;
 import org.osgi.framework.VersionRange;
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Supplier;
 import com.google.common.base.Suppliers;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
 
 public class BundleUpgradeParserTest {
 
+    private static final String DEFAULT_WILDCARD_NAME = "WILDCARD-NAME";
+    private static final String DEFAULT_WILDCARD_VERSION = 
"0-WILDCARD_VERSION";
+    private static final String DEFAULT_WILDCARD_VERSION_RANGE = 
"[0,"+DEFAULT_WILDCARD_VERSION+")";
+    private static final String DEFAULT_TARGET_VERSION = "0-DEFAULT-TARGET";
+    
     private VersionRange from0lessThan1 = new VersionRange('[', 
Version.valueOf("0"), Version.valueOf("1.0.0"), ')');
     private VersionRange from0lessThan1_2_3 = new VersionRange('[', 
Version.valueOf("0"), Version.valueOf("1.2.3"), ')');
     private VersionRange exactly0dot1 = new VersionRange('[', 
Version.valueOf("0.1.0"), Version.valueOf("0.1.0"), ']');
@@ -86,27 +95,64 @@ public class BundleUpgradeParserTest {
     @Test
     public void testParseSingleQuotedVal() throws Exception {
         String input = "\"foo:[0,1.0.0)\"";
-        assertParseList(input, ImmutableList.of(fooFrom0lessThan1));
+        assertParseListVersionRangeNames(input, 
ImmutableList.of(fooFrom0lessThan1));
     }
     
     @Test
     public void testParseSingleQuotedValWithNestedQuotes() throws Exception {
         String input = "\"foo:[0,\"1.0.0\")\"";
-        assertParseList(input, ImmutableList.of(fooFrom0lessThan1));
+        assertParseListVersionRangeNames(input, 
ImmutableList.of(fooFrom0lessThan1));
     }
     
     @Test
     public void testParseMultipleVals() throws Exception {
         String input = "\"foo:[0,1.0.0)\",\"bar:[0,1.0.0)\"";
-        assertParseList(input, ImmutableList.of(fooFrom0lessThan1, 
barFrom0lessThan1));
+        assertParseListVersionRangeNames(input, 
ImmutableList.of(fooFrom0lessThan1, barFrom0lessThan1));
     }
 
     @Test
     public void testParseValWithExactVersion() throws Exception {
         String input = "\"foo:0.1.0\"";
-        assertParseList(input, ImmutableList.of(new VersionRangedName("foo", 
exactly0dot1)));
+        assertParseListVersionRangeNames(input, ImmutableList.of(new 
VersionRangedName("foo", exactly0dot1)));
     }
-
+    
+    @Test
+    public void testParseKeyEqualsValue() throws Exception {
+        String input = "\"foo:[0,1)=foo:1\"";
+        Multimap<VersionedName, VersionRangedName> expected = 
LinkedHashMultimap.create();
+        expected.put(VersionedName.fromString("foo:1"), 
VersionRangedName.fromString("foo:[0,1)", false));
+        assertParseListVersionRangedNameToVersionedNames(input, expected); 
+    }
+    
+    @Test
+    public void testParseKeyEqualsValueList() throws Exception {
+        String input = "\"foo:[0,1)=foo:1\", foo:1-SNAPSHOT=foo:1, 
bar:0=bar:1";
+        Multimap<VersionedName, VersionRangedName> expected = 
LinkedHashMultimap.create();
+        expected.put(VersionedName.fromString("foo:1"), 
VersionRangedName.fromString("foo:[0,1)", false));
+        expected.put(VersionedName.fromString("foo:1"), 
VersionRangedName.fromString("foo:1-SNAPSHOT", false));
+        expected.put(VersionedName.fromString("bar:1"), 
VersionRangedName.fromString("bar:0", false));
+        assertParseListVersionRangedNameToVersionedNames(input, expected); 
+    }
+    
+    @Test
+    public void testParseKeyEqualsValueWildcardsAndDefault() throws Exception {
+        String input = "foo, foo:9-bogus, *, *:8, 
\"*:[9-bogus,9-bogut)=foo9:10.bogus\"";
+        Multimap<VersionedName, VersionRangedName> expected = 
LinkedHashMultimap.create();
+        expected.putAll(new VersionedName("foo", DEFAULT_TARGET_VERSION),
+            MutableList.of(
+                
VersionRangedName.fromString("foo:"+DEFAULT_WILDCARD_VERSION_RANGE, false),
+                VersionRangedName.fromString("foo:"+"9-bogus", false)
+            ));
+        expected.putAll(new VersionedName(DEFAULT_WILDCARD_NAME, 
DEFAULT_TARGET_VERSION),
+            MutableList.of(
+                
VersionRangedName.fromString(DEFAULT_WILDCARD_NAME+":"+DEFAULT_WILDCARD_VERSION_RANGE,
 false),
+                VersionRangedName.fromString(DEFAULT_WILDCARD_NAME+":8", false)
+            ));
+        expected.put(new VersionedName("foo9", "10.bogus"),
+            
VersionRangedName.fromString(DEFAULT_WILDCARD_NAME+":[9-bogus,9-bogut)", 
false));
+        assertParseListVersionRangedNameToVersionedNames(input, expected); 
+    }
+    
     @Test
     public void testParseForceRemoveBundlesHeader() throws Exception {
         Bundle bundle = newMockBundle(new VersionedName("foo.bar", "1.2.3"));
@@ -154,24 +200,14 @@ public class BundleUpgradeParserTest {
     }
 
     @Test
-    public void testParseBundleManifest() throws Exception {
+    public void testParseBundleManifestRemovals() throws Exception {
         Bundle bundle = newMockBundle(ImmutableMap.of(
                 BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, 
"\"foo:[0,1.0.0)\",\"foo:1.0.0.SNAPSHOT\",\"bar:[0,1.0.0)\"",
-                BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, 
"\"org.example.brooklyn.mybundle:[0,1.0.0)\"",
-                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_BUNDLES, 
"\"org.example.brooklyn.mybundle:[0,1.0.0)=org.example.brooklyn.mybundle:1\"",
-                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_TYPES, 
"\"foo:[0,1)=foo:1\""));
-        checkParse(bundle);
+                BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, 
"\"org.example.brooklyn.mybundle:[0,1.0.0)\""));
+        checkParseRemovals(bundle);
     }
 
-    @Test
-    public void testParseBundleManifestWithSpaces() throws Exception {
-        Bundle bundle = newMockBundle(ImmutableMap.of(
-                BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, 
"\"foo:[0,1.0.0)\", \"foo:1.0.0.SNAPSHOT\", \"bar:[0,1.0.0)\"",
-                BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, " 
\"org.example.brooklyn.mybundle:[0,1.0.0)\""));
-        checkParse(bundle);
-    }
-
-    protected void checkParse(Bundle bundle) {
+    protected void checkParseRemovals(Bundle bundle) {
         Supplier<Iterable<RegisteredType>> typeSupplier = 
Suppliers.ofInstance(ImmutableList.of());
         
         CatalogUpgrades upgrades = 
BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle, typeSupplier);
@@ -194,6 +230,144 @@ public class BundleUpgradeParserTest {
     }
     
     @Test
+    public void testParseBundleManifestUpgrades1() throws Exception {
+        Bundle bundle = newMockBundle(ImmutableMap.of(
+                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_BUNDLES, 
"\"org.example.brooklyn.mybundle:[0,1.0.0)=org.example.brooklyn.mybundle:1\"",
+                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_TYPES, 
"\"foo:[0,1)=foo:1\""));
+        checkParseUpgrades1(bundle);
+    }
+
+    protected void checkParseUpgrades1(Bundle bundle) {
+        Supplier<Iterable<RegisteredType>> typeSupplier = 
Suppliers.ofInstance(ImmutableList.of());
+        
+        CatalogUpgrades upgrades = 
BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle, typeSupplier);
+        assertFalse(upgrades.isEmpty());
+        assertBundleUpgrade(upgrades, "org.example.brooklyn.mybundle", "0", 
"org.example.brooklyn.mybundle", "1");
+        assertBundleUpgrade(upgrades, "org.example.brooklyn.mybundle", "1", 
null, null);
+        assertTypeUpgrade(upgrades, "foo", "0", "foo", "1");
+        assertTypeUpgrade(upgrades, "foo", "0.2", "foo", "1");
+        assertTypeUpgrade(upgrades, "foo", "0-SNAPSHOT", "foo", "1");
+        assertTypeUpgrade(upgrades, "foo", "1", null, null);
+    }
+    
+    @Test
+    public void testParseBundleManifest() throws Exception {
+        Bundle bundle = newMockBundle(ImmutableMap.of(
+                BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, 
"\"foo:[0,1.0.0)\",\"foo:1.0.0.SNAPSHOT\",\"bar:[0,1.0.0)\"",
+                BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, 
"\"org.example.brooklyn.mybundle:[0,1.0.0)\"",
+                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_BUNDLES, 
"\"org.example.brooklyn.mybundle:[0,1.0.0)=org.example.brooklyn.mybundle:1\"",
+                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_TYPES, 
"\"foo:[0,1)=foo:1\""));
+        checkParseRemovals(bundle);
+        checkParseUpgrades1(bundle);
+    }
+
+    @Test
+    public void testParseBundleManifestWithSpaces() throws Exception {
+        Bundle bundle = newMockBundle(ImmutableMap.of(
+                BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, 
"\"foo:[0,1.0.0)\", \"foo:1.0.0.SNAPSHOT\", \"bar:[0,1.0.0)\"",
+                BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, " 
\"org.example.brooklyn.mybundle:[0,1.0.0)\"",
+                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_BUNDLES, 
"\"org.example.brooklyn.mybundle:[0,1.0.0)=org.example.brooklyn.mybundle:1\" ",
+                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_TYPES, 
"\"foo:[0,1)=foo:1\""));
+        checkParseRemovals(bundle);
+        checkParseUpgrades1(bundle);
+    }
+
+
+    @Test
+    public void testParseBundleManifestUpgrades2() throws Exception {
+        Bundle bundle = newMockBundle(new VersionedName("bun", "2"), 
+            ImmutableMap.of(
+                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_BUNDLES, 
+                    "foo, foo:9-bogus, *, *:8, 
\"*:[9-bogus,9-bogut)=foo9:10.bogus\"",
+                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_TYPES, 
+                    "foo=foo:3, foo:9-bogus=foo:3, *, *:8, bar:2-SNAPSHOT, 
\"*:[9-bogus,9-bogut)=foo9:10.bogus\""));
+        checkParseUpgrades2(bundle);
+    }
+
+    protected void checkParseUpgrades2(Bundle bundle) {
+        Supplier<Iterable<RegisteredType>> typeSupplier = 
Suppliers.ofInstance(ImmutableList.of(
+            new BasicRegisteredType(null, "bar", "2", null),
+            new BasicRegisteredType(null, "bub", "2", null)));
+        CatalogUpgrades upgrades = 
BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle, typeSupplier);
+        
+        assertFalse(upgrades.isEmpty());
+        
+        assertBundleUpgrade(upgrades, "foo", "0.1", "bun", "2.0.0");
+        assertBundleUpgrade(upgrades, "foo", "9-bogus", "bun", "2.0.0");
+        assertBundleUpgrade(upgrades, "foo", "1.5", "bun", "2.0.0");
+        assertBundleUpgrade(upgrades, "foo", "3", null, null);
+        
+        assertBundleUpgrade(upgrades, "bun", "1", "bun", "2.0.0");
+        assertBundleUpgrade(upgrades, "bun", "3", null, null);
+        
+        assertTypeUpgrade(upgrades, "foo", "1", "foo", "3");
+        assertTypeUpgrade(upgrades, "foo", "2.2", null, null);
+        assertTypeUpgrade(upgrades, "foo", "9-bogus", "foo", "3");
+        
+        assertTypeUpgrade(upgrades, "bar", "1", "bar", "2.0.0");
+        assertTypeUpgrade(upgrades, "bar", "8", "bar", "2.0.0");
+        assertTypeUpgrade(upgrades, "bar", "2-SNAPSHOT", "bar", "2.0.0");
+        assertTypeUpgrade(upgrades, "bar", "2.0.0.SNAPSHOT", "bar", "2.0.0");
+        
+        assertTypeUpgrade(upgrades, "bub", "1", "bub", "2.0.0");
+        assertTypeUpgrade(upgrades, "bub", "8", "bub", "2.0.0");
+        assertTypeUpgrade(upgrades, "bub", "2-SNAPSHOT", null, null);
+        
+        assertTypeUpgrade(upgrades, "bar", "9-bogus-one", "foo9", "10.bogus");
+        assertTypeUpgrade(upgrades, "bar", "9.bogus", "foo9", "10.bogus");
+        assertTypeUpgrade(upgrades, "baz", "9-bogus-one", null, null);
+        assertTypeUpgrade(upgrades, "bar", "9-bogut", null, null);
+        assertTypeUpgrade(upgrades, "bar", "9.bogut", null, null);
+    }
+    
+    @Test
+    public void 
testParseBundleManifestUpgradesValidatesIfNoBundleUpgradeVersion() throws 
Exception {
+        Supplier<Iterable<RegisteredType>> typeSupplier = 
Suppliers.ofInstance(ImmutableList.of(
+            new BasicRegisteredType(null, "foo", "1.0", null) ));
+        Bundle bundle = newMockBundle(new VersionedName("bundle", "1.0"), 
+            
ImmutableMap.of(BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_TYPES, "foo"));
+        try {
+            BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle, 
typeSupplier);
+            Asserts.shouldHaveFailedPreviously();
+        } catch (Exception e) {
+            Asserts.expectedFailureContainsIgnoreCase(e, "foo", "version", 
"cannot be inferred");
+        }
+    }
+    
+    @Test
+    public void testParseBundleManifestUpgradesValidatesIfTypeNotContained() 
throws Exception {
+        Supplier<Iterable<RegisteredType>> typeSupplier = 
Suppliers.ofInstance(ImmutableList.of());
+        Bundle bundle = newMockBundle(new VersionedName("bundle", "1.0"), 
+            ImmutableMap.of(
+                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_BUNDLES, "*",
+                BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_TYPES, "foo"));
+        try {
+            BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle, 
typeSupplier);
+            Asserts.shouldHaveFailedPreviously();
+        } catch (Exception e) {
+            Asserts.expectedFailureContainsIgnoreCase(e, "foo", "bundle", 
"upgrade", "does not contain", "target");
+        }
+    }
+    
+    private void assertBundleUpgrade(CatalogUpgrades upgrades, String sn, 
String sv, String tn, String tv) {
+        Set<VersionedName> targets = upgrades.getUpgradesForBundle(new 
VersionedName(sn, sv));
+        if (tn==null) {
+            Asserts.assertSize(targets, 0);
+        } else if (!targets.contains(new VersionedName(tn, tv))) {
+            Assert.fail("Failed target "+tn+":"+tv+" expected for 
"+sn+":"+sv+"; got "+targets);
+        }
+    }
+
+    private void assertTypeUpgrade(CatalogUpgrades upgrades, String sn, String 
sv, String tn, String tv) {
+        Set<VersionedName> targets = upgrades.getUpgradesForType(new 
VersionedName(sn, sv));
+        if (tn==null) {
+            Asserts.assertSize(targets, 0);
+        } else if (!targets.contains(new VersionedName(tn, tv))) {
+            Assert.fail("Failed target "+tn+":"+tv+" expected for 
"+sn+":"+sv+"; got "+targets);
+        }
+    }
+
+    @Test
     public void testForgetQuotesGivesNiceError() throws Exception {
         Bundle bundle = newMockBundle(ImmutableMap.of(
                 BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, 
"foo:[0,1.0.0),bar:[0,1.0.0)"));
@@ -255,11 +429,18 @@ public class BundleUpgradeParserTest {
         return result;
     }
     
-    private void assertParseList(String input, List<VersionRangedName> 
expected) throws Exception {
-        List<VersionRangedName> actual = 
BundleUpgradeParser.parseVersionRangedNameList(input, false, 
MutableList.of("WILCARD-NAME"), "0-WILDCARD_VERSION");
+    private void assertParseListVersionRangeNames(String input, 
List<VersionRangedName> expected) throws Exception {
+        List<VersionRangedName> actual = 
BundleUpgradeParser.parseVersionRangedNameList(input, false, 
MutableList.of(DEFAULT_WILDCARD_NAME), DEFAULT_WILDCARD_VERSION);
         assertListsEqual(actual, expected);
     }
     
+    private void assertParseListVersionRangedNameToVersionedNames(String 
input, Multimap<VersionedName,VersionRangedName> expected) throws Exception {
+        Multimap<VersionedName, VersionRangedName> actual = 
BundleUpgradeParser.parseVersionRangedNameEqualsVersionedNameList(input, false, 
+            MutableList.of(DEFAULT_WILDCARD_NAME), 
MutableList.of(DEFAULT_WILDCARD_VERSION_RANGE),
+            (i) -> new VersionedName(i.getSymbolicName(), 
DEFAULT_TARGET_VERSION));
+        assertEquals(actual, expected);
+    }
+    
     private void assertParseForceRemoveBundlesHeader(String input, Bundle 
bundle, List<VersionRangedName> expected) throws Exception {
         List<VersionRangedName> actual = 
BundleUpgradeParser.parseForceRemoveBundlesHeader(input, bundle);
         assertListsEqual(actual, expected);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/af3f5f51/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
----------------------------------------------------------------------
diff --git 
a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
 
b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
index 289b96a..595f5f9 100644
--- 
a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
+++ 
b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
@@ -152,7 +152,7 @@ public class BrooklynLauncherUpgradeCatalogOsgiTest extends 
AbstractBrooklynLaun
     
     // removed item with upgrade deployed after rebind
     // TODO WIP
-    @Test
+    @Test(groups="WIP")
     public void testForceUpgradeItemByRemovingBundle() throws Exception {
         VersionedName one_1_0_0 = VersionedName.fromString("one:1.0.0");
         VersionedName one_2_0_0 = VersionedName.fromString("one:2.0.0");

Reply via email to