]> git.puffer.fish Git - mirror/frr.git/commitdiff
topotest: add version comparison function
authorRafael Zalamena <rzalamena@gmail.com>
Fri, 14 Jul 2017 17:00:52 +0000 (14:00 -0300)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 28 Nov 2018 01:22:11 +0000 (20:22 -0500)
Implemented a version comparison function that tells if a version
contained in a string is greater/less/equal to another.

tests/topotests/lib/test/test_version.py [new file with mode: 0644]
tests/topotests/lib/topotest.py

diff --git a/tests/topotests/lib/test/test_version.py b/tests/topotests/lib/test/test_version.py
new file mode 100644 (file)
index 0000000..4bb1c0b
--- /dev/null
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+#
+# test_version.py
+# Tests for library function: version_cmp().
+#
+# Copyright (c) 2017 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+Tests for the version_cmp() function.
+"""
+
+import os
+import sys
+import pytest
+
+# Save the Current Working Directory to find lib files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, '../../'))
+
+# pylint: disable=C0413
+from lib.topotest import version_cmp
+
+def test_valid_versions():
+    "Test valid version compare results"
+
+    curver = '3.0'
+    samever = '3'
+    oldver = '2.0'
+    newver = '3.0.1'
+    newerver = '3.0.11'
+    vercustom = '3.0-dev'
+    verysmallinc = '3.0.0.0.0.0.0.1'
+
+    assert version_cmp(curver, oldver) == 1
+    assert version_cmp(curver, newver) == -1
+    assert version_cmp(curver, curver) == 0
+    assert version_cmp(curver, newerver) == -1
+    assert version_cmp(newver, newerver) == -1
+    assert version_cmp(curver, samever) == 0
+    assert version_cmp(curver, vercustom) == 0
+    assert version_cmp(vercustom, vercustom) == 0
+    assert version_cmp(vercustom, oldver) == 1
+    assert version_cmp(vercustom, newver) == -1
+    assert version_cmp(vercustom, samever) == 0
+    assert version_cmp(curver, verysmallinc) == -1
+    assert version_cmp(newver, verysmallinc) == 1
+    assert version_cmp(verysmallinc, verysmallinc) == 0
+    assert version_cmp(vercustom, verysmallinc) == -1
+
+def test_invalid_versions():
+    "Test invalid version strings"
+
+    curver = '3.0'
+    badver1 = '.1'
+    badver2 = '-1.0'
+    badver3 = '.'
+    badver4 = '3.-0.3'
+
+    with pytest.raises(ValueError):
+        assert version_cmp(curver, badver1)
+        assert version_cmp(curver, badver2)
+        assert version_cmp(curver, badver3)
+        assert version_cmp(curver, badver4)
index b83d75a717781b39173e3cd3a34105fab3794281..7872e7087a1c50819cadba6e37784a338a9999af 100644 (file)
@@ -232,6 +232,61 @@ def normalize_text(text):
     text = re.sub(r'\r', '', text)
     return text
 
+def version_cmp(v1, v2):
+    """
+    Compare two version strings and returns:
+
+    * `-1`: if `v1` is less than `v2`
+    * `0`: if `v1` is equal to `v2`
+    * `1`: if `v1` is greater than `v2`
+
+    Raises `ValueError` if versions are not well formated.
+    """
+    vregex = r'(?P<whole>\d+(\.(\d+))*)'
+    v1m = re.match(vregex, v1)
+    v2m = re.match(vregex, v2)
+    if v1m is None or v2m is None:
+        raise ValueError("got a invalid version string")
+
+    # Split values
+    v1g = v1m.group('whole').split('.')
+    v2g = v2m.group('whole').split('.')
+
+    # Get the longest version string
+    vnum = len(v1g)
+    if len(v2g) > vnum:
+        vnum = len(v2g)
+
+    # Reverse list because we are going to pop the tail
+    v1g.reverse()
+    v2g.reverse()
+    for _ in range(vnum):
+        try:
+            v1n = int(v1g.pop())
+        except IndexError:
+            while v2g:
+                v2n = int(v2g.pop())
+                if v2n > 0:
+                    return -1
+            break
+
+        try:
+            v2n = int(v2g.pop())
+        except IndexError:
+            if v1n > 0:
+                return 1
+            while v1g:
+                v1n = int(v1g.pop())
+                if v1n > 0:
+                    return -1
+            break
+
+        if v1n > v2n:
+            return 1
+        if v1n < v2n:
+            return -1
+    return 0
+
 def checkAddressSanitizerError(output, router, component):
     "Checks for AddressSanitizer in output. If found, then logs it and returns true, false otherwise"