From 3bb4c199817c8aa4ecd4ae684bd28f84933fb14d Mon Sep 17 00:00:00 2001 From: Victor Coutellier Date: Sun, 10 Mar 2019 19:07:00 +0100 Subject: [PATCH] Fix kolla-docker possible undefined variable It is possible to reference undefined variable in kolla-docker module if DockerWorker object initialization fail, so the current behaviour will crash the playbook with the unwanted error message : UnboundLocalError: local variable 'dw' referenced before assignment Change-Id: Ic8d26b11f93255220888b5406f8ab4a6f81736c2 Closes-Bug: #1819361 --- ansible/library/kolla_docker.py | 3 ++- tests/test_kolla_docker.py | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/ansible/library/kolla_docker.py b/ansible/library/kolla_docker.py index 38c0900771..063e240914 100644 --- a/ansible/library/kolla_docker.py +++ b/ansible/library/kolla_docker.py @@ -974,6 +974,7 @@ def generate_module(): def main(): module = generate_module() + dw = None try: dw = DockerWorker(module) # TODO(inc0): We keep it bool to have ansible deal with consistent @@ -983,7 +984,7 @@ def main(): module.exit_json(changed=dw.changed, result=result, **dw.result) except Exception: module.fail_json(changed=True, msg=repr(traceback.format_exc()), - **dw.result) + **getattr(dw, 'result', {})) if __name__ == '__main__': diff --git a/tests/test_kolla_docker.py b/tests/test_kolla_docker.py index 1a7d943529..1aab4617c1 100644 --- a/tests/test_kolla_docker.py +++ b/tests/test_kolla_docker.py @@ -113,6 +113,7 @@ class ModuleArgsTest(base.BaseTestCase): bypass_checks=False ) + FAKE_DATA = { 'params': { @@ -192,6 +193,43 @@ def get_DockerWorker(mod_param, mock_dclient): return dw +class TestMainModule(base.BaseTestCase): + + def setUp(self): + super(TestMainModule, self).setUp() + self.fake_data = copy.deepcopy(FAKE_DATA) + + @mock.patch("kolla_docker.traceback.format_exc") + @mock.patch("kolla_docker.get_docker_client") + @mock.patch("kolla_docker.generate_module") + def test_docker_client_exception(self, mock_generate_module, mock_dclient, + mock_traceback): + module_mock = mock.MagicMock() + mock_generate_module.return_value = module_mock + mock_dclient.side_effect = AttributeError() + mock_traceback.return_value = "Some very ugly traceback" + kd.main() + module_mock.fail_json.assert_called_once_with( + changed=True, msg=repr("Some very ugly traceback")) + + @mock.patch("kolla_docker.DockerWorker") + @mock.patch("kolla_docker.generate_module") + def test_execute_module(self, mock_generate_module, mock_dw): + mock_dw.return_value.check_image.return_value = False + mock_dw.return_value.changed = False + mock_dw.return_value.result = {"some_key": "some_value"} + module_mock = mock.MagicMock() + module_mock.params = self.fake_data['params'] + module_mock.params["action"] = "check_image" + mock_generate_module.return_value = module_mock + kd.main() + mock_dw.assert_called_once_with(module_mock) + mock_dw.return_value.check_image.assert_called_once_with() + module_mock.exit_json.assert_called_once_with(changed=False, + result=False, + some_key="some_value") + + class TestContainer(base.BaseTestCase): def setUp(self):