def test_one_failed_step_is_preventing_next_steps_from_execution_and_result_is_marked_as_failure(self): """Check the correctness of error handling""" io = IO() str_io = StringIO() buffered = BufferedSystemIO() task_declaration = get_test_declaration() BasicTestingCase.satisfy_task_dependencies(task_declaration.get_task_to_execute(), io=buffered) ctx = ExecutionContext(task_declaration) executor = DeclarativeExecutor() executor.add_step('python', 'this.io().outln("Peter Kropotkin"); return True', task_name=':first', rkd_path='', envs={}) executor.add_step('bash', 'echo "Buenaventura Durruti"; exit 1', task_name=':second', rkd_path='', envs={}) executor.add_step('python', 'this.io().outln("This one will not show"); return True', task_name=':third', rkd_path='', envs={}) with io.capture_descriptors(target_files=[], stream=str_io, enable_standard_out=False): final_result = executor.execute_steps_one_by_one(ctx, task_declaration.get_task_to_execute()) output = str_io.getvalue() + buffered.get_value() self.assertIn('Peter Kropotkin', output) self.assertIn('Buenaventura Durruti', output) self.assertNotIn('This one will not show', output) self.assertEqual(False, final_result)
def test_is_information_written_through_stderr_methods(self): """To check if information is written to the proper methods we will mock stdout methods""" io = BufferedSystemIO() io._stdout = lambda *args, **kwargs: None try: raise IndexError('Invalid index 5') except Exception as exc: output_formatted_exception(exc, ':my-test-task', io) self.assertIn('IndexError', io.get_value()) self.assertIn('Invalid index 5', io.get_value()) self.assertIn( 'Retry with "-rl debug" switch before failed task to see stacktrace', io.get_value())
def test_are_chained_exceptions_printed(self): """Check if there are multiple exceptions, then those would be printed as a cause""" io = BufferedSystemIO() try: try: raise IndexError('Invalid index 5') except IndexError as index_exc: raise Exception('There was an error with index') from index_exc except Exception as exc: output_formatted_exception(exc, ':my-test-task', io) self.assertIn('(Caused by) IndexError:', io.get_value()) self.assertIn('Exception:', io.get_value()) self.assertIn('There was an error with index', io.get_value())
def test_parse_tasks_signals_error_instead_of_throwing_exception(self): """ Test that error thrown by executed Python code will """ input_tasks = { ':song': { 'description': 'Bella Ciao is an Italian protest folk song that originated in the hardships of the ' + 'mondina women, the paddy field workers in the late 19th century who sang it to ' + 'protest against harsh working conditions in the paddy fields of North Italy', 'steps': ['''#!python print(syntax-error-here) '''] } } io = BufferedSystemIO() factory = YamlSyntaxInterpreter(io, YamlFileLoader([])) parsed_tasks = factory.parse_tasks(input_tasks, '', 'makefile.yaml', {}) declaration = parsed_tasks[0] declaration.get_task_to_execute()._io = IO() task = declaration.get_task_to_execute() task._io = io # execute prepared task result = task.execute(ExecutionContext(declaration)) self.assertEqual( False, result, msg='Expected that syntax error would result in a failure') self.assertIn("NameError: name 'syntax' is not defined", io.get_value(), msg='Error message should be attached') self.assertIn('File ":song@step 1", line 1', io.get_value(), msg='Stacktrace should be attached')
def test_find_matching_skips_services_on_syntax_error_but_raises_error_in_log(self): io = BufferedSystemIO() selector = ServiceSelector('service["labels"]["org.riotkit.country"] != ""', io) names = list(map(lambda service: service.get_name(), selector.find_matching_services(self._provide_test_data()))) self.assertEqual(['web_phillyabc'], names) self.assertIn("KeyError: 'org.riotkit.country'", io.get_value()) self.assertIn("Exception raised, while attempting to evaluate --profile selector", io.get_value())
def test_formatting_methods_are_clearing_formatting_at_the_end(self): """Check that formatting methods are clearing the formatting at the end""" io = BufferedSystemIO() methods = [ io.h1, io.h2, io.h3, io.h4, io.success_msg, io.error_msg, io.info_msg, io.print_separator, io.print_group ] for method in methods: try: method('test') except TypeError: method() self.assertEqual("\x1B[", io.get_value()[0:2], msg='Expected beginning of formatting') self.assertEqual('[0m', io.get_value().strip()[-3:], msg='Expected formatting clearing at the end') io.clear_buffer()