Skip to content

Commit

Permalink
Merge pull request #208 from vesposito/master
Browse files Browse the repository at this point in the history
Improve version handling to be on par with imcsdk
  • Loading branch information
vvb authored Aug 19, 2021
2 parents 57ac80f + 03bc1e1 commit f9c8926
Show file tree
Hide file tree
Showing 2 changed files with 250 additions and 21 deletions.
123 changes: 123 additions & 0 deletions tests/unit_tests/common/test_ucsversion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Copyright 2015 Cisco Systems, Inc.
#
# Licensed 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.

from nose.tools import assert_equal
from ucsmsdk.ucsmeta import VersionMeta
from ucsmsdk.ucscoremeta import UcsVersion


def test_nightly_version1():
version1 = UcsVersion("2.0(13aS6)")
version2 = UcsVersion("3.0(1S10)")
assert_equal((version1 < version2), True)


def test_nightly_version2():
version1 = UcsVersion("2.0(13aS6)")
version2 = UcsVersion("2.0(1S10)")
assert_equal((version1 > version2), True)


def test_nightly_version3():
# 2.0(2cS6) will be considered as 2.0(2d) internally
version1 = UcsVersion("2.0(2cS6)")
version2 = UcsVersion("2.0(2c)")
assert_equal((version1 == version2), False)


def test_nightly_version4():
version1 = UcsVersion("2.0(2cS6)")
version2 = UcsVersion("2.0(3)")
assert_equal((version1 < version2), True)


def test_spin_version1():
# version interpreted as 4.0(2b)
version1 = UcsVersion("4.0(2aS3)")
version2 = UcsVersion("4.0(2b)")
assert_equal((version1 == version2), True)


def test_spin_version2():
# version interpreted as 4.0(234c)
version1 = UcsVersion("4.0(234bS3)")
version2 = UcsVersion("4.0(234c)")
assert_equal((version1 == version2), True)


def test_spin_version3():
# version interpreted as 4.0(2z)
version1 = UcsVersion("4.0(2S3)")
version2 = UcsVersion("4.0(2z)")
assert_equal((version1 == version2), True)


def test_spin_version4():
# version interpreted as 4.0(234z)
version1 = UcsVersion("4.0(234S3)")
version2 = UcsVersion("4.0(234z)")
assert_equal((version1 == version2), True)


def test_patch_version1():
# version interpreted as 4.0(235a)
version1 = UcsVersion("4.0(234.5)")
version2 = UcsVersion("4.0(235a)")
assert_equal((version1 == version2), True)


def test_build_version1():
# 4.2(0.175a) is an engineering build that will later become 4.2(1a)
version1 = UcsVersion("4.2(0.175a)")
version2 = UcsVersion("4.2(1a)")
assert_equal((version1 < version2), True)


def test_build_version2():
version1 = UcsVersion("4.2(0.175a)")
version2 = UcsVersion("4.2(0.258a)")
assert_equal((version1 < version2), True)


def test_spin_version5():
# version interpreted as 4.2(2a)
version1 = UcsVersion("4.2(1.2021052301)")
version2 = UcsVersion("4.2(2a)")
assert_equal((version1 == version2), True)


def test_spin_version6():
# version interpreted as 4.2(1b)
version1 = UcsVersion("4.2(1a.2021052301)")
version2 = UcsVersion("4.2(1b)")
assert_equal((version1 == version2), True)


def test_gt_same_major_version():
version1 = VersionMeta.Version211a
version2 = VersionMeta.Version211e
assert_equal((version1 < version2), True)


def test_gt_different_major_version():
version1 = VersionMeta.Version404a
version2 = VersionMeta.Version412b
assert_equal((version1 < version2), True)


def test_patch_versions():
# when we don't see a patch version we use z
# so 2.0(12) will be considered as 2.0(12z)
version1 = UcsVersion("2.0(12b)")
version2 = UcsVersion("2.0(12)")
assert_equal((version1 > version2), False)
148 changes: 127 additions & 21 deletions ucsmsdk/ucscoremeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,41 +42,119 @@ def __init__(self, version):
return None

self.__version = version
self.__major = None
self.__minor = None
self.__mr = None
self.__patch = None
self.__spin = None
self.__build = None

match_pattern = re.compile("^(?P<major>[1-9][0-9]{0,2})\."
"(?P<minor>(([0-9])|([1-9][0-9]{0,1})))\("
"(?P<mr>(([0-9])|([1-9][0-9]{0,2})))\."
"(?P<patch>(([0-9])|([1-9][0-9]{0,4})))\)$")
match_obj = re.match(match_pattern, version)
if match_obj:
self.__major = match_obj.group("major")
self.__minor = match_obj.group("minor")
self.__mr = match_obj.group("mr")
self.__patch = match_obj.group("patch")
if self._set_versions(match_obj):
return

match_pattern = re.compile("^(?P<major>[1-9][0-9]{0,2})\."
"(?P<minor>(([0-9])|([1-9][0-9]{0,1})))\("
"(?P<mr>(([0-9])|([1-9][0-9]{0,2})))"
"(?P<patch>[a-z])\)$")
match_obj = re.match(match_pattern, version)
if match_obj:
self.__major = match_obj.group("major")
self.__minor = match_obj.group("minor")
self.__mr = match_obj.group("mr")
self.__patch = match_obj.group("patch")
if self._set_versions(match_obj):
return

match_pattern = re.compile("^(?P<major>[1-9][0-9]{0,2})\."
"(?P<minor>(([0-9])|([1-9][0-9]{0,1})))\("
"(?P<mr>(([0-9])|([1-9][0-9]{0,2})))\)$")
match_obj = re.match(match_pattern, version)
if match_obj:
self.__major = match_obj.group("major")
self.__minor = match_obj.group("minor")
self.__mr = match_obj.group("mr")
if self._set_versions(match_obj):
return

# handle spin builds "2.0(13aS1))"
match_pattern = re.compile("^(?P<major>[1-9][0-9]{0,2})\."
"(?P<minor>(([0-9])|([1-9][0-9]{0,1})))\("
"(?P<mr>(([0-9])|([1-9][0-9]{0,2})))"
"(?P<patch>[a-z])"
"(?P<spin>S[1-9][0-9]{0,2})\)$")
match_obj = re.match(match_pattern, version)
if self._set_versions(match_obj):
return

# handle spin builds "3.0(1S10))"
match_pattern = re.compile("^(?P<major>[1-9][0-9]{0,2})\."
"(?P<minor>(([0-9])|([1-9][0-9]{0,1})))\("
"(?P<mr>(([0-9])|([1-9][0-9]{0,2})))"
"(?P<spin>S[1-9][0-9]{0,2})\)$")
match_obj = re.match(match_pattern, version)
if self._set_versions(match_obj):
return

# handle de special builds "66.77(67.1582251418)"
match_pattern = re.compile("^(?P<major>[1-9][0-9]{0,2})\."
"(?P<minor>(([0-9])|([1-9][0-9]{0,2})))\("
"(?P<mr>(([0-9])|([1-9][0-9]{0,2})))\."
"(?P<patch>(([0-9])|([1-9][0-9]{0,})))\)$")
match_obj = re.match(match_pattern, version)
if self._set_versions(match_obj):
return

# handle engineering builds "4.2(0.175a)"
match_pattern = re.compile("^(?P<major>[1-9][0-9]{0,2})\."
"(?P<minor>(([0-9])|([1-9][0-9]{0,2})))\("
"(?P<mr>(([0-9])|([1-9][0-9]{0,2})))\."
"(?P<build>(([0-9])|([1-9][0-9]{0,})))"
"(?P<patch>[a-z])\)$")
match_obj = re.match(match_pattern, version)
if self._set_versions(match_obj):
return

# handle spin builds "4.2(1.2021052301)"
match_pattern = re.compile("^(?P<major>[1-9][0-9]{0,2})\."
"(?P<minor>(([0-9])|([1-9][0-9]{0,1})))\("
"(?P<mr>(([0-9])|([1-9][0-9]{0,2})))\."
"(?P<spin>\d{0,4}\d{0,2}\d{0,2}\d{0,2})\)$")
match_obj = re.match(match_pattern, version)
if self._set_versions(match_obj):
return

# handle patch spin builds "4.2(1a.2021052301)"
match_pattern = re.compile("^(?P<major>[1-9][0-9]{0,2})\."
"(?P<minor>(([0-9])|([1-9][0-9]{0,1})))\("
"(?P<mr>(([0-9])|([1-9][0-9]{0,2})))"
"(?P<patch>[a-z])\."
"(?P<spin>\d{0,4}\d{0,2}\d{0,2}\d{0,2})\)$")
match_obj = re.match(match_pattern, version)
if self._set_versions(match_obj):
return

def _set_versions(self, match_obj):
if not match_obj:
return False

match_dict = match_obj.groupdict()
self.__major = match_dict.get("major")
self.__minor = match_dict.get("minor")
self.__mr = match_dict.get("mr")
self.__patch = match_dict.get("patch")
self.__spin = match_dict.get("spin")
self.__build = match_dict.get("build")

# for spin builds 4.0(1S52), the patch version will be None
# In this scenario assume the version to be highest patch z
if self.__patch is None:
self.__patch = 'z'
elif self.__patch.isdigit() and self.__mr.isdigit():
log.debug("Interim version encountered: %s. MR version has been bumped up." % self.version)
self.__mr = str(int(self.__mr) + 1)
self.__patch = 'a'
elif self.__patch.isalpha() and self.__spin:
log.debug("Interim version encountered: %s. patch version has been bumped up." % self.version)
self.__patch = str(chr(ord(self.__patch) + 1))

return True

@property
def major(self):
"""Getter Method of UcsVersion Class"""
Expand All @@ -97,23 +175,48 @@ def patch(self):
"""Getter Method of UcsVersion Class"""
return self.__patch

@property
def spin(self):
"""Getter Method of UcsVersion Class"""
return self.__spin

@property
def build(self):
"""Getter Method of UcsVersion Class"""
return self.__build

@property
def version(self):
"""Getter Method of UcsVersion Class"""
return self.__version

def _compare(self, version1, version2):
if version1 == version2:
return 0
if not version1:
return -1
if not version2:
return 1

func = (ord, int)[version1.isdigit() and version2.isdigit()]
return func(version1) - func(version2)

def compare_to(self, version):
"""Method to compare UcsVersion."""
if version is None or not isinstance(version, UcsVersion):
return 1

if self.__major != version.major:
return ord(self.__major) - ord(version.major)
if self.__minor != version.minor:
return ord(self.__minor) - ord(version.minor)
if self.__mr != version.mr:
return ord(self.__mr) - ord(version.mr)
return ord(self.__patch) - ord(version.patch)
ret = 0
versions = [(self.__major, version.major),
(self.__minor, version.minor),
(self.__mr, version.mr),
(self.__build, version.build),
(self.__patch, version.patch)]
for item in versions:
ret = self._compare(item[0], item[1])
if ret:
return ret
return ret

def __gt__(self, version):
return self.compare_to(version) > 0
Expand All @@ -130,6 +233,9 @@ def __le__(self, version):
def __eq__(self, version):
return self.compare_to(version) == 0

def __ne__(self, version):
return self.compare_to(version) != 0

def __str__(self):
return self.__version

Expand Down

0 comments on commit f9c8926

Please sign in to comment.