From 92d5f1d6e55c2eba311bed69a5e5faeb79378569 Mon Sep 17 00:00:00 2001 From: SegFaulti4 Date: Tue, 16 Jan 2024 21:18:48 +0300 Subject: [PATCH] Added tests for internal errors, simplified inventory file for tests, minor changes in excepthook --- .github/workflows/cotea_testing_workflow.yaml | 1 + src/cotea/runner.py | 16 ++--- src/cotea_internal_error_case.py | 66 +++++++++++++++++++ src/cotea_run_files/incorrect.yaml | 6 ++ src/cotea_run_files/inv | 5 +- 5 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 src/cotea_internal_error_case.py create mode 100644 src/cotea_run_files/incorrect.yaml diff --git a/.github/workflows/cotea_testing_workflow.yaml b/.github/workflows/cotea_testing_workflow.yaml index e2ec3f6..4bea0de 100644 --- a/.github/workflows/cotea_testing_workflow.yaml +++ b/.github/workflows/cotea_testing_workflow.yaml @@ -31,3 +31,4 @@ jobs: cd ./src python cotea_ok_case.py python cotea_ansible_error_case.py + python cotea_internal_error_case.py diff --git a/src/cotea/runner.py b/src/cotea/runner.py index 01afe12..12dc95f 100644 --- a/src/cotea/runner.py +++ b/src/cotea/runner.py @@ -123,15 +123,12 @@ def _set_wrappers_back(self): PlaybookExecutor.__init__ = self.playbook_executor_wrp.func def _except_hook(self, args, /): - exc_type, exc_value, exc_traceback, thread = \ - args.exc_type, args.exc_value, args.exc_traceback, args.thread - - if (exc_type == SystemExit or + if (args.exc_type == SystemExit or # NOTE: this probably should never happen - thread != self.ansible_thread): + args.thread != self.ansible_thread): return self._old_except_hook(args) - self.sync_obj.exception = exc_value + self.sync_obj.exception = args.exc_value self.sync_obj.continue_runner() def _start_ansible(self): @@ -318,10 +315,11 @@ def get_already_ignore_unrch(self): def finish_ansible(self): - while self.sync_obj.curr_breakpoint_label != self.breakpoint_labeles["after_playbook"]: - self.sync_obj.continue_ansible_with_stop() + if self.sync_obj.exception is None: + while self.sync_obj.curr_breakpoint_label != self.breakpoint_labeles["after_playbook"]: + self.sync_obj.continue_ansible_with_stop() + self.sync_obj.continue_ansible() - self.sync_obj.continue_ansible() self.ansible_thread.join(timeout=5) self._set_wrappers_back() diff --git a/src/cotea_internal_error_case.py b/src/cotea_internal_error_case.py new file mode 100644 index 0000000..e495dc4 --- /dev/null +++ b/src/cotea_internal_error_case.py @@ -0,0 +1,66 @@ +import unittest + + +class TestCotea(unittest.TestCase): + + def tearDown(self) -> None: + from cotea.utils import remove_modules_from_imported + + # Remove any Ansible-related objects from memory + # to clear previous execution context + remove_modules_from_imported(module_name_like="cotea") + + def test_incorrect_playbook_path_case(self): + from cotea.runner import runner + from cotea.arguments_maker import argument_maker + + pb_path = "cotea_run_files/#%|&" + inv_path = "cotea_run_files/inv" + + arg_maker = argument_maker() + arg_maker.add_arg("-i", inv_path) + r = runner(pb_path, arg_maker, show_progress_bar=True) + + try: + while r.has_next_play(): + while r.has_next_task(): + r.run_next_task() + r.finish_ansible() + except Exception as e: + r.finish_ansible() + self.assertTrue(hasattr(e, "message"), msg="Exception is expected to have 'message' attribute") + self.assertTrue(e.message.startswith(f"the playbook: {pb_path} could not be found"), + msg="Unexpected exception message") + else: + self.assertFalse(True, msg="Ansible is supposed to fail due to syntax error " + "and its' exception should be passed to main thread") + + def test_incorrect_syntax_case(self): + from cotea.runner import runner + from cotea.arguments_maker import argument_maker + + pb_path = "cotea_run_files/incorrect.yaml" + inv_path = "cotea_run_files/inv" + + arg_maker = argument_maker() + arg_maker.add_arg("-i", inv_path) + r = runner(pb_path, arg_maker, show_progress_bar=True) + + try: + while r.has_next_play(): + while r.has_next_task(): + r.run_next_task() + r.finish_ansible() + except Exception as e: + r.finish_ansible() + # NOTE: e should be AnsibleParserError, but "isinstance" returns False for some reason + self.assertTrue(hasattr(e, "message"), msg="Exception is expected to have 'message' attribute") + self.assertTrue(e.message.startswith("couldn't resolve module/action"), + msg="Unexpected exception message") + else: + self.assertFalse(True, msg="Ansible is supposed to fail due to syntax error " + "and its' exception should be passed to main thread") + + +if __name__ == '__main__': + unittest.main() diff --git a/src/cotea_run_files/incorrect.yaml b/src/cotea_run_files/incorrect.yaml new file mode 100644 index 0000000..1beadab --- /dev/null +++ b/src/cotea_run_files/incorrect.yaml @@ -0,0 +1,6 @@ +--- +- name: Play1 + hosts: all + tasks: + - name: Syntactically incorrect command + battle_star_engine: diff --git a/src/cotea_run_files/inv b/src/cotea_run_files/inv index 95fc38d..d0162e9 100644 --- a/src/cotea_run_files/inv +++ b/src/cotea_run_files/inv @@ -1,5 +1,2 @@ [host1] -host1 ansible_host=localhost ansible_connection=ssh ansible_ssh_port=2222 ansible_user=root ansible_password=amella - -[targets] -host1 \ No newline at end of file +localhost ansible_connection=ssh ansible_ssh_port=2222 ansible_user=root ansible_password=amella ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'