summaryrefslogtreecommitdiffstats
path: root/tests/topotests/lib/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:53:30 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:53:30 +0000
commit2c7cac91ed6e7db0f6937923d2b57f97dbdbc337 (patch)
treec05dc0f8e6aa3accc84e3e5cffc933ed94941383 /tests/topotests/lib/test
parentInitial commit. (diff)
downloadfrr-2c7cac91ed6e7db0f6937923d2b57f97dbdbc337.tar.xz
frr-2c7cac91ed6e7db0f6937923d2b57f97dbdbc337.zip
Adding upstream version 8.4.4.upstream/8.4.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/topotests/lib/test')
-rw-r--r--tests/topotests/lib/test/__init__.py0
-rwxr-xr-xtests/topotests/lib/test/test_json.py641
-rwxr-xr-xtests/topotests/lib/test/test_run_and_expect.py79
-rwxr-xr-xtests/topotests/lib/test/test_version.py90
4 files changed, 810 insertions, 0 deletions
diff --git a/tests/topotests/lib/test/__init__.py b/tests/topotests/lib/test/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/topotests/lib/test/__init__.py
diff --git a/tests/topotests/lib/test/test_json.py b/tests/topotests/lib/test/test_json.py
new file mode 100755
index 0000000..7b3c859
--- /dev/null
+++ b/tests/topotests/lib/test/test_json.py
@@ -0,0 +1,641 @@
+#!/usr/bin/env python
+
+#
+# test_json.py
+# Tests for library function: json_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 json_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 json_cmp
+
+
+def test_json_intersect_true():
+ "Test simple correct JSON intersections"
+
+ dcomplete = {
+ "i1": "item1",
+ "i2": "item2",
+ "i3": "item3",
+ "i100": "item4",
+ }
+
+ dsub1 = {
+ "i1": "item1",
+ "i3": "item3",
+ }
+ dsub2 = {
+ "i1": "item1",
+ "i2": "item2",
+ }
+ dsub3 = {
+ "i100": "item4",
+ "i2": "item2",
+ }
+ dsub4 = {
+ "i50": None,
+ "i100": "item4",
+ }
+
+ assert json_cmp(dcomplete, dsub1) is None
+ assert json_cmp(dcomplete, dsub2) is None
+ assert json_cmp(dcomplete, dsub3) is None
+ assert json_cmp(dcomplete, dsub4) is None
+
+
+def test_json_intersect_false():
+ "Test simple incorrect JSON intersections"
+
+ dcomplete = {
+ "i1": "item1",
+ "i2": "item2",
+ "i3": "item3",
+ "i100": "item4",
+ }
+
+ # Incorrect value for 'i1'
+ dsub1 = {
+ "i1": "item3",
+ "i3": "item3",
+ }
+ # Non-existing key 'i5'
+ dsub2 = {
+ "i1": "item1",
+ "i5": "item2",
+ }
+ # Key should not exist
+ dsub3 = {
+ "i100": None,
+ }
+
+ assert json_cmp(dcomplete, dsub1) is not None
+ assert json_cmp(dcomplete, dsub2) is not None
+ assert json_cmp(dcomplete, dsub3) is not None
+
+
+def test_json_intersect_multilevel_true():
+ "Test multi level correct JSON intersections"
+
+ dcomplete = {
+ "i1": "item1",
+ "i2": "item2",
+ "i3": {
+ "i100": "item100",
+ },
+ "i4": {
+ "i41": {
+ "i411": "item411",
+ },
+ "i42": {
+ "i421": "item421",
+ "i422": "item422",
+ },
+ },
+ }
+
+ dsub1 = {
+ "i1": "item1",
+ "i3": {
+ "i100": "item100",
+ },
+ "i10": None,
+ }
+ dsub2 = {
+ "i1": "item1",
+ "i2": "item2",
+ "i3": {},
+ }
+ dsub3 = {
+ "i2": "item2",
+ "i4": {
+ "i41": {
+ "i411": "item411",
+ },
+ "i42": {
+ "i422": "item422",
+ "i450": None,
+ },
+ },
+ }
+ dsub4 = {
+ "i2": "item2",
+ "i4": {
+ "i41": {},
+ "i42": {
+ "i450": None,
+ },
+ },
+ }
+ dsub5 = {
+ "i2": "item2",
+ "i3": {
+ "i100": "item100",
+ },
+ "i4": {
+ "i42": {
+ "i450": None,
+ }
+ },
+ }
+
+ assert json_cmp(dcomplete, dsub1) is None
+ assert json_cmp(dcomplete, dsub2) is None
+ assert json_cmp(dcomplete, dsub3) is None
+ assert json_cmp(dcomplete, dsub4) is None
+ assert json_cmp(dcomplete, dsub5) is None
+
+
+def test_json_intersect_multilevel_false():
+ "Test multi level incorrect JSON intersections"
+
+ dcomplete = {
+ "i1": "item1",
+ "i2": "item2",
+ "i3": {
+ "i100": "item100",
+ },
+ "i4": {
+ "i41": {
+ "i411": "item411",
+ },
+ "i42": {
+ "i421": "item421",
+ "i422": "item422",
+ },
+ },
+ }
+
+ # Incorrect sub-level value
+ dsub1 = {
+ "i1": "item1",
+ "i3": {
+ "i100": "item00",
+ },
+ "i10": None,
+ }
+ # Inexistent sub-level
+ dsub2 = {
+ "i1": "item1",
+ "i2": "item2",
+ "i3": None,
+ }
+ # Inexistent sub-level value
+ dsub3 = {
+ "i1": "item1",
+ "i3": {
+ "i100": None,
+ },
+ }
+ # Inexistent sub-sub-level value
+ dsub4 = {
+ "i4": {
+ "i41": {
+ "i412": "item412",
+ },
+ "i42": {
+ "i421": "item421",
+ },
+ }
+ }
+ # Invalid sub-sub-level value
+ dsub5 = {
+ "i4": {
+ "i41": {
+ "i411": "item411",
+ },
+ "i42": {
+ "i421": "item420000",
+ },
+ }
+ }
+ # sub-sub-level should be value
+ dsub6 = {
+ "i4": {
+ "i41": {
+ "i411": "item411",
+ },
+ "i42": "foobar",
+ }
+ }
+
+ assert json_cmp(dcomplete, dsub1) is not None
+ assert json_cmp(dcomplete, dsub2) is not None
+ assert json_cmp(dcomplete, dsub3) is not None
+ assert json_cmp(dcomplete, dsub4) is not None
+ assert json_cmp(dcomplete, dsub5) is not None
+ assert json_cmp(dcomplete, dsub6) is not None
+
+
+def test_json_with_list_sucess():
+ "Test successful json comparisons that have lists."
+
+ dcomplete = {
+ "list": [
+ {
+ "i1": "item 1",
+ "i2": "item 2",
+ },
+ {
+ "i10": "item 10",
+ },
+ ],
+ "i100": "item 100",
+ }
+
+ # Test list type
+ dsub1 = {
+ "list": [],
+ }
+ # Test list correct list items
+ dsub2 = {
+ "list": [
+ {
+ "i1": "item 1",
+ },
+ ],
+ "i100": "item 100",
+ }
+ # Test list correct list size
+ dsub3 = {
+ "list": [
+ {},
+ {},
+ ],
+ }
+
+ assert json_cmp(dcomplete, dsub1) is None
+ assert json_cmp(dcomplete, dsub2) is None
+ assert json_cmp(dcomplete, dsub3) is None
+
+
+def test_json_with_list_failure():
+ "Test failed json comparisons that have lists."
+
+ dcomplete = {
+ "list": [
+ {
+ "i1": "item 1",
+ "i2": "item 2",
+ },
+ {
+ "i10": "item 10",
+ },
+ ],
+ "i100": "item 100",
+ }
+
+ # Test list type
+ dsub1 = {
+ "list": {},
+ }
+ # Test list incorrect list items
+ dsub2 = {
+ "list": [
+ {
+ "i1": "item 2",
+ },
+ ],
+ "i100": "item 100",
+ }
+ # Test list correct list size
+ dsub3 = {
+ "list": [
+ {},
+ {},
+ {},
+ ],
+ }
+
+ assert json_cmp(dcomplete, dsub1) is not None
+ assert json_cmp(dcomplete, dsub2) is not None
+ assert json_cmp(dcomplete, dsub3) is not None
+
+
+def test_json_list_start_success():
+ "Test JSON encoded data that starts with a list that should succeed."
+
+ dcomplete = [
+ {
+ "id": 100,
+ "value": "abc",
+ },
+ {
+ "id": 200,
+ "value": "abcd",
+ },
+ {
+ "id": 300,
+ "value": "abcde",
+ },
+ ]
+
+ dsub1 = [
+ {
+ "id": 100,
+ "value": "abc",
+ }
+ ]
+
+ dsub2 = [
+ {
+ "id": 100,
+ "value": "abc",
+ },
+ {
+ "id": 200,
+ "value": "abcd",
+ },
+ ]
+
+ dsub3 = [
+ {
+ "id": 300,
+ "value": "abcde",
+ }
+ ]
+
+ dsub4 = []
+
+ dsub5 = [
+ {
+ "id": 100,
+ }
+ ]
+
+ assert json_cmp(dcomplete, dsub1) is None
+ assert json_cmp(dcomplete, dsub2) is None
+ assert json_cmp(dcomplete, dsub3) is None
+ assert json_cmp(dcomplete, dsub4) is None
+ assert json_cmp(dcomplete, dsub5) is None
+
+
+def test_json_list_start_failure():
+ "Test JSON encoded data that starts with a list that should fail."
+
+ dcomplete = [
+ {"id": 100, "value": "abc"},
+ {"id": 200, "value": "abcd"},
+ {"id": 300, "value": "abcde"},
+ ]
+
+ dsub1 = [
+ {
+ "id": 100,
+ "value": "abcd",
+ }
+ ]
+
+ dsub2 = [
+ {
+ "id": 100,
+ "value": "abc",
+ },
+ {
+ "id": 200,
+ "value": "abc",
+ },
+ ]
+
+ dsub3 = [
+ {
+ "id": 100,
+ "value": "abc",
+ },
+ {
+ "id": 350,
+ "value": "abcde",
+ },
+ ]
+
+ dsub4 = [
+ {
+ "value": "abcx",
+ },
+ {
+ "id": 300,
+ "value": "abcde",
+ },
+ ]
+
+ assert json_cmp(dcomplete, dsub1) is not None
+ assert json_cmp(dcomplete, dsub2) is not None
+ assert json_cmp(dcomplete, dsub3) is not None
+ assert json_cmp(dcomplete, dsub4) is not None
+
+
+def test_json_list_ordered():
+ "Test JSON encoded data that should be ordered using the '__ordered__' tag."
+
+ dcomplete = [
+ {"id": 1, "value": "abc"},
+ "some string",
+ 123,
+ ]
+
+ dsub1 = [
+ "__ordered__",
+ "some string",
+ {"id": 1, "value": "abc"},
+ 123,
+ ]
+
+ assert json_cmp(dcomplete, dsub1) is not None
+
+
+def test_json_list_exact_matching():
+ "Test JSON array on exact matching using the 'exact' parameter."
+
+ dcomplete = [
+ {"id": 1, "value": "abc"},
+ "some string",
+ 123,
+ [1, 2, 3],
+ ]
+
+ dsub1 = [
+ "some string",
+ {"id": 1, "value": "abc"},
+ 123,
+ [1, 2, 3],
+ ]
+
+ dsub2 = [
+ {"id": 1},
+ "some string",
+ 123,
+ [1, 2, 3],
+ ]
+
+ dsub3 = [
+ {"id": 1, "value": "abc"},
+ "some string",
+ 123,
+ [1, 3, 2],
+ ]
+
+ assert json_cmp(dcomplete, dsub1, exact=True) is not None
+ assert json_cmp(dcomplete, dsub2, exact=True) is not None
+
+
+def test_json_object_exact_matching():
+ "Test JSON object on exact matching using the 'exact' parameter."
+
+ dcomplete = {
+ "a": {"id": 1, "value": "abc"},
+ "b": "some string",
+ "c": 123,
+ "d": [1, 2, 3],
+ }
+
+ dsub1 = {
+ "a": {"id": 1, "value": "abc"},
+ "c": 123,
+ "d": [1, 2, 3],
+ }
+
+ dsub2 = {
+ "a": {"id": 1},
+ "b": "some string",
+ "c": 123,
+ "d": [1, 2, 3],
+ }
+
+ dsub3 = {
+ "a": {"id": 1, "value": "abc"},
+ "b": "some string",
+ "c": 123,
+ "d": [1, 3],
+ }
+
+ assert json_cmp(dcomplete, dsub1, exact=True) is not None
+ assert json_cmp(dcomplete, dsub2, exact=True) is not None
+ assert json_cmp(dcomplete, dsub3, exact=True) is not None
+
+
+def test_json_list_asterisk_matching():
+ "Test JSON array elements on matching '*' as a placeholder for arbitrary data."
+
+ dcomplete = [
+ {"id": 1, "value": "abc"},
+ "some string",
+ 123,
+ [1, 2, 3],
+ ]
+
+ dsub1 = [
+ "*",
+ "some string",
+ 123,
+ [1, 2, 3],
+ ]
+
+ dsub2 = [
+ {"id": "*", "value": "abc"},
+ "some string",
+ 123,
+ [1, 2, 3],
+ ]
+
+ dsub3 = [
+ {"id": 1, "value": "abc"},
+ "some string",
+ 123,
+ [1, "*", 3],
+ ]
+
+ dsub4 = [
+ "*",
+ "some string",
+ "*",
+ [1, 2, 3],
+ ]
+
+ assert json_cmp(dcomplete, dsub1) is None
+ assert json_cmp(dcomplete, dsub2) is None
+ assert json_cmp(dcomplete, dsub3) is None
+ assert json_cmp(dcomplete, dsub4) is None
+
+
+def test_json_object_asterisk_matching():
+ "Test JSON object value elements on matching '*' as a placeholder for arbitrary data."
+
+ dcomplete = {
+ "a": {"id": 1, "value": "abc"},
+ "b": "some string",
+ "c": 123,
+ "d": [1, 2, 3],
+ }
+
+ dsub1 = {
+ "a": "*",
+ "b": "some string",
+ "c": 123,
+ "d": [1, 2, 3],
+ }
+
+ dsub2 = {
+ "a": {"id": 1, "value": "abc"},
+ "b": "some string",
+ "c": 123,
+ "d": [1, "*", 3],
+ }
+
+ dsub3 = {
+ "a": {"id": "*", "value": "abc"},
+ "b": "some string",
+ "c": 123,
+ "d": [1, 2, 3],
+ }
+
+ dsub4 = {
+ "a": "*",
+ "b": "some string",
+ "c": "*",
+ "d": [1, 2, 3],
+ }
+
+ assert json_cmp(dcomplete, dsub1) is None
+ assert json_cmp(dcomplete, dsub2) is None
+ assert json_cmp(dcomplete, dsub3) is None
+ assert json_cmp(dcomplete, dsub4) is None
+
+
+def test_json_list_nested_with_objects():
+
+ dcomplete = [{"key": 1, "list": [123]}, {"key": 2, "list": [123]}]
+
+ dsub1 = [{"key": 2, "list": [123]}, {"key": 1, "list": [123]}]
+
+ assert json_cmp(dcomplete, dsub1) is None
+
+
+if __name__ == "__main__":
+ sys.exit(pytest.main())
diff --git a/tests/topotests/lib/test/test_run_and_expect.py b/tests/topotests/lib/test/test_run_and_expect.py
new file mode 100755
index 0000000..d65d5ba
--- /dev/null
+++ b/tests/topotests/lib/test/test_run_and_expect.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+#
+# test_run_and_expect.py
+# Tests for library function: run_and_expect(_type)().
+#
+# Copyright (c) 2019 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 `run_and_expect(_type)()` functions.
+"""
+
+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 run_and_expect_type
+
+
+def test_run_and_expect_type():
+ "Test basic `run_and_expect_type` functionality."
+
+ def return_true():
+ "Test function that returns `True`."
+ return True
+
+ # Test value success.
+ success, value = run_and_expect_type(
+ return_true, bool, count=1, wait=0, avalue=True
+ )
+ assert success is True
+ assert value is True
+
+ # Test value failure.
+ success, value = run_and_expect_type(
+ return_true, bool, count=1, wait=0, avalue=False
+ )
+ assert success is False
+ assert value is True
+
+ # Test type success.
+ success, value = run_and_expect_type(return_true, bool, count=1, wait=0)
+ assert success is True
+ assert value is True
+
+ # Test type failure.
+ success, value = run_and_expect_type(return_true, str, count=1, wait=0)
+ assert success is False
+ assert value is True
+
+ # Test type failure, return correct type.
+ success, value = run_and_expect_type(return_true, str, count=1, wait=0, avalue=True)
+ assert success is False
+ assert value is True
+
+
+if __name__ == "__main__":
+ sys.exit(pytest.main())
diff --git a/tests/topotests/lib/test/test_version.py b/tests/topotests/lib/test/test_version.py
new file mode 100755
index 0000000..7c2df00
--- /dev/null
+++ b/tests/topotests/lib/test/test_version.py
@@ -0,0 +1,90 @@
+#!/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)
+
+
+def test_regression_1():
+ """
+ Test regression on the following type of comparison: '3.0.2' > '3'
+ Expected result is 1.
+ """
+ assert version_cmp("3.0.2", "3") == 1