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");
