|
| 1 | +import jsonpatch |
| 2 | +import unittest |
| 3 | +import copy |
| 4 | +from unittest.mock import MagicMock, Mock |
| 5 | +from mock import patch |
| 6 | + |
| 7 | +import generic_config_updater.change_applier |
| 8 | +import generic_config_updater.patch_sorter as ps |
| 9 | +import generic_config_updater.generic_updater as gu |
| 10 | +from .gutest_helpers import Files |
| 11 | +from generic_config_updater.gu_common import ConfigWrapper, PatchWrapper |
| 12 | + |
| 13 | +running_config = {} |
| 14 | + |
| 15 | +def set_entry(config_db, tbl, key, data): |
| 16 | + global running_config |
| 17 | + if data != None: |
| 18 | + if tbl not in running_config: |
| 19 | + running_config[tbl] = {} |
| 20 | + running_config[tbl][key] = data |
| 21 | + else: |
| 22 | + assert tbl in running_config |
| 23 | + assert key in running_config[tbl] |
| 24 | + running_config[tbl].pop(key) |
| 25 | + if not running_config[tbl]: |
| 26 | + running_config.pop(tbl) |
| 27 | + |
| 28 | +def get_running_config(): |
| 29 | + return running_config |
| 30 | + |
| 31 | +class TestFeaturePatchApplication(unittest.TestCase): |
| 32 | + def setUp(self): |
| 33 | + self.config_wrapper = ConfigWrapper() |
| 34 | + |
| 35 | + def test_feature_patch_application_success(self): |
| 36 | + # Format of the JSON file containing the test-cases: |
| 37 | + # |
| 38 | + # { |
| 39 | + # "<unique_name_for_the_test>":{ |
| 40 | + # "desc":"<brief explanation of the test case>", |
| 41 | + # "current_config":<the running config to be modified>, |
| 42 | + # "patch":<the JsonPatch to apply>, |
| 43 | + # "expected_config":<the config after jsonpatch modification> |
| 44 | + # }, |
| 45 | + # . |
| 46 | + # . |
| 47 | + # . |
| 48 | + # } |
| 49 | + data = Files.FEATURE_PATCH_APPLICATION_TEST_SUCCESS |
| 50 | + |
| 51 | + for test_case_name in data: |
| 52 | + with self.subTest(name=test_case_name): |
| 53 | + self.run_single_success_case_applier(data[test_case_name]) |
| 54 | + |
| 55 | + def test_feature_patch_application_failure(self): |
| 56 | + # Fromat of the JSON file containing the test-cases: |
| 57 | + # |
| 58 | + # { |
| 59 | + # "<unique_name_for_the_test>":{ |
| 60 | + # "desc":"<brief explanation of the test case>", |
| 61 | + # "current_config":<the running config to be modified>, |
| 62 | + # "patch":<the JsonPatch to apply>, |
| 63 | + # "expected_error_substrings":<error substrings expected in failure output> |
| 64 | + # }, |
| 65 | + # . |
| 66 | + # . |
| 67 | + # . |
| 68 | + # } |
| 69 | + data = Files.FEATURE_PATCH_APPLICATION_TEST_FAILURE |
| 70 | + |
| 71 | + for test_case_name in data: |
| 72 | + with self.subTest(name=test_case_name): |
| 73 | + self.run_single_failure_case_applier(data[test_case_name]) |
| 74 | + |
| 75 | + def create_patch_applier(self, config): |
| 76 | + global running_config |
| 77 | + running_config = copy.deepcopy(config) |
| 78 | + config_wrapper = self.config_wrapper |
| 79 | + config_wrapper.get_config_db_as_json = MagicMock(side_effect=get_running_config) |
| 80 | + change_applier = generic_config_updater.change_applier.ChangeApplier() |
| 81 | + change_applier._get_running_config = MagicMock(side_effect=get_running_config) |
| 82 | + patch_wrapper = PatchWrapper(config_wrapper) |
| 83 | + return gu.PatchApplier(config_wrapper=config_wrapper, patch_wrapper=patch_wrapper, changeapplier=change_applier) |
| 84 | + |
| 85 | + @patch("generic_config_updater.change_applier.get_config_db") |
| 86 | + @patch("generic_config_updater.change_applier.set_config") |
| 87 | + def run_single_success_case_applier(self, data, mock_set, mock_db): |
| 88 | + current_config = data["current_config"] |
| 89 | + mock_set.side_effect = set_entry |
| 90 | + expected_config = data["expected_config"] |
| 91 | + patch = jsonpatch.JsonPatch(data["patch"]) |
| 92 | + patch_applier = self.create_patch_applier(current_config) |
| 93 | + patch_applier.apply(patch) |
| 94 | + result_config = patch_applier.config_wrapper.get_config_db_as_json() |
| 95 | + |
| 96 | + self.assertEqual(expected_config, result_config) |
| 97 | + |
| 98 | + @patch("generic_config_updater.change_applier.get_config_db") |
| 99 | + def run_single_failure_case_applier(self, data, mock_db): |
| 100 | + current_config = data["current_config"] |
| 101 | + patch = jsonpatch.JsonPatch(data["patch"]) |
| 102 | + expected_error_substrings = data["expected_error_substrings"] |
| 103 | + |
| 104 | + try: |
| 105 | + patch_applier = self.create_patch_applier(current_config) |
| 106 | + patch_applier.apply(patch) |
| 107 | + self.fail("An exception was supposed to be thrown") |
| 108 | + except Exception as ex: |
| 109 | + notfound_substrings = [] |
| 110 | + error = str(ex) |
| 111 | + |
| 112 | + for substring in expected_error_substrings: |
| 113 | + if substring not in error: |
| 114 | + notfound_substrings.append(substring) |
| 115 | + |
| 116 | + if notfound_substrings: |
| 117 | + self.fail(f"Did not find the expected substrings {notfound_substrings} in the error: '{error}'") |
0 commit comments