diff options
| author | omnom62 <omnom62@outlook.com> | 2026-09-16 11:14:08 +1000 |
|---|---|---|
| committer | omnom62 <omnom62@outlook.com> | 2026-09-16 11:14:08 +1000 |
| commit | d182306a5680c288fca3838395bba689f0626055 (patch) | |
| tree | 5674ba6b0a0d9fd507f09a0712cbd44657354a1b | |
| parent | 2150da570d603ba2c4d6319a54e300bb479ba945 (diff) | |
| download | rest.vyos-T8989_update_get_vaule.tar.gz rest.vyos-T8989_update_get_vaule.zip | |
T8989: get_values - AI fixes, add unit testT8989_update_get_vaule
| -rw-r--r-- | plugins/module_utils/vyos.py | 3 | ||||
| -rw-r--r-- | tests/unit/test_module_utils_vyos.py | 84 |
2 files changed, 85 insertions, 2 deletions
diff --git a/plugins/module_utils/vyos.py b/plugins/module_utils/vyos.py index eee3e56..b7a519e 100644 --- a/plugins/module_utils/vyos.py +++ b/plugins/module_utils/vyos.py @@ -373,7 +373,8 @@ class VyOSModule: rather than being indistinguishable from a valid empty response. """ result = self._client.show(path) - return result.get("data") or "" + data = result.get("data") + return "" if data is None else data def save_config(self, file_path=None): """Save the running configuration to disk.""" diff --git a/tests/unit/test_module_utils_vyos.py b/tests/unit/test_module_utils_vyos.py index 920e9a5..4b46eb1 100644 --- a/tests/unit/test_module_utils_vyos.py +++ b/tests/unit/test_module_utils_vyos.py @@ -14,7 +14,12 @@ __metaclass__ = type import unittest -from ansible_collections.vyos.rest.plugins.module_utils.vyos import cast_by_spec +from unittest.mock import MagicMock + +from ansible_collections.vyos.rest.plugins.module_utils.vyos import ( + VyOSModule, + cast_by_spec, +) class TestCastBySpecIntCollapse(unittest.TestCase): @@ -51,5 +56,82 @@ class TestCastBySpecIntCollapse(unittest.TestCase): self.assertIsNone(entry["distance"]) +class TestGetValue(unittest.TestCase): + """Regression tests for a confirmed bug (Copilot): get_value() + previously did `result.get("data") or ""`, which incorrectly + converts any falsy-but-valid scalar (0, False, an already-empty + string) into an empty string -- indistinguishable from the value + being genuinely unset. Fixed to only treat a missing "data" key + (None) as unset, leaving every other value -- including falsy + ones -- exactly as returned.""" + + def _vyos_with_data(self, data): + vyos = VyOSModule.__new__(VyOSModule) + vyos._client = MagicMock() + vyos._client.retrieve_return_value.return_value = {"data": data} + return vyos + + def test_zero_preserved_not_emptied(self): + vyos = self._vyos_with_data(0) + self.assertEqual(vyos.get_value(["some", "path"]), 0) + + def test_false_preserved_not_emptied(self): + vyos = self._vyos_with_data(False) + self.assertEqual(vyos.get_value(["some", "path"]), False) + + def test_genuine_string_value_passes_through(self): + vyos = self._vyos_with_data("vyos-core-01") + self.assertEqual(vyos.get_value(["some", "path"]), "vyos-core-01") + + def test_already_empty_string_stays_empty(self): + vyos = self._vyos_with_data("") + self.assertEqual(vyos.get_value(["some", "path"]), "") + + def test_missing_data_key_becomes_empty_string(self): + vyos = VyOSModule.__new__(VyOSModule) + vyos._client = MagicMock() + vyos._client.retrieve_return_value.return_value = {} + self.assertEqual(vyos.get_value(["some", "path"]), "") + + +class TestShow(unittest.TestCase): + """Regression tests for the same confirmed bug class as + TestGetValue, found independently in show(): `result.get("data") + or ""` incorrectly converts any falsy-but-valid scalar (0, False, + an already-empty string) from an operational show command into an + empty string -- indistinguishable from the command genuinely + returning nothing. Fixed to only treat a missing "data" key + (None) as empty, leaving every other value -- including falsy + ones -- exactly as returned.""" + + def _vyos_with_data(self, data): + vyos = VyOSModule.__new__(VyOSModule) + vyos._client = MagicMock() + vyos._client.show.return_value = {"data": data} + return vyos + + def test_zero_preserved_not_emptied(self): + vyos = self._vyos_with_data(0) + self.assertEqual(vyos.show(["some", "op", "path"]), 0) + + def test_false_preserved_not_emptied(self): + vyos = self._vyos_with_data(False) + self.assertEqual(vyos.show(["some", "op", "path"]), False) + + def test_genuine_output_passes_through(self): + vyos = self._vyos_with_data("interface eth0 up") + self.assertEqual(vyos.show(["some", "op", "path"]), "interface eth0 up") + + def test_already_empty_string_stays_empty(self): + vyos = self._vyos_with_data("") + self.assertEqual(vyos.show(["some", "op", "path"]), "") + + def test_missing_data_key_becomes_empty_string(self): + vyos = VyOSModule.__new__(VyOSModule) + vyos._client = MagicMock() + vyos._client.show.return_value = {} + self.assertEqual(vyos.show(["some", "op", "path"]), "") + + if __name__ == "__main__": unittest.main() |
