This is an automated email from the ASF dual-hosted git repository. mradhakrishnan pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push: new 611337c [AMBARI-22817] Update backend code to handle new versioning schema. (#155) 611337c is described below commit 611337c928c99222133effb3ad8dc708cdfb8da3 Author: vbrodetskyi <vbrodets...@cybervisiontech.com> AuthorDate: Thu Jan 25 03:04:45 2018 +0200 [AMBARI-22817] Update backend code to handle new versioning schema. (#155) * AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi) * AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi) * AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi) * AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi) * AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi) * AMBARI-22817. Update backend code to handle new versioning schema.(vbrodetskyi) --- .../libraries/functions/module_version.py | 158 ++++++++++++++++ .../libraries/functions/mpack_version.py | 207 +++++++++++++++++++++ .../apache/ambari/server/utils/ModuleVersion.java | 162 ++++++++++++++++ .../apache/ambari/server/utils/MpackVersion.java | 197 ++++++++++++++++++++ .../ambari/server/utils/TestVersionUtils.java | 142 ++++++++++++++ ambari-server/src/test/python/TestVersion.py | 100 +++++++++- 6 files changed, 964 insertions(+), 2 deletions(-) diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/module_version.py b/ambari-common/src/main/python/resource_management/libraries/functions/module_version.py new file mode 100644 index 0000000..6ec4ba3 --- /dev/null +++ b/ambari-common/src/main/python/resource_management/libraries/functions/module_version.py @@ -0,0 +1,158 @@ +""" + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import re + +""" + This class should be used to compare module(service) versions. + Base method which should be used is parse(..), This method will validate and parse + version which you will pass as parameter, and return object of current class with + parsed version. Same thing you should do with another version, with which you are + planning to compare previous one. After that, use "==", "<", ">" to get final result. +""" +class ModuleVersion(object): + __module_version_pattern = "(?P<aMajor>[0-9]+).(?P<aMinor>[0-9]+).(?P<iMinor>[0-9]+).(?P<iMaint>[0-9]+)(-h(?P<hotfix>[0-9]+))*-b(?P<build>[0-9]+)" + __module_version_regex = re.compile(__module_version_pattern) + + def __init__(self, apache_major, apache_minor, internal_minor, internal_maint, hotfix, build): + """ + :type apache_major int + :type apache_minor int + :type internal_maint int + :type internal_minor int + :type hotfix int + :type build int + """ + self.__apache_major = int(apache_major) + self.__apache_minor = int(apache_minor) + self.__internal_maint = int(internal_maint) + self.__internal_minor = int(internal_minor) + self.__hotfix = int(hotfix) if hotfix else 0 # hotfix is optional group + self.__build = int(build) + + def __repr__(self): + return "{0}.{1}.{2}.{3}-h{4}-b{5}".format(*self.to_list()) + + def to_list(self): + """ + Return version elements as list + + :rtype list + """ + return [ + self.__apache_major, + self.__apache_minor, + self.__internal_minor, + self.__internal_maint, + self.__hotfix, + self.__build + ] + + def __cmp__(self, other): + """ + :type other ModuleVersion + + :raise TypeError + """ + if other and not isinstance(other, self.__class__): + raise TypeError("Operand type is different from {0}".format(self.__class__.__name__)) + + r = 0 + x = self.to_list() + y = other.to_list() + + for i in range(0, len(x)): + r = x[i] - y[i] + if r != 0: + break + + return 1 if r > 0 else -1 if r < 0 else 0 + + @classmethod + def parse(cls, module_version): + """ + Parse string to module version + + :type module_version str + :rtype ModuleVersion + """ + matcher = cls.validate(module_version) + return ModuleVersion( + matcher.group("aMajor"), + matcher.group("aMinor"), + matcher.group("iMinor"), + matcher.group("iMaint"), + matcher.group("hotfix"), + matcher.group("build") + ) + + @classmethod + def validate(cls, module_version): + """ + Check if provided version is valid. If version is valid will return match object + or will raise exception. + + :param module_version version to check + :type module_version str + + :rtype __Match[T] | None + + :raise ValueError + """ + + if not module_version: + raise ValueError("Module version can't be empty or null") + + version = module_version.strip() + + if not version: + raise ValueError("Module version can't be empty or null") + + matcher = cls.__module_version_regex.match(version) + + if not matcher: + raise ValueError("{0} is not a valid {1}".format(version, cls.__name__)) + + return matcher + + @property + def apache_major(self): + return self.__apache_major + + @property + def apache_minor(self): + return self.__apache_minor + + @property + def internal_minor(self): + return self.__internal_minor + + @property + def internal_maint(self): + return self.__internal_maint + + @property + def hotfix(self): + return self.__hotfix + + @property + def build(self): + return self.__build + + + diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/mpack_version.py b/ambari-common/src/main/python/resource_management/libraries/functions/mpack_version.py new file mode 100644 index 0000000..664f9fe --- /dev/null +++ b/ambari-common/src/main/python/resource_management/libraries/functions/mpack_version.py @@ -0,0 +1,207 @@ +""" + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import re + +""" + This class should be used to compare mpack and stack versions. + Base method which should be used is parse/parse_stack_version, depends + on which versions you want to compare. This method will validate and parse + version which you will pass as parameter, and return object of current class with + parsed version. Same thing you should do with another version, with which you are + planning to compare previous one. After that, use "==", ">", "<" to get final result. +""" +class MpackVersion(object): + __mpack_version_pattern = "(?P<major>[0-9]+).(?P<minor>[0-9]+).(?P<maint>[0-9]+)(-h(?P<hotfix>[0-9]+))*-b(?P<build>[0-9]+)" + __mpack_legacy_stack_version_pattern = "(?P<major>[0-9]+).(?P<minor>[0-9]+).(?P<maint>[0-9]+).(?P<hotfix>[0-9]+)(-(?P<build>[0-9]+))" + __mpack_version_regex = re.compile(__mpack_version_pattern) + __mpack_legacy_stack_version_regex = re.compile(__mpack_legacy_stack_version_pattern) + + def __init__(self, major, minor, maint, hotfix, build): + """ + :type major int + :type minor int + :type maint int + :type hotfix int + :type build int + """ + self.__major = int(major) + self.__minor = int(minor) + self.__maint = int(maint) + self.__hotfix = int(hotfix) if hotfix else 0 # hotfix is optional group + self.__build = int(build) + + def __repr__(self): + return "{0}.{1}.{2}-h{3}-b{4}".format(*self.to_list()) + + def to_list(self): + """ + Return version elements as list + + :rtype list + """ + return [ + self.__major, + self.__minor, + self.__maint, + self.__hotfix, + self.__build + ] + + def __cmp__(self, other): + """ + :type other MpackVersion + + :raise TypeError + """ + if other and not isinstance(other, self.__class__): + raise TypeError("Operand type is different from {0}".format(self.__class__.__name__)) + + r = 0 + x = self.to_list() + y = other.to_list() + + for i in range(0, len(x)): + r = x[i] - y[i] + if r != 0: + break + + return 1 if r > 0 else -1 if r < 0 else 0 + + @classmethod + def parse(cls, mpack_version): + """ + Parse string to mpack version + + :type mpack_version str + :rtype MpackVersion + """ + matcher = cls.validate(mpack_version) + return MpackVersion( + matcher.group("major"), + matcher.group("minor"), + matcher.group("maint"), + matcher.group("hotfix"), + matcher.group("build") + ) + + + @classmethod + def parse_stack_version(cls, stack_version): + """ + Parse string to mpack version + + :type stack_version str + :rtype MpackVersion + """ + matcher = cls.validate_stack_version(stack_version) + return MpackVersion( + matcher.group("major"), + matcher.group("minor"), + matcher.group("maint"), + matcher.group("hotfix"), + matcher.group("build") + ) + + + @classmethod + def validate_stack_version(cls, stack_version): + """ + Check if provided version is valid. If version is valid will return match object + or will raise exception. + + :param stack_version version to check + :type stack_version str + + :rtype __Match[T] | None + + :raise ValueError + """ + + if not stack_version: + raise ValueError("Module version can't be empty or null") + + version = stack_version.strip() + + if not version: + raise ValueError("Module version can't be empty or null") + + matcher = cls.__mpack_version_regex.match(version) + + if not matcher: + matcher = cls.__mpack_legacy_stack_version_regex.match(version) + if not matcher: + raise ValueError("{0} is not a valid {1}".format(version, cls.__name__)) + else: + if not matcher.group("hotfix"): + raise ValueError("{0} is not a valid {1}".format(version, cls.__name__)) + + return matcher + + + @classmethod + def validate(cls, mpack_version): + """ + Check if provided version is valid. If version is valid will return match object + or will raise exception. + + :param module_version version to check + :type module_version str + + :rtype __Match[T] | None + + :raise ValueError + """ + + if not mpack_version: + raise ValueError("Module version can't be empty or null") + + version = mpack_version.strip() + + if not version: + raise ValueError("Module version can't be empty or null") + + matcher = cls.__mpack_version_regex.match(version) + + if not matcher: + raise ValueError("{0} is not a valid {1}".format(version, cls.__name__)) + + return matcher + + @property + def major(self): + return self.__major + + @property + def minor(self): + return self.__minor + + @property + def maint(self): + return self.__maint + + @property + def hotfix(self): + return self.__hotfix + + @property + def build(self): + return self.__build + + + diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/ModuleVersion.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/ModuleVersion.java new file mode 100644 index 0000000..520eac7 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/ModuleVersion.java @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ambari.server.utils; + + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; + +/** + * This class should be used to compare module(service) versions. + * Base method which should be used is parse(..), This method will validate and parse + * version which you will pass as parameter, and return object of current class with + * parsed version. Same thing you should do with another version, with which you are + * planning to compare previous one. After that, use method compare to get final result. + */ + +public class ModuleVersion implements Comparable<ModuleVersion> { + + // RE for different version formats like N.N.N.N-bN, N.N.N-hN-bN + private static final String VERSION_WITH_HOTFIX_AND_BUILD_PATTERN = "^([0-9]+).([0-9]+).([0-9]+).([0-9]+)-h([0-9]+)-b([0-9]+)"; + private static final String VERSION_WITH_BUILD_PATTERN = "^([0-9]+).([0-9]+).([0-9]+).([0-9]+)-b([0-9]+)"; + + // Patterns for previous RE + private static final Pattern PATTERN_WITH_HOTFIX = Pattern.compile(VERSION_WITH_HOTFIX_AND_BUILD_PATTERN); + private static final Pattern PATTERN_WITHOUT_HOTFIX = Pattern.compile(VERSION_WITH_BUILD_PATTERN); + + // Parts of version + private int apacheMajor; + private int apacheMinor; + private int internalMinor; + private int internalMaint; + private int hotfix; + private int build; + + + public ModuleVersion(int apacheMajor, int apacheMinor, int internalMinor, int internalMaint, int hotfix, int build) { + this.apacheMajor = apacheMajor; + this.apacheMinor = apacheMinor; + this.internalMinor = internalMinor; + this.internalMaint = internalMaint; + this.hotfix = hotfix; + this.build = build; + } + + /** + * Method which will parse module version + * which user passed as parameter. Also + * in this method version will be validated. + * @param moduleVersion string + * @return MpackVersion instance which contains parsed version + * */ + public static ModuleVersion parse(String moduleVersion) { + Matcher versionMatcher = validateModuleVersion(moduleVersion); + ModuleVersion result = null; + + if (versionMatcher.pattern().pattern().equals(VERSION_WITH_HOTFIX_AND_BUILD_PATTERN)) { + result = new ModuleVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)), + Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)), + Integer.parseInt(versionMatcher.group(5)), Integer.parseInt(versionMatcher.group(6))); + + } else { + result = new ModuleVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)), + Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)), 0, + Integer.parseInt(versionMatcher.group(5))); + + } + + return result; + } + + /** + * Method validate module version not to be + * empty or null. Also check if passed version + * has valid format. + * @param version string + * @return Matcher for passed version + * @throws IllegalArgumentException() if version empty/null/not valid + */ + private static Matcher validateModuleVersion(String version) { + if (StringUtils.isEmpty(version)) { + throw new IllegalArgumentException("Module version can't be empty or null"); + } + + String moduleVersion = StringUtils.trim(version); + + Matcher versionMatcher = PATTERN_WITH_HOTFIX.matcher(moduleVersion); + if (!versionMatcher.find()) { + versionMatcher = PATTERN_WITHOUT_HOTFIX.matcher(moduleVersion); + if (!versionMatcher.find()) { + throw new IllegalArgumentException("Wrong format for module version, should be N.N.N.N-bN or N.N.N-hN-bN"); + } + } + + return versionMatcher; + } + + @Override + public int compareTo(ModuleVersion other) { + int result = this.apacheMajor - other.apacheMajor; + if(result == 0) { + result = this.apacheMinor - other.apacheMinor; + if(result == 0) { + result = this.internalMinor - other.internalMinor; + if(result == 0) { + result = this.internalMaint - other.internalMaint; + if(result == 0) { + result = this.hotfix - other.hotfix; + if(result == 0) { + result = this.build - other.build; + } + } + } + } + } + return result > 0 ? 1 : result < 0 ? -1 : 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ModuleVersion that = (ModuleVersion) o; + + if (apacheMajor != that.apacheMajor) return false; + if (apacheMinor != that.apacheMinor) return false; + if (build != that.build) return false; + if (hotfix != that.hotfix) return false; + if (internalMaint != that.internalMaint) return false; + if (internalMinor != that.internalMinor) return false; + + return true; + } + + @Override + public int hashCode() { + int result = apacheMajor; + result = 31 * result + apacheMinor; + result = 31 * result + internalMinor; + result = 31 * result + internalMaint; + result = 31 * result + hotfix; + result = 31 * result + build; + return result; + } +} diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/MpackVersion.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/MpackVersion.java new file mode 100644 index 0000000..ad3fdc8 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/MpackVersion.java @@ -0,0 +1,197 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ambari.server.utils; + + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; + +/** + * This class should be used to compare mpack and stack versions. + * Base method which should be used is parse/parseStackVersion, depends + * on which versions you want to compare. This method will validate and parse + * version which you will pass as parameter, and return object of current class with + * parsed version. Same thing you should do with another version, with which you are + * planning to compare previous one. After that, use method compare to get final result. + */ + +public class MpackVersion implements Comparable<MpackVersion> { + + // RE for different version formats like N.N.N-hN-bN, N.N.N-bN, N.N.N.N-N + private final static String VERSION_WITH_HOTFIX_AND_BUILD_PATTERN = "^([0-9]+).([0-9]+).([0-9]+)-h([0-9]+)-b([0-9]+)"; + private final static String VERSION_WITH_BUILD_PATTERN = "^([0-9]+).([0-9]+).([0-9]+)-b([0-9]+)"; + private final static String LEGACY_STACK_VERSION_PATTERN = "^([0-9]+).([0-9]+).([0-9]+).([0-9]+)-([0-9]+)"; + + // Patterns for previous RE + private final static Pattern PATTERN_WITH_HOTFIX = Pattern.compile(VERSION_WITH_HOTFIX_AND_BUILD_PATTERN); + private final static Pattern PATTERN_LEGACY_STACK_VERSION = Pattern.compile(LEGACY_STACK_VERSION_PATTERN); + private final static Pattern PATTERN_WITHOUT_HOTFIX = Pattern.compile(VERSION_WITH_BUILD_PATTERN); + + // Parts of version + private int major; + private int minor; + private int maint; + private int hotfix; + private int build; + + + public MpackVersion(int major, int minor, int maint, int hotfix, int build) { + this.major = major; + this.minor = minor; + this.maint = maint; + this.hotfix = hotfix; + this.build = build; + } + + /** + * Method which will parse mpack version + * which user passed as parameter. Also + * in this method version will be validated. + * @param mpackVersion string + * @return MpackVersion instance which contains parsed version + * */ + public static MpackVersion parse(String mpackVersion) { + Matcher versionMatcher = validateMpackVersion(mpackVersion); + MpackVersion result = null; + + if (versionMatcher.pattern().pattern().equals(VERSION_WITH_BUILD_PATTERN)) { + result = new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)), + Integer.parseInt(versionMatcher.group(3)), 0, Integer.parseInt(versionMatcher.group(4))); + + } else { + result = new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)), + Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)), Integer.parseInt(versionMatcher.group(5))); + + } + + return result; + } + + /** + * Method which will parse stack version + * which user passed as parameter. Also + * in this method version will be validated. + * @param stackVersion string + * @return MpackVersion instance which contains parsed version + * */ + public static MpackVersion parseStackVersion(String stackVersion) { + Matcher versionMatcher = validateStackVersion(stackVersion); + MpackVersion result = new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)), + Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)), Integer.parseInt(versionMatcher.group(5))); + + return result; + } + + /** + * Method validate stack version not to be + * empty or null. Also check if passed version + * has valid format. + * @param version string + * @return Matcher for passed version + * @throws IllegalArgumentException() if version empty/null/not valid + */ + private static Matcher validateStackVersion(String version) { + if (StringUtils.isEmpty(version)) { + throw new IllegalArgumentException("Stack version can't be empty or null"); + } + + String stackVersion = StringUtils.trim(version); + + Matcher versionMatcher = PATTERN_WITH_HOTFIX.matcher(stackVersion); + if (!versionMatcher.find()) { + versionMatcher = PATTERN_LEGACY_STACK_VERSION.matcher(stackVersion); + if (!versionMatcher.find()) { + throw new IllegalArgumentException("Wrong format for stack version, should be N.N.N.N-N or N.N.N-hN-bN"); + } + } + + return versionMatcher; + } + + /** + * Method validate mpack version not to be + * empty or null. Also check if passed version + * has valid format. + * @param version string + * @return Matcher for passed version + * @throws IllegalArgumentException() if version empty/null/not valid + */ + private static Matcher validateMpackVersion(String version) { + if (StringUtils.isEmpty(version)) { + throw new IllegalArgumentException("Mpack version can't be empty or null"); + } + + String mpackVersion = StringUtils.trim(version); + + Matcher versionMatcher = PATTERN_WITH_HOTFIX.matcher(mpackVersion); + if (!versionMatcher.find()) { + versionMatcher = PATTERN_WITHOUT_HOTFIX.matcher(mpackVersion); + if (!versionMatcher.find()) { + throw new IllegalArgumentException("Wrong format for mpack version, should be N.N.N-bN or N.N.N-hN-bN"); + } + } + + return versionMatcher; + } + + @Override + public int compareTo(MpackVersion other) { + int result = this.major - other.major; + if(result == 0) { + result = this.minor - other.minor; + if(result == 0) { + result = this.maint - other.maint; + if(result == 0) { + result = this.hotfix - other.hotfix; + if(result == 0) { + result = this.build - other.build; + } + } + } + } + return result > 0 ? 1 : result < 0 ? -1 : 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + MpackVersion that = (MpackVersion) o; + + if (build != that.build) return false; + if (hotfix != that.hotfix) return false; + if (maint != that.maint) return false; + if (major != that.major) return false; + if (minor != that.minor) return false; + + return true; + } + + @Override + public int hashCode() { + int result = major; + result = 31 * result + minor; + result = 31 * result + maint; + result = 31 * result + hotfix; + result = 31 * result + build; + return result; + } +} diff --git a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java index 42d321a..08c0a06 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java @@ -26,6 +26,10 @@ import junit.framework.Assert; public class TestVersionUtils { + private static final String MODULE_ERR_MESSAGE = "Module version can't be empty or null"; + private static final String STACK_ERR_MESSAGE = "Stack version can't be empty or null"; + private static final String MPACK_ERR_MESSAGE = "Mpack version can't be empty or null"; + @Rule public ExpectedException expectedException = ExpectedException.none(); @@ -168,4 +172,142 @@ public class TestVersionUtils { expectedException.expectMessage("maxLengthToCompare cannot be less than 0"); VersionUtils.compareVersions("2", "1", -1); } + + @Test + public void testMpackVersionWithNotValidVersions() { + String errMessage = null; + try { + MpackVersion.parse(null); + } catch (IllegalArgumentException e) { + errMessage = e.getMessage(); + } + Assert.assertEquals(MPACK_ERR_MESSAGE, errMessage); + + + try { + errMessage = null; + MpackVersion.parse(""); + } catch (IllegalArgumentException e) { + errMessage = e.getMessage(); + } + Assert.assertEquals(MPACK_ERR_MESSAGE, errMessage); + + try { + errMessage = null; + MpackVersion.parse("1.2.3.4-b10"); + } catch (IllegalArgumentException e) { + errMessage = e.getMessage(); + } + Assert.assertEquals("Wrong format for mpack version, should be N.N.N-bN or N.N.N-hN-bN", errMessage); + } + + + @Test + public void testStackVersionWithNotValidVersions() { + String errMessage = null; + try { + errMessage = null; + MpackVersion.parseStackVersion(null); + } catch (IllegalArgumentException e) { + errMessage = e.getMessage(); + } + Assert.assertEquals(STACK_ERR_MESSAGE, errMessage); + + + try { + errMessage = null; + MpackVersion.parseStackVersion(""); + } catch (IllegalArgumentException e) { + errMessage = e.getMessage(); + } + Assert.assertEquals(STACK_ERR_MESSAGE, errMessage); + + try { + errMessage = null; + MpackVersion.parseStackVersion("1.2.3-10"); + } catch (IllegalArgumentException e) { + errMessage = e.getMessage(); + } + Assert.assertEquals("Wrong format for stack version, should be N.N.N.N-N or N.N.N-hN-bN", errMessage); + } + + + @Test + public void testModuleVersionWithNotValidVersions() { + String errMessage = null; + try { + errMessage = null; + ModuleVersion.parse(null); + } catch (IllegalArgumentException e) { + errMessage = e.getMessage(); + } + Assert.assertEquals(MODULE_ERR_MESSAGE, errMessage); + + + try { + errMessage = null; + ModuleVersion.parse(""); + } catch (IllegalArgumentException e) { + errMessage = e.getMessage(); + } + Assert.assertEquals(MODULE_ERR_MESSAGE, errMessage); + + + try { + errMessage = null; + ModuleVersion.parse("1.2.3-10"); + } catch (IllegalArgumentException e) { + errMessage = e.getMessage(); + } + Assert.assertEquals("Wrong format for module version, should be N.N.N.N-bN or N.N.N-hN-bN", errMessage); + } + + @Test + public void testMpackVersionWithValidVersions() { + Assert.assertEquals(1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parse("1.2.3-b888"))); + Assert.assertEquals(1, MpackVersion.parse("2.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-b888"))); + Assert.assertEquals(1, MpackVersion.parse("1.3.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-b888"))); + Assert.assertEquals(1, MpackVersion.parse("1.2.4-h0-b10").compareTo(MpackVersion.parse("1.2.3-b888"))); + Assert.assertEquals(1, MpackVersion.parse("1.2.3-h0-b1000").compareTo(MpackVersion.parse("1.2.3-b888"))); + Assert.assertEquals(0, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-b10"))); + Assert.assertEquals(0, MpackVersion.parse("1.2.3-b10").compareTo(MpackVersion.parse("1.2.3-b10"))); + Assert.assertEquals(0, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-h0-b10"))); + Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.4-b10"))); + Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.3.3-b10"))); + Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("2.2.3-b10"))); + Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-h1-b10"))); + Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-h0-b11"))); + } + + @Test + public void testStackVersionWithValidVersions() { + Assert.assertEquals(1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888"))); + Assert.assertEquals(1, MpackVersion.parseStackVersion("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888"))); + Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.11-888"))); + Assert.assertEquals(1, MpackVersion.parseStackVersion("1.2.3.4-999").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888"))); + Assert.assertEquals(0, MpackVersion.parseStackVersion("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3-h10-b10"))); + Assert.assertEquals(0, MpackVersion.parseStackVersion("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.10-10"))); + Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("2.2.3.4-888"))); + } + + @Test + public void testModuleVersionWithValidVersions() { + Assert.assertEquals(1, ModuleVersion.parse("1.2.3.4-h10-b888").compareTo(ModuleVersion.parse("1.2.3.4-b888"))); + Assert.assertEquals(1, ModuleVersion.parse("1.2.3.5-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10"))); + Assert.assertEquals(1, ModuleVersion.parse("1.2.4.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10"))); + Assert.assertEquals(1, ModuleVersion.parse("1.3.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10"))); + Assert.assertEquals(1, ModuleVersion.parse("2.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10"))); + Assert.assertEquals(1, ModuleVersion.parse("1.2.3.4-h0-b11").compareTo(ModuleVersion.parse("1.2.3.4-b10"))); + + Assert.assertEquals(0, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10"))); + Assert.assertEquals(0, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-h0-b10"))); + Assert.assertEquals(0, ModuleVersion.parse("1.2.3.4-b10").compareTo(ModuleVersion.parse("1.2.3.4-b10"))); + Assert.assertEquals(0, ModuleVersion.parse("1.2.3.4-b10").compareTo(ModuleVersion.parse("1.2.3.4-h0-b10"))); + + Assert.assertEquals(-1, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.4-b888"))); + Assert.assertEquals(-1, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.3.5-b10"))); + Assert.assertEquals(-1, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.2.4.4-b10"))); + Assert.assertEquals(-1, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("1.3.3.4-b10"))); + Assert.assertEquals(-1, ModuleVersion.parse("1.2.3.4-h0-b10").compareTo(ModuleVersion.parse("2.2.3.4-b10"))); + } } diff --git a/ambari-server/src/test/python/TestVersion.py b/ambari-server/src/test/python/TestVersion.py index a8f4c65..0b66478 100644 --- a/ambari-server/src/test/python/TestVersion.py +++ b/ambari-server/src/test/python/TestVersion.py @@ -16,8 +16,10 @@ See the License for the specific language governing permissions and limitations under the License. ''' -from unittest import TestCase import os +from unittest import TestCase +from resource_management.libraries.functions.mpack_version import MpackVersion +from resource_management.libraries.functions.module_version import ModuleVersion class TestVersion(TestCase): @@ -80,4 +82,98 @@ class TestVersion(TestCase): except ValueError: pass else: - self.fail("Did not raise exception") \ No newline at end of file + self.fail("Did not raise exception") + + + def test_mpack_version(self): + try: + MpackVersion.parse("") + except ValueError: + pass + else: + self.fail("Did not raise exception") + + try: + MpackVersion.parse(None) + except ValueError: + pass + else: + self.fail("Did not raise exception") + + try: + MpackVersion.parse_stack_version("") + except ValueError: + pass + else: + self.fail("Did not raise exception") + + try: + MpackVersion.parse_stack_version(None) + except ValueError: + pass + else: + self.fail("Did not raise exception") + + try: + ModuleVersion.parse("") + except ValueError: + pass + else: + self.fail("Did not raise exception") + + try: + ModuleVersion.parse(None) + except ValueError: + pass + else: + self.fail("Did not raise exception") + + + try: + MpackVersion.parse("1.2.3.4-h1-b1") + except ValueError: + pass + else: + self.fail("Did not raise exception") + + try: + MpackVersion.parse_stack_version("1.1.1.1.1-1") + except ValueError: + pass + else: + self.fail("Did not raise exception") + + + try: + ModuleVersion.parse("1.1.1.1-h1") + except ValueError: + pass + else: + self.fail("Did not raise exception") + + m1 = MpackVersion.parse("1.2.3-h1-b2") + m2 = MpackVersion.parse("1.2.3-b2") + self.assertTrue(m1 > m2) + + m1 = MpackVersion.parse("1.2.3-h1-b2") + m2 = MpackVersion.parse_stack_version("1.2.3.4-33") + self.assertTrue(m1 < m2) + + m1 = MpackVersion.parse("1.2.3-h0-b10") + m2 = MpackVersion.parse("1.2.3-b10") + self.assertTrue(m1 == m2) + + m1 = ModuleVersion.parse("1.2.3.4-h10-b10") + m2 = ModuleVersion.parse("1.2.3.4-b888") + self.assertTrue(m1 > m2) + + m1 = ModuleVersion.parse("1.2.3.5-h10-b10") + m2 = ModuleVersion.parse("1.2.3.4-b888") + self.assertTrue(m1 > m2) + + m1 = ModuleVersion.parse("1.2.3.4-h0-b10") + m2 = ModuleVersion.parse("1.2.3.4-b10") + self.assertTrue(m1 == m2) + + +