From eb9a2b295f8c6629a0e4d2af763f14af3b1c03c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20M=C3=B6slinger?= <dominik.moeslinger@univie.ac.at> Date: Tue, 13 Jul 2021 15:18:41 +0200 Subject: [PATCH] TST: Continued improvement Comment possibility is implemented Progress Viewer additional Tooltip --- Tst/progress_view/progress_view.py | 69 ++++++++++++++----- .../testlib/analyse_command_log.py | 24 +++++++ .../testlib/analyse_test_run.py | 31 ++++++++- Tst/testing_library/testlib/report.py | 13 ++-- Tst/tst/data_model.py | 13 +++- Tst/tst/generator.py | 7 +- Tst/tst/generator_templates/co_class.py | 6 +- Tst/tst/generator_templates/co_footer.py | 2 +- 8 files changed, 133 insertions(+), 32 deletions(-) diff --git a/Tst/progress_view/progress_view.py b/Tst/progress_view/progress_view.py index f84d763..2b24cb6 100644 --- a/Tst/progress_view/progress_view.py +++ b/Tst/progress_view/progress_view.py @@ -103,6 +103,8 @@ class TestProgressView(Gtk.ApplicationWindow): self.cmd_steps = None self.vrc_steps = None + self.run_count = {} + self.expander_states = [] self.progress_tree_store = Gtk.TreeStore(str, str, str, str, str, str, str, str, str, str, str) @@ -720,9 +722,7 @@ class TestProgressView(Gtk.ApplicationWindow): detailed_info.append('Error Code:') elif count == 5: detailed_info.append('Code') - elif count in [3,6,8]: - detailed_info.append('') - elif count == 10: + elif count in [3, 6, 8, 10]: detailed_info.append('') new_row_iter = tree_store.append(inner_row_iter, detailed_info) @@ -730,14 +730,15 @@ class TestProgressView(Gtk.ApplicationWindow): def set_test_title(self): json_title = self.test_model.name if self.test_model else None test_desc = self.test_model.description if self.test_model else None - cmd_title = self.text_path_cmd_btn.get_filename() - vrc_title = self.text_path_vrc_btn.get_filename() + cmd_title = self.text_path_cmd_btn.get_filename() if self.text_path_cmd_btn.get_filename() else None + test_desc = analyse_command_log.get_test_description(self.path_cmd) if not test_desc else test_desc + vrc_title = self.text_path_vrc_btn.get_filename().split('_')[0] if self.text_path_vrc_btn.get_filename() else None if json_title: self.test_title.set_markup('<b><big>{}</big></b>\t{}'.format(json_title.split('/')[-1], test_desc)) elif cmd_title: - self.test_title.set_markup('<b><big>{}</big></b>\t{}'.format(cmd_title.split('/')[-1], test_desc)) + self.test_title.set_markup('<b><big>{}</big></b>\t{}'.format(cmd_title.split('/')[-1].split('_')[0], test_desc)) elif vrc_title: - self.test_title.set_markup('<b><big>{}</big></b>\t{}'.format(vrc_title.split('/')[-1], test_desc)) + self.test_title.set_markup('<b><big>{}</big></b>\t{}'.format(vrc_title.split('/')[-1].split('_')[0], test_desc)) else: self.test_title.set_text('') @@ -799,8 +800,10 @@ class TestProgressView(Gtk.ApplicationWindow): for step in test_model.sequences[0].steps: step_number = step.step_number_test_format if step_number not in tree_store_steps: - # Sequnece number is no longer shown as it is not necessary as long as only one sequnece is supported - step_desc = 'Step ' + str(step_number[:-2]) + # Secondary Counter is not shown if it is 0 + step_number_primary, step_number_secondary = step_number.split('_') + step_number_shown = step_number_primary if int(step_number_secondary) == 0 else '{}.{}'.format(step_number_primary, step_number_secondary) + step_desc = 'Step ' + str(step_number_shown) new_drawer_row = self.build_row_list(step_number=str(step_number), step_desc=step_desc, @@ -873,11 +876,15 @@ class TestProgressView(Gtk.ApplicationWindow): # make execution drawers for exec_num in all_exec_numbers.keys(): if not exec_num in tree_store_exec.keys(): - #exec_desc = 'Run ' + str(exec_num) - exec_desc = str(exec_num) + if exec_num not in self.run_count.keys(): + self.run_count[exec_num] = str(len(self.run_count) + 1) + exec_desc = 'Run ' + self.run_count[exec_num] + tooltip = '{}-{}-{} {}:{}:{}'.format(exec_num[0:4], exec_num[4:6], exec_num[6:8], exec_num[8:10], + exec_num[10:12], exec_num[12:14]) new_drawer_row = self.build_row_list(exec_int=str(exec_num), exec_desc=exec_desc, - sort_button_active=self.sort_button.get_active()) + sort_button_active=self.sort_button.get_active(), + tooltip_text=tooltip) tree_store.append(None, new_drawer_row) tree_store_exec[exec_num] = [] @@ -887,7 +894,12 @@ class TestProgressView(Gtk.ApplicationWindow): exec_num = row[12] for step in all_exec_numbers[exec_num]: if not step['step'] in tree_store_exec[exec_num]: - step_desc = 'Step ' + str(step['step'][:-2]) + # Secondary Counter is not shown if it is 0 + step_number_primary, step_number_secondary = step['step'].split('_') + step_number_shown = step_number_primary if int( + step_number_secondary) == 0 else '{}.{}'.format(step_number_primary, + step_number_secondary) + step_desc = 'Step ' + str(step_number_shown) new_step_row = self.build_row_list(step_number=str(step['step']), step_desc=step_desc, sort_button_active=self.sort_button.get_active(), @@ -953,7 +965,12 @@ class TestProgressView(Gtk.ApplicationWindow): for item in cmd_steps: step_number = item['step'] if step_number not in tree_store_steps: - step_desc = 'Step ' + str(step_number[:-2]) + # Secondary Counter is not shown if it is 0 + step_number_primary, step_number_secondary = step_number.split('_') + step_number_shown = step_number_primary if int( + step_number_secondary) == 0 else '{}.{}'.format(step_number_primary, + step_number_secondary) + step_desc = 'Step ' + str(step_number_shown) new_drawer_row = self.build_row_list(step_number=str(step_number), step_desc=step_desc, sort_button_active=self.sort_button.get_active(), @@ -1041,11 +1058,15 @@ class TestProgressView(Gtk.ApplicationWindow): # make execution drawers for exec_num in all_exec_numbers.keys(): if not exec_num in tree_store_exec.keys(): - #exec_desc = 'Run ' + str(exec_num) - exec_desc = str(exec_num) + if exec_num not in self.run_count.keys(): + self.run_count[exec_num] = str(len(self.run_count) + 1) + exec_desc = 'Run ' + self.run_count[exec_num] + tooltip = '{}-{}-{} {}:{}:{}'.format(exec_num[0:4], exec_num[4:6], exec_num[6:8], exec_num[8:10], + exec_num[10:12], exec_num[12:14]) new_drawer_row = self.build_row_list(exec_int=str(exec_num), exec_desc=exec_desc, - sort_button_active=self.sort_button.get_active()) + sort_button_active=self.sort_button.get_active(), + tooltip_text=tooltip) tree_store.append(None, new_drawer_row) tree_store_exec[exec_num] = [] @@ -1055,7 +1076,12 @@ class TestProgressView(Gtk.ApplicationWindow): exec_num = row[12] for step in all_exec_numbers[exec_num]: if not step['step'] in tree_store_exec[exec_num]: - step_desc = 'Step ' + str(step['step'][:-2]) + # Secondary Counter is not shown if it is 0 + step_number_primary, step_number_secondary = step['step'].split('_') + step_number_shown = step_number_primary if int( + step_number_secondary) == 0 else '{}.{}'.format(step_number_primary, + step_number_secondary) + step_desc = 'Step ' + str(step_number_shown) new_step_row = self.build_row_list(step_number=str(step['step']), step_desc=step_desc, sort_button_active=self.sort_button.get_active(), @@ -1117,7 +1143,12 @@ class TestProgressView(Gtk.ApplicationWindow): for item in vrc_steps: step_number = item['step'] if step_number not in tree_store_steps: - step_desc = 'Step ' + str(step_number[:-2]) + # Secondary Counter is not shown if it is 0 + step_number_primary, step_number_secondary = step_number.split('_') + step_number_shown = step_number_primary if int( + step_number_secondary) == 0 else '{}.{}'.format(step_number_primary, + step_number_secondary) + step_desc = 'Step ' + str(step_number_shown) new_drawer_row = self.build_row_list(step_number=str(step_number), step_desc=step_desc, sort_button_active=self.sort_button.get_active(), diff --git a/Tst/testing_library/testlib/analyse_command_log.py b/Tst/testing_library/testlib/analyse_command_log.py index 63fa98a..119ee0d 100644 --- a/Tst/testing_library/testlib/analyse_command_log.py +++ b/Tst/testing_library/testlib/analyse_command_log.py @@ -77,6 +77,30 @@ def get_steps(filename): return steps +def get_test_description(filename): + """ + Returns the Test Description, If two are identical only one of them is returned + :param filename: path to the log file + :return: list of test descriptions + :rtype: list of str + """ + if not filename: + return '' + descr_list = [] + with open(filename, 'r') as fileobject: + for line in fileobject: + if report.key_word_found(line, report.cmd_test_start_keyword): + general_step_info = report.parse_step_from_json_string(line, report.cmd_test_start_keyword) + if general_step_info['descr'] not in descr_list: + descr_list.append(general_step_info['descr']) + + for count, descr in enumerate(descr_list): + if count == 0: + description = descr + else: + description += ' / ' + descr + print('More than one Description was found in the command log File') + return description def get_steps_and_commands(filename): """ diff --git a/Tst/testing_library/testlib/analyse_test_run.py b/Tst/testing_library/testlib/analyse_test_run.py index 89a66ee..b5a89ff 100644 --- a/Tst/testing_library/testlib/analyse_test_run.py +++ b/Tst/testing_library/testlib/analyse_test_run.py @@ -17,7 +17,7 @@ cfl.add_tst_import_paths() from testlib import analyse_verification_log from testlib import analyse_command_log -test_name = 'test3' +test_name = 'test' cmd_log_file_end = '_command.log' vrc_log_file_end = '_verification.log' @@ -60,7 +60,9 @@ def result_as_csv(test_name, log_file_path=None, output_file_path=None): writer.writerow(output_file_header) # write the general info line - writer.writerow([test_name, 'Test Description', 'Test Spec. Version: ' + cmd_steps[0]['version'], 'Test Rep. Version: ' + f'{file_count:03d}']) # TODO: version always same in log file? + description = analyse_command_log.get_test_description(cmd_log_file) + version = get_version(cmd_steps) + writer.writerow([test_name, 'Test Description', version, 'Test Rep. Version: ' + f'{file_count:03d}']) # TODO: Multiple versions/descriptions what to do? # write date line date_format = '%Y-%m-%d' @@ -79,11 +81,34 @@ def result_as_csv(test_name, log_file_path=None, output_file_path=None): for vrc_step in vrc_steps: if step['step_id'] == vrc_step['step_id']: test_result = 'VERIFIED' if vrc_step['result'] else 'FAILED' - writer.writerow(['Step ' + step['step'][:-2], step['descr'], 'Probably some VRC description', test_result]) # TODO: Third coloumn is what? + # Secondary Counter is not shown if it is 0 + step_number_primary, step_number_secondary = step['step'].split('_') + step_number_shown = step_number_primary if int( + step_number_secondary) == 0 else '{}.{}'.format(step_number_primary, + step_number_secondary) + step_desc = 'Step ' + str(step_number_shown) + writer.writerow([step_desc, step['descr'], 'Probably some VRC description', test_result]) # TODO: Third coloumn is what? # write Postcon line writer.writerow(['Postcon.', 'This has still to be solved', '', '']) # TODO: What should be shown of the Postcon +def get_version(steps): + """ + Get a string of the different version that could be found + :param list of dicts steps: all the steps from the log file + :return str version_final: A string that contains all found versions + """ + version_list = [] + for step in steps: + if step['version'] not in version_list: + version_list.append() + for count, version in enumerate(version_list): + if count == 0: + version_final = version + else: + version_final += ' / ' + version + print('More than one Version was found in the command log File') + return version_final def show_basic_results(test_name, log_file_path=None): """ diff --git a/Tst/testing_library/testlib/report.py b/Tst/testing_library/testlib/report.py index 2ec9655..89acb67 100644 --- a/Tst/testing_library/testlib/report.py +++ b/Tst/testing_library/testlib/report.py @@ -26,7 +26,6 @@ cmd_test_start_keyword = '#START TEST' cmd_step_keyword = '#COMMAND STEP' cmd_step_exception_keyword = 'EXCEPTION IN STEP' cmd_step_keyword_done = '#STEP DONE' # ATTENTION! The _done keyword must not contain the start keyword -vrc_test_start_keyword = '#START VERIFICATION' vrc_step_keyword = '#VERIFICATION FOR STEP' vrc_step_exception_keyword = 'EXCEPTION IN STEP' vrc_step_keyword_done = '#VERIFICATION STEP DONE' # ATTENTION! The _done keyword must not contain the start keyword @@ -48,7 +47,7 @@ def key_word_found(line, key_word): return found -def encode_to_json_string(step_number, timestamp, step_version=None, step_result=None, descr=None, run_id=None, step_id=None): +def encode_to_json_string(step_number, timestamp, step_version=None, step_result=None, descr=None, run_id=None, step_id=None, comment=None): """ Make a JSON string out of the step number and timestamp :param step_number: number of the step @@ -68,6 +67,8 @@ def encode_to_json_string(step_number, timestamp, step_version=None, step_result od['run_id'] = run_id if step_id is not None: od['step_id'] = step_id + if comment is not None: + od['comment'] = comment json_string = json.dumps(od) return json_string @@ -123,7 +124,8 @@ def command_step_begin(step_param, script_version, pool_name, step_start_cuc, ru step_version=script_version, run_id=run_id, step_id=step_id, - descr=step_param['descr']))) + descr=step_param['descr'], + comment=step_param['comment']))) logger.info(step_param['descr']) if 'comment' in step_param: if len(step_param['comment']) > 0: @@ -212,9 +214,12 @@ def write_log_test_header(test, pool_name=None): pool_name=pool_name, cuc_start_time=cfl.get_last_pckt_time(pool_name=pool_name, string=False), local_start_time=date_time, + descr=test.description, + comment=test.comment, run_id=test.run_id))) - logger.info('#Description: {} \n'.format(test.description)) + #logger.info('#Description: {} \n'.format(test.description)) + logger.info(test.description) if test.comment: logger.info('Comment: {}'.format(test.comment)) diff --git a/Tst/tst/data_model.py b/Tst/tst/data_model.py index e9db4fe..cfcf234 100644 --- a/Tst/tst/data_model.py +++ b/Tst/tst/data_model.py @@ -329,7 +329,6 @@ class TestSequence: self._description = '' self._version = '' self._primary_counter_locked = False - self.steps = [] if json_data is not None: @@ -893,6 +892,7 @@ class TestSpecification: self._primary_counter_locked = False self._precon = '' self._postcon = '' + self._comment = '' self.sequences = [] if json_data is not None: @@ -908,6 +908,7 @@ class TestSpecification: new_testspec.primary_counter_locked = copy.copy(self.primary_counter_locked) new_testspec.precon = copy.copy(self.precon) new_testspec.postcon = copy.copy(self.postcon) + new_testspec.comment = copy.copy(self.comment) return new_testspec @@ -969,6 +970,15 @@ class TestSpecification: assert isinstance(value, str) self._postcon = value + @property + def comment(self): + return self._comment + + @comment.setter + def comment(self, value: str): + assert isinstance(value, str) + self._comment = value + def encode_to_json(self, *args): """ Makes out of the TestSequence a JSON object. @@ -988,6 +998,7 @@ class TestSpecification: self.primary_counter_locked = json_data['_primary_counter_locked'] self.precon = json_data['_precon'] self.postcon = json_data['_postcon'] + self.comment = json_data['_comment'] except KeyError as keyerror: self.logger.error('KeyError: no {} could be found in the loaded data'.format(keyerror)) diff --git a/Tst/tst/generator.py b/Tst/tst/generator.py index ef39a6a..8a46c41 100644 --- a/Tst/tst/generator.py +++ b/Tst/tst/generator.py @@ -138,7 +138,10 @@ def make_command_script(model, model_spec): testSpecFileName=create_file_name(model_spec.name), testSpecName=model_spec.name, testSpecDescription=model_spec.description, - testSpecVersion=model_spec.version) + testSpecVersion=model_spec.version, + testPreCondition=model_spec.comment, + testPostCondition=model_spec.comment, + testComment=model_spec.comment) # add the header string content += '\n\n' + cls @@ -368,11 +371,13 @@ def make_documentation(model, model_spec): def make_all(model): paths = [] + # TODO: Only one Sequence is supported here for sequence in model.sequences: cs_path = make_command_script(sequence, model) cms_path = make_command_run_script(sequence, model) vf_path = make_verification_script(sequence, model) dc_path = make_documentation(sequence, model) + break #cs_path = make_command_script(model) #cms_path = make_command_manually_steps_script(model) diff --git a/Tst/tst/generator_templates/co_class.py b/Tst/tst/generator_templates/co_class.py index a16b433..5138db8 100644 --- a/Tst/tst/generator_templates/co_class.py +++ b/Tst/tst/generator_templates/co_class.py @@ -3,9 +3,9 @@ class ${testSpecClassName}: self.id = '${testSpecFileName}' self.name = '${testSpecName}' self.description = '${testSpecDescription}' - self.precondition = '' - self.postcondition = '' - self.comment = '' + self.precondition = '${testPreCondition}' + self.postcondition = '${testPostCondition}' + self.comment = '${testComment}' self.number_of_steps = None self.successful_steps = 0 self.step_results = [] diff --git a/Tst/tst/generator_templates/co_footer.py b/Tst/tst/generator_templates/co_footer.py index 8aad388..9bee9f5 100644 --- a/Tst/tst/generator_templates/co_footer.py +++ b/Tst/tst/generator_templates/co_footer.py @@ -10,7 +10,7 @@ Defines the log level :param make_new_log_file: bool The logging writes to a file. If this variable is set to True, a new log-file is created. - :return: instance of TestIASW66 + :return: instance the Test A instance of this test class """ testing_logger.cmd_log_handler(__name__) -- GitLab