diff --git a/aci-preupgrade-validation-script.py b/aci-preupgrade-validation-script.py index b420eea..ed6d9c6 100644 --- a/aci-preupgrade-validation-script.py +++ b/aci-preupgrade-validation-script.py @@ -38,7 +38,7 @@ import os import re -SCRIPT_VERSION = "v4.1.0" +SCRIPT_VERSION = "v4.1.1" DEFAULT_TIMEOUT = 600 # sec # result constants DONE = 'DONE' @@ -1333,13 +1333,26 @@ class Result: """Class to hold the result of a check.""" __slots__ = ("result", "msg", "headers", "data", "unformatted_headers", "unformatted_data", "recommended_action", "doc_url") + @staticmethod + def _stringify_table_rows(rows): + """Convert every table cell value to string for stable sorting/printing.""" + if rows is None: + return [] + normalized = [] + for row in rows: + if isinstance(row, (list, tuple)): + normalized.append([str(col) for col in row]) + else: + normalized.append([str(row)]) + return normalized + def __init__(self, result=PASS, msg="", headers=None, data=None, unformatted_headers=None, unformatted_data=None, recommended_action="", doc_url=""): self.result = result self.msg = msg self.headers = headers if headers is not None else [] - self.data = data if data is not None else [] + self.data = self._stringify_table_rows(data) self.unformatted_headers = unformatted_headers if unformatted_headers is not None else [] - self.unformatted_data = unformatted_data if unformatted_data is not None else [] + self.unformatted_data = self._stringify_table_rows(unformatted_data) self.recommended_action = recommended_action self.doc_url = doc_url diff --git a/tests/checks/n9k_c9408_model_lem_count_check/test_n9k_c9408_model_lem_count_check.py b/tests/checks/n9k_c9408_model_lem_count_check/test_n9k_c9408_model_lem_count_check.py index 656f39f..9402760 100644 --- a/tests/checks/n9k_c9408_model_lem_count_check/test_n9k_c9408_model_lem_count_check.py +++ b/tests/checks/n9k_c9408_model_lem_count_check/test_n9k_c9408_model_lem_count_check.py @@ -71,7 +71,7 @@ "6.2(1g)", read_data(dir, "fabricNode_n9k_c9408.json"), script.FAIL_O, - [["101", "N9K-C9408", "N9K-X9400-16W", 6]], + [["101", "N9K-C9408", "N9K-X9400-16W", "6"]], "", ), # Applicable mid-train version 6.1(5e), less than 6 LEMs on C9408 -> PASS @@ -89,7 +89,7 @@ "6.1(5e)", read_data(dir, "fabricNode_n9k_c9408.json"), script.FAIL_O, - [["101", "N9K-C9408", "N9K-X9400-16W", 6]], + [["101", "N9K-C9408", "N9K-X9400-16W", "6"]], "", ), # Version not affected (fixed in 6.1(6)+) @@ -107,7 +107,7 @@ "6.1(2f)", read_data(dir, "fabricNode_n9k_c9408.json"), script.FAIL_O, - [["101", "N9K-C9408", "N9K-X9400-16W", 6]], + [["101", "N9K-C9408", "N9K-X9400-16W", "6"]], "", ), # Count only C9408 nodes and only matching LEM model @@ -117,8 +117,8 @@ read_data(dir, "fabricNode_mixed.json"), script.FAIL_O, [ - ["101", "N9K-C9408", "N9K-X9400-16W", 6], - ["102", "N9K-C9408", "N9K-X9400-16W", 6], + ["101", "N9K-C9408", "N9K-X9400-16W", "6"], + ["102", "N9K-C9408", "N9K-X9400-16W", "6"], ], "", ), diff --git a/tests/checks/r_leaf_compatibility_check/test_r_leaf_compatibility_check.py b/tests/checks/r_leaf_compatibility_check/test_r_leaf_compatibility_check.py index b5d53ab..31886b0 100644 --- a/tests/checks/r_leaf_compatibility_check/test_r_leaf_compatibility_check.py +++ b/tests/checks/r_leaf_compatibility_check/test_r_leaf_compatibility_check.py @@ -53,7 +53,7 @@ "4.1(2a)", "4.2(2a)", script.FAIL_O, - [["4.2(2a)", "Present", True]], + [["4.2(2a)", "Present", "True"]], ), # PASS - bug version upgrade, no RL ( @@ -80,7 +80,7 @@ "4.2(3a)", "5.2(3a)", script.FAIL_O, - [["5.2(3a)", "Present", False]], + [["5.2(3a)", "Present", "False"]], ), # PASS - Fix ver to 5.x, no RL ( diff --git a/tests/checks/rogue_ep_coop_exception_mac_check/test_rogue_ep_coop_exception_mac_check.py b/tests/checks/rogue_ep_coop_exception_mac_check/test_rogue_ep_coop_exception_mac_check.py index f19dd7d..bb1a667 100644 --- a/tests/checks/rogue_ep_coop_exception_mac_check/test_rogue_ep_coop_exception_mac_check.py +++ b/tests/checks/rogue_ep_coop_exception_mac_check/test_rogue_ep_coop_exception_mac_check.py @@ -66,14 +66,14 @@ "6.0(3e)", "5.2(3e)", script.FAIL_O, - [[5, "N/A"]], + [["5", "N/A"]], ), ( {exception_mac_api: read_data(dir, "rogue_mac_response.json")}, "6.1(3g)", "5.2(3e)", script.FAIL_O, - [[5, "N/A"]], + [["5", "N/A"]], ), # Affected (post-APIC upgrade, pre-switch upgrade) cases # tversion == cversion (affected target), no exception MACs @@ -121,7 +121,7 @@ "6.0(3e)", "6.0(3e)", script.FAIL_O, - [[5, "only 31 found out of 32"]], + [["5", "only 31 found out of 32"]], ), ( { @@ -131,7 +131,7 @@ "6.1(3g)", "6.1(3g)", script.FAIL_O, - [[5, "only 31 found out of 32"]], + [["5", "only 31 found out of 32"]], ), ( { @@ -141,7 +141,7 @@ "6.0(3e)", "6.0(3e)", script.FAIL_O, - [[5, "only 27 found out of 32"]], + [["5", "only 27 found out of 32"]], ), ( { @@ -151,7 +151,7 @@ "6.1(3g)", "6.1(3g)", script.FAIL_O, - [[5, "only 27 found out of 32"]], + [["5", "only 27 found out of 32"]], ), ( { @@ -161,7 +161,7 @@ "6.0(3e)", "6.0(3e)", script.FAIL_O, - [[5, "only 1 found out of 32"]], + [["5", "only 1 found out of 32"]], ), ( { @@ -171,7 +171,7 @@ "6.1(3g)", "6.1(3g)", script.FAIL_O, - [[5, "only 1 found out of 32"]], + [["5", "only 1 found out of 32"]], ), ( { @@ -181,7 +181,7 @@ "6.0(3e)", "6.0(3e)", script.FAIL_O, - [[5, "only 0 found out of 32"]], + [["5", "only 0 found out of 32"]], ), ( { @@ -191,7 +191,7 @@ "6.1(3g)", "6.1(3g)", script.FAIL_O, - [[5, "only 0 found out of 32"]], + [["5", "only 0 found out of 32"]], ), ], ) diff --git a/tests/test_Result.py b/tests/test_Result.py new file mode 100644 index 0000000..d899a56 --- /dev/null +++ b/tests/test_Result.py @@ -0,0 +1,28 @@ +import importlib + +script = importlib.import_module("aci-preupgrade-validation-script") + + +def test_print_result_handles_mixed_type_rows_without_error(): + # Verify that Result stringifies all cell values, so data.sort() in print_result never fails. + r = script.Result( + result=script.FAIL_O, + headers=["col1"], + data=[[1], ["2"]], + unformatted_headers=["col1"], + unformatted_data=[[3], ["4"]], + ) + # All values must already be strings after construction. + assert r.data == [["1"], ["2"]] + assert r.unformatted_data == [["3"], ["4"]] + # print_result must not raise. + script.print_result( + index=1, + total=1, + title="Mixed type table", + result=script.FAIL_O, + headers=r.headers, + data=r.data, + unformatted_headers=r.unformatted_headers, + unformatted_data=r.unformatted_data, + )