From 104a2d00d31ddbc1c797d4d443b8e6d68bf3242b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20M=C3=B6slinger?= <dominik.moeslinger@univie.ac.at> Date: Tue, 6 Jul 2021 11:21:26 +0200 Subject: [PATCH] TST: Slightly changed logging behaviour, step_id and run_id added progress_view.py can be sorted by execution_id tooltip text-code implemented (not completly finished) --- Tst/confignator/confignator/config.py | 2 +- Tst/progress_view/progress_view.py | 701 +++++++++++++----- .../testlib/analyse_command_log.py | 53 +- .../testlib/analyse_verification_log.py | 18 +- Tst/testing_library/testlib/report.py | 91 ++- Tst/testing_library/testlib/testing_logger.py | 8 +- Tst/tst/generator_templates/co_class.py | 1 + Tst/tst/generator_templates/co_footer.py | 10 + Tst/tst/generator_templates/co_header.py | 1 + .../generator_templates/co_post_condition.py | 6 +- .../co_post_condition_entry.py | 10 + .../generator_templates/co_pre_condition.py | 7 +- .../co_pre_condition_entry.py | 10 + Tst/tst/generator_templates/co_step.py | 10 +- Tst/tst/generator_templates/run_header.py | 3 +- Tst/tst/generator_templates/ver_class.py | 14 + Tst/tst/generator_templates/ver_header.py | 1 + Tst/tst/generator_templates/ver_step.py | 17 +- 18 files changed, 702 insertions(+), 261 deletions(-) diff --git a/Tst/confignator/confignator/config.py b/Tst/confignator/confignator/config.py index 251f53c..169cbf8 100755 --- a/Tst/confignator/confignator/config.py +++ b/Tst/confignator/confignator/config.py @@ -72,7 +72,7 @@ fmt += '%(thread)s\t' fmt += '%(threadName)s\t' logging_format = fmt -logging_level_file = logging.DEBUG +logging_level_file = logging.INFO logging_level_console = logging.WARNING module_logger = logging.getLogger(__name__) module_logger.setLevel(logging.DEBUG) diff --git a/Tst/progress_view/progress_view.py b/Tst/progress_view/progress_view.py index 5331bed..dd529da 100644 --- a/Tst/progress_view/progress_view.py +++ b/Tst/progress_view/progress_view.py @@ -30,7 +30,6 @@ logger.addHandler(hdlr=console_hdlr) file_hdlr = toolbox.create_file_handler(file=log_file_path) logger.addHandler(hdlr=file_hdlr) - menu_xml = os.path.join(os.path.dirname(__file__), 'app_menu.xml') css_file = os.path.join(os.path.dirname(__file__), 'style_progress_view.css') @@ -106,7 +105,7 @@ class TestProgressView(Gtk.ApplicationWindow): self.expander_states = [] - self.progress_tree_store = Gtk.TreeStore(str, str, str, str, str, str, str, str, str, str) + self.progress_tree_store = Gtk.TreeStore(str, str, str, str, str, str, str, str, str, str, str) # monitoring the cmd and vrc log files for changes file_cmd = Gio.File.new_for_path(self.path_cmd) @@ -174,7 +173,92 @@ class TestProgressView(Gtk.ApplicationWindow): self.path_frame.add(self.path_box) self.box.pack_start(self.path_frame, True, True, 0) + self.title_box = Gtk.HBox() + self.test_label = Gtk.Label() + self.test_label.set_markup('<big>Test Title: </big>') + self.test_title = Gtk.Label() + self.set_test_title() + + self.title_box.pack_start(self.test_label, False, True, 0) + self.title_box.pack_start(self.test_title, False, True, 0) + self.box.pack_start(self.title_box, False, True, 20) + # buttons for the tree view (expand all, collapse all) + self.make_button_box() + self.box.pack_start(self.box_buttons, False, True, 0) + + self.btn_apply_css = Gtk.Button().new_from_icon_name('media-playlist-repeat-symbolic', Gtk.IconSize.BUTTON) + self.btn_apply_css.set_tooltip_text('Apply CSS') + self.btn_apply_css.connect('clicked', self.on_apply_css) + # self.box_buttons.pack_start(self.btn_apply_css, False, False, 0) + + # --------------- tree view --------------- + self.sorted_model = Gtk.TreeModelSort(model=self.progress_tree_store) + self.sorted_model.set_sort_column_id(1, Gtk.SortType.ASCENDING) + self.view = Gtk.TreeView(model=self.sorted_model) + self.view.set_grid_lines(True) + self.view.set_has_tooltip(True) + self.view.set_tooltip_column(10) + self.make_treeview() + + self.view.expand_all() + + self.scroll_win = Gtk.ScrolledWindow() + self.scroll_win.set_min_content_height(1200) + self.scroll_win.set_min_content_width(900) + self.scroll_win.add(self.view) + self.box.pack_start(self.scroll_win, True, True, 0) + + self.connect('destroy', self.on_destroy) + + # expand all entries + self.view.expand_all() + + self.refresh_rate = 1 + self.refresh_worker() + + # for styling the application with CSS + context = self.get_style_context() + Gtk.StyleContext.add_class(context, 'tst-css') + self.on_apply_css() + self.show_all() + logger.debug('__init__ succeeded') + + @staticmethod + def on_apply_css(*args): + logger.debug('Applying CSS') + style_provider = Gtk.CssProvider() + css = open(css_file, 'rb') # rb needed for python 3 support + css_data = css.read() + css.close() + style_provider.load_from_data(css_data) + Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), + style_provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) + Gtk.StyleContext.reset_widgets(Gdk.Screen.get_default()) + + def on_open(self, simple_action, parameter): + """ + Menu -> Open: choose a Test specification file. The command log and verification log files will be loaded + automatically. Using the path in the configuration file. + :param Gio.SimpleAction simple_action: The object which received the signal + :param parameter: the parameter to the activation, or None if it has no parameter + """ + dialog = Gtk.FileChooserDialog('Please choose a Test Specification', + self, + Gtk.FileChooserAction.OPEN, + (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) + self.add_filters(dialog) + response = dialog.run() + if response == Gtk.ResponseType.OK: + file_selected = dialog.get_filename() + # ToDo: get the path for all 3 (json, cmd, vrc) and load them + self.open_test_files(None, self.get_log_file_paths_from_json_file_name(file_selected)) + elif response == Gtk.ResponseType.CANCEL: + pass + dialog.destroy() + + def make_button_box(self): self.box_buttons = Gtk.Box() self.box_buttons.set_orientation(Gtk.Orientation.HORIZONTAL) self.btn_exp_all = Gtk.Button() @@ -189,24 +273,39 @@ class TestProgressView(Gtk.ApplicationWindow): self.btn_rld_all.set_label('Reload all') self.btn_rld_all.connect('clicked', self.on_reload_all) self.box_buttons.pack_start(self.btn_rld_all, False, False, 0) - self.box.pack_start(self.box_buttons, False, True, 0) - self.btn_apply_css = Gtk.Button().new_from_icon_name('media-playlist-repeat-symbolic', Gtk.IconSize.BUTTON) - self.btn_apply_css.set_tooltip_text('Apply CSS') - self.btn_apply_css.connect('clicked', self.on_apply_css) - # self.box_buttons.pack_start(self.btn_apply_css, False, False, 0) + self.sort_label = Gtk.Label() + self.sort_label.set_text('Sort by Execution') + self.box_buttons.pack_end(self.sort_label, False, True, 0) - # --------------- tree view --------------- - self.sorted_model = Gtk.TreeModelSort(model=self.progress_tree_store) - self.sorted_model.set_sort_column_id(1, Gtk.SortType.ASCENDING) - self.view = Gtk.TreeView(model=self.sorted_model) - self.view.set_grid_lines(True) + self.sort_button = Gtk.Switch() + self.sort_button.connect("notify::active", self.on_remake_treeview) + self.sort_button.set_active(False) + self.box_buttons.pack_end(self.sort_button, False, True, 0) + + self.sort_label2 = Gtk.Label() + self.sort_label2.set_text('Sort by Steps') + self.box_buttons.pack_end(self.sort_label2, False, True, 0) + + def make_treeview(self): # self.view.set_enable_tree_lines(True) + if self.sort_button.get_active(): # Only if sorted by executions + # column 0 + renderer_number = Gtk.CellRendererText() + #renderer_number.set_property('scale', 2) + renderer_number.set_property('single-paragraph-mode', True) + execution_number = Gtk.TreeViewColumn('Run ', renderer_number, text=11) + execution_number.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) + execution_number.set_resizable(True) + execution_number.set_min_width(50) + self.view.append_column(execution_number) + # column 1 renderer_number = Gtk.CellRendererText() - renderer_number.set_property('scale', 2) - renderer_number.set_property('single-paragraph-mode', True) + if not self.sort_button.get_active(): # Only big if sorted by steps, otherwise normal size + renderer_number.set_property('scale', 2) + renderer_number.set_property('single-paragraph-mode', True) column_number = Gtk.TreeViewColumn('Step', renderer_number, text=8) column_number.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) column_number.set_resizable(True) @@ -272,64 +371,14 @@ class TestProgressView(Gtk.ApplicationWindow): column_result.set_min_width(50) # column_result.set_cell_data_func(cell_renderer=renderer_result, func=set_bkgrd_clr, func_data=None) self.view.append_column(column_result) - - self.view.expand_all() - - self.scroll_win = Gtk.ScrolledWindow() - self.scroll_win.set_min_content_height(1200) - self.scroll_win.set_min_content_width(900) - self.scroll_win.add(self.view) - self.box.pack_start(self.scroll_win, True, True, 0) - - self.connect('destroy', self.on_destroy) - - # expand all entries - self.view.expand_all() - - self.refresh_rate = 1 - self.refresh_worker() - - # for styling the application with CSS - context = self.get_style_context() - Gtk.StyleContext.add_class(context, 'tst-css') - self.on_apply_css() - self.show_all() - logger.debug('__init__ succeeded') - - @staticmethod - def on_apply_css(*args): - logger.debug('Applying CSS') - style_provider = Gtk.CssProvider() - css = open(css_file, 'rb') # rb needed for python 3 support - css_data = css.read() - css.close() - style_provider.load_from_data(css_data) - Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), - style_provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) - Gtk.StyleContext.reset_widgets(Gdk.Screen.get_default()) - - def on_open(self, simple_action, parameter): - """ - Menu -> Open: choose a Test specification file. The command log and verification log files will be loaded - automatically. Using the path in the configuration file. - :param Gio.SimpleAction simple_action: The object which received the signal - :param parameter: the parameter to the activation, or None if it has no parameter - """ - dialog = Gtk.FileChooserDialog('Please choose a Test Specification', - self, - Gtk.FileChooserAction.OPEN, - (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) - self.add_filters(dialog) - response = dialog.run() - if response == Gtk.ResponseType.OK: - file_selected = dialog.get_filename() - # ToDo: get the path for all 3 (json, cmd, vrc) and load them - self.open_test_files(None, self.get_log_file_paths_from_json_file_name(file_selected)) - elif response == Gtk.ResponseType.CANCEL: - pass - dialog.destroy() - + return + + def tooltip_treeview(self, widget, *args): + #print(widget) + #print(args) + #print(self.view.get_path_at_pos(args[0], args[1])) + pass + return True def get_log_file_paths_from_json_file_name(self, filename): from testlib import testing_logger paths = {} @@ -491,6 +540,22 @@ class TestProgressView(Gtk.ApplicationWindow): def refresh_worker(self): GLib.timeout_add_seconds(self.refresh_rate, self.on_reload_all) + def on_remake_treeview(self, *args): + if self.sort_button.get_active(): + self.progress_tree_store = Gtk.TreeStore(str, str, str, str, str, str, str, str, str, str, str, str, str) + else: + self.progress_tree_store = Gtk.TreeStore(str, str, str, str, str, str, str, str, str, str, str) + + self.sorted_model = Gtk.TreeModelSort(model=self.progress_tree_store) + self.sorted_model.set_sort_column_id(1, Gtk.SortType.ASCENDING) + self.view.set_model(self.sorted_model) + all_columns = self.view.get_columns() + for column in all_columns: + self.view.remove_column(column) + self.make_treeview() + self.on_reload_all() + + def on_reload_all(self, *args): if self.path_json: self.load_json(self.path_json) @@ -517,7 +582,7 @@ class TestProgressView(Gtk.ApplicationWindow): # ------------------- model functions ---------------------- @staticmethod def build_row_list(row=None, step_number=None, exec_date=None, entry_type=None, version=None, status=None, tcs=None, - result=None, step_desc=None): + result=None, step_desc=None, tooltip_text=None, exec_int=None, exec_desc=None, sort_button_active=False): """ Builds or updates a row of the TreeStore. For a new row, the argument 'row' is expected to be None. :param Gtk.TreeModelRow row: a row of the tree model @@ -546,6 +611,8 @@ class TestProgressView(Gtk.ApplicationWindow): else: return 'failed' + sort_adjustment = 1 if sort_button_active else 0 + entry_background = None if exec_date is not None: exec_date = datetime.datetime.strftime(exec_date, testing_logger.date_time_format) @@ -558,6 +625,12 @@ class TestProgressView(Gtk.ApplicationWindow): if row is not None: # update existing row + row[10] = 'Hello' + if sort_button_active: + if exec_int: + row[12] = exec_int + if exec_desc: + row[11] = exec_desc if step_number is not None: row[0] = step_number if exec_date is not None: @@ -577,19 +650,36 @@ class TestProgressView(Gtk.ApplicationWindow): row[8] = step_desc else: # build a new row - row = [ - step_number, - exec_date, - entry_type, - version, - status, - tcs, - result_value, - entry_background, - step_desc, - result_cell_color - - ] + if sort_button_active: + row = [ + step_number, + exec_date, + entry_type, + version, + status, + tcs, + result_value, + entry_background, + step_desc, + result_cell_color, + tooltip_text, + exec_desc, + exec_int + ] + else: + row = [ + step_number, + exec_date, + entry_type, + version, + status, + tcs, + result_value, + entry_background, + step_desc, + result_cell_color, + tooltip_text + ] # set the background color of the rows if row[2] == 'command': entry_background = row_cmd_color @@ -603,7 +693,6 @@ class TestProgressView(Gtk.ApplicationWindow): return row def add_detailed_row(self, inner_row_iter, tree_store): - detailed_info=[] for count, item in enumerate(tree_store[inner_row_iter]): if count in [0,7,9]: # Stepnumber, colour, colour @@ -611,7 +700,10 @@ class TestProgressView(Gtk.ApplicationWindow): elif count == 1: detailed_info.append('Description:') elif count == 2: - detailed_info.append('Code') + if self.test_model: + detailed_info.append('{}'.format(self.test_model.description)) + else: + detailed_info.append('Json File has to be given') elif count == 4: if tree_store[inner_row_iter][2] == 'command': detailed_info.append('Command Code:') @@ -623,11 +715,27 @@ class TestProgressView(Gtk.ApplicationWindow): detailed_info.append('Code') elif count in [3,6,8]: detailed_info.append('') + elif count == 10: + detailed_info.append('') new_row_iter = tree_store.append(inner_row_iter, detailed_info) + 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() + 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)) + elif vrc_title: + self.test_title.set_markup('<b><big>{}</big></b>\t{}'.format(vrc_title.split('/')[-1], test_desc)) + else: + self.test_title.set_text('') def load_json(self, filepath): + if not os.path.isfile(filepath): message = 'load_file: no file found for the path {}'.format(filepath) logger.warning(message) @@ -641,9 +749,11 @@ class TestProgressView(Gtk.ApplicationWindow): if data_from_file is not None: self.test_model = data_model.TestSpecification() self.test_model.decode_from_json(json_data=data_from_file) - self.load_model_into_tree_store(self.progress_tree_store, self.test_model) + if not self.sort_button.get_active(): # Only add json steps, if sorted by steps + self.load_model_into_tree_store(self.progress_tree_store, self.test_model) else: logger.warning('load_file: could not read from the JSON test spec') + self.set_test_title() def load_cmd(self, filepath): if not os.path.isfile(filepath): @@ -654,6 +764,7 @@ class TestProgressView(Gtk.ApplicationWindow): # analyse the command log self.cmd_steps = analyse_command_log.get_steps_and_commands(filepath) self.load_cmd_into_tree_store(self.progress_tree_store, self.cmd_steps) + self.set_test_title() def load_vrc(self, filepath): if not os.path.isfile(filepath): @@ -664,6 +775,7 @@ class TestProgressView(Gtk.ApplicationWindow): # analyse the verification log self.vrc_steps = analyse_verification_log.get_verification_steps(filepath) self.load_vrc_into_tree_store(self.progress_tree_store, self.vrc_steps) + self.set_test_title() def load_model_into_tree_store(self, tree_store, test_model): @@ -684,7 +796,8 @@ class TestProgressView(Gtk.ApplicationWindow): step_desc = 'Step ' + str(step_number[:-2]) new_drawer_row = self.build_row_list(step_number=str(step_number), - step_desc=step_desc) + step_desc=step_desc, + sort_button_active=self.sort_button.get_active()) tree_store.append(None, new_drawer_row) tree_store_steps.append(step_number) @@ -728,64 +841,164 @@ class TestProgressView(Gtk.ApplicationWindow): """ # collect the information if the drawer rows are expanded, in order to restore this states self.gather_expanded_states(tree_store) + if self.sort_button.get_active(): + # check which executions are already in the tree store + tree_store_exec = {} + for row in tree_store: + if row[12]: + tree_store_exec[row[12]] = [] + # check which steps are in each execution + for row in tree_store: + if row[12]: + for item in row.iterchildren(): + if item[0]: + tree_store_exec[row[12]].append(item[0]) + + all_exec_numbers = {} + # get all executions + for item in cmd_steps: + all_exec_numbers[str(item['run_id'])] = [] + # get all steps for every execution + for item in cmd_steps: + all_exec_numbers[str(item['run_id'])].append(item['step']) + + # 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) + new_drawer_row = self.build_row_list(exec_int=str(exec_num), + exec_desc=exec_desc, + sort_button_active=self.sort_button.get_active()) + tree_store.append(None, new_drawer_row) + tree_store_exec[exec_num] = [] + + # make step drawers for every execution drawer + for row in tree_store: + if row[12]: + exec_num = row[12] + for step_num in all_exec_numbers[exec_num]: + if not step_num in tree_store_exec[exec_num]: + step_desc = 'Step ' + str(step_num[:-2]) + new_step_row = self.build_row_list(step_number=str(step_num), + step_desc=step_desc, + sort_button_active=self.sort_button.get_active()) + new_row_iter = tree_store.append(row.iter, new_step_row) + tree_store_exec[exec_num].append(step_num) + + # clear all command rows, before adding + for row in tree_store: + if row[12]: + for step_row in row.iterchildren(): + for item in step_row.iterchildren(): + if item[2] == 'command': + tree_store.remove(item.iter) + + # add rows for command + for row in tree_store: + if row[12]: + exec_num = row[12] + for step_row in row.iterchildren(): + if step_row[0]: + step_num = step_row[0] + for item in cmd_steps: + if item['run_id'] == exec_num and item['step'] == step_num: + new_row_list = self.build_row_list(entry_type='command', + version=item['version'], + exec_date=item['exec_date'], + sort_button_active=self.sort_button.get_active(), + tooltip_text=item['descr']) + new_row_iter = tree_store.append(step_row.iter, new_row_list) + new_row = tree_store[new_row_iter] + # add the information if the step was executed or had an exception + if 'exception' in item: + self.build_row_list(row=new_row, + status='EXCEPTION', + result=False, + sort_button_active=self.sort_button.get_active()) + else: + if 'end_timestamp' in item: + self.build_row_list(row=new_row, + status='executed', + result=True, + sort_button_active=self.sort_button.get_active()) + # add the TC's + tcs_str = '' + for telecommand in item['tcs']: + if tcs_str != '': + tcs_str += ', ' + tcs_str += telecommand.tc_kind() + self.build_row_list(row=new_row, + tcs=tcs_str, + sort_button_active=self.sort_button.get_active()) + + #self.add_detailed_row(new_row_iter, tree_store) - # check which step numbers are already in the tree_store - tree_store_steps = [] - for row in tree_store: - step_number_tree_store = row[0:1][0] - tree_store_steps.append(step_number_tree_store) - # add drawer for each step which is not in the tree_store already - for item in cmd_steps: - step_number = item['step'] - if step_number not in tree_store_steps: - step_desc = 'Step ' + str(step_number) - new_drawer_row = self.build_row_list(step_number=str(step_number), - step_desc=step_desc) - tree_store.append(None, new_drawer_row) - tree_store_steps.append(step_number) - # clear all command rows, before adding - for row in tree_store: - for item in row.iterchildren(): - if item[2] == 'command': - tree_store.remove(item.iter) - # add rows for command - for row in tree_store: - step_number_tree_store = row[0:1][0] + else: + # check which step numbers are already in the tree_store + tree_store_steps = [] + for row in tree_store: + step_number_tree_store = row[0:1][0] + tree_store_steps.append(step_number_tree_store) + # add drawer for each step which is not in the tree_store already for item in cmd_steps: - step_number_cmd = item['step'] - if step_number_tree_store == step_number_cmd: - # already_exists = False - # for i in row.iterchildren(): - # if datetime.datetime.strftime(item['exec_date'], testing_logger.date_time_format) == i[1]: - # already_exists = True - # # add a new row - # if not already_exists: - new_row_list = self.build_row_list(entry_type='command', - version=item['version'], - exec_date=item['exec_date']) - new_row_iter = tree_store.append(row.iter, new_row_list) - new_row = tree_store[new_row_iter] - - # add the information if the step was executed or had an exception - if 'exception' in item: - self.build_row_list(row=new_row, - status='EXCEPTION', - result=False) - else: - if 'end_timestamp' in item: + step_number = item['step'] + if step_number not in tree_store_steps: + step_desc = 'Step ' + str(step_number[:-2]) + new_drawer_row = self.build_row_list(step_number=str(step_number), + step_desc=step_desc, + sort_button_active=self.sort_button.get_active()) + tree_store.append(None, new_drawer_row) + tree_store_steps.append(step_number) + # clear all command rows, before adding + for row in tree_store: + for item in row.iterchildren(): + if item[2] == 'command': + tree_store.remove(item.iter) + # add rows for command + for row in tree_store: + #self.view.set_tooltip_column() + step_number_tree_store = row[0:1][0] + for item in cmd_steps: + step_number_cmd = item['step'] + if step_number_tree_store == step_number_cmd: + # already_exists = False + # for i in row.iterchildren(): + # if datetime.datetime.strftime(item['exec_date'], testing_logger.date_time_format) == i[1]: + # already_exists = True + # # add a new row + # if not already_exists: + new_row_list = self.build_row_list(entry_type='command', + version=item['version'], + exec_date=item['exec_date'], + sort_button_active=self.sort_button.get_active(), + tooltip_text=item['descr']) + new_row_iter = tree_store.append(row.iter, new_row_list) + new_row = tree_store[new_row_iter] + + # add the information if the step was executed or had an exception + if 'exception' in item: self.build_row_list(row=new_row, - status='executed', - result=True) - # add the TC's - tcs_str = '' - for telecommand in item['tcs']: - if tcs_str != '': - tcs_str += ', ' - tcs_str += telecommand.tc_kind() - self.build_row_list(row=new_row, - tcs=tcs_str) - - self.add_detailed_row(new_row_iter, tree_store) + status='EXCEPTION', + result=False, + sort_button_active=self.sort_button.get_active()) + else: + if 'end_timestamp' in item: + self.build_row_list(row=new_row, + status='executed', + result=True, + sort_button_active=self.sort_button.get_active()) + # add the TC's + tcs_str = '' + for telecommand in item['tcs']: + if tcs_str != '': + tcs_str += ', ' + tcs_str += telecommand.tc_kind() + self.build_row_list(row=new_row, + tcs=tcs_str, + sort_button_active=self.sort_button.get_active()) + + self.add_detailed_row(new_row_iter, tree_store) self.restore_expanded_states(tree_store) @@ -793,59 +1006,157 @@ class TestProgressView(Gtk.ApplicationWindow): # collect the information if the drawer rows are expanded, in order to restore this states self.gather_expanded_states(tree_store) - # check which step numbers are already in the tree_store - tree_store_steps = [] - for row in tree_store: - step_number_tree_store = row[0:1][0] - tree_store_steps.append(step_number_tree_store) - # add drawer for each step which is not in the tree_store already - for item in vrc_steps: - step_number = item['step'] - if step_number not in tree_store_steps: - step_desc = 'Step ' + str(step_number) - new_drawer_row = self.build_row_list(step_number=str(step_number), - step_desc=step_desc) - tree_store.append(None, new_drawer_row) - tree_store_steps.append(step_number) - # clear all verification rows, before adding - for row in tree_store: - for item in row.iterchildren(): - if item[2] == 'verification': - tree_store.remove(item.iter) - # add row for verification - for row in tree_store: - step_number_tree_store = row[0:1][0] + + if self.sort_button.get_active(): + # check which executions are already in the tree store + tree_store_exec = {} + for row in tree_store: + if row[12]: + tree_store_exec[row[12]] = [] + # check which steps are in each execution + for row in tree_store: + if row[12]: + for item in row.iterchildren(): + if item[0]: + tree_store_exec[row[12]].append(item[0]) + + all_exec_numbers = {} + # get all executions for item in vrc_steps: - step_number_vrc = item['step'] - if step_number_tree_store == step_number_vrc: - # already_exists = False - # for i in row.iterchildren(): - # if datetime.datetime.strftime(item['exec_date'], testing_logger.date_time_format) == i[1]: - # already_exists = True - # # add a new row - # if not already_exists: - new_row_list = self.build_row_list(entry_type='verification', - version=item['version'], - exec_date=item['exec_date']) - new_row_iter = tree_store.append(row.iter, new_row_list) - new_row = tree_store[new_row_iter] - # add the information if the step was executed or had an exception - if 'exception' in item: - self.build_row_list(row=new_row, - status='EXCEPTION') - else: - if 'end_timestamp' in item: - self.build_row_list(row=new_row, - status='executed') - if 'result' in item: - if item['result'] is True: + all_exec_numbers[str(item['run_id'])] = [] + # get all steps for every execution + for item in vrc_steps: + all_exec_numbers[str(item['run_id'])].append(item['step']) + + # 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) + new_drawer_row = self.build_row_list(exec_int=str(exec_num), + exec_desc=exec_desc, + sort_button_active=self.sort_button.get_active()) + tree_store.append(None, new_drawer_row) + tree_store_exec[exec_num] = [] + + # make step drawers for every execution drawer + for row in tree_store: + if row[12]: + exec_num = row[12] + for step_num in all_exec_numbers[exec_num]: + if not step_num in tree_store_exec[exec_num]: + step_desc = 'Step ' + str(step_num[:-2]) + new_step_row = self.build_row_list(step_number=str(step_num), + step_desc=step_desc, + sort_button_active=self.sort_button.get_active()) + new_row_iter = tree_store.append(row.iter, new_step_row) + tree_store_exec[exec_num].append(step_num) + + # clear all verification rows, before adding + for row in tree_store: + if row[12]: + for step_row in row.iterchildren(): + for item in step_row.iterchildren(): + if item[2] == 'verification': + tree_store.remove(item.iter) + + # add rows for verification + for row in tree_store: + if row[12]: + exec_num = row[12] + for step_row in row.iterchildren(): + if step_row[0]: + step_num = step_row[0] + for item in vrc_steps: + if item['run_id'] == exec_num and item['step'] == step_num: + new_row_list = self.build_row_list(entry_type='verification', + version=item['version'], + exec_date=item['exec_date'], + sort_button_active=self.sort_button.get_active(), + tooltip_text=item['descr']) + new_row_iter = tree_store.append(step_row.iter, new_row_list) + new_row = tree_store[new_row_iter] + # add the information if the step was executed or had an exception + if 'exception' in item: + self.build_row_list(row=new_row, + status='EXCEPTION', + sort_button_active=self.sort_button.get_active()) + else: + if 'end_timestamp' in item: + self.build_row_list(row=new_row, + status='executed', + sort_button_active=self.sort_button.get_active()) + if 'result' in item: + if item['result'] is True: + self.build_row_list(row=new_row, + result=True, + sort_button_active=self.sort_button.get_active()) + else: + self.build_row_list(row=new_row, + result=False, + sort_button_active=self.sort_button.get_active()) + + else: + # check which step numbers are already in the tree_store + tree_store_steps = [] + for row in tree_store: + step_number_tree_store = row[0:1][0] + tree_store_steps.append(step_number_tree_store) + # add drawer for each step which is not in the tree_store already + for item in vrc_steps: + step_number = item['step'] + if step_number not in tree_store_steps: + step_desc = 'Step ' + str(step_number[:-2]) + new_drawer_row = self.build_row_list(step_number=str(step_number), + step_desc=step_desc, + sort_button_active=self.sort_button.get_active()) + tree_store.append(None, new_drawer_row) + tree_store_steps.append(step_number) + # clear all verification rows, before adding + for row in tree_store: + for item in row.iterchildren(): + if item[2] == 'verification': + tree_store.remove(item.iter) + # add row for verification + for row in tree_store: + step_number_tree_store = row[0:1][0] + for item in vrc_steps: + step_number_vrc = item['step'] + if step_number_tree_store == step_number_vrc: + # already_exists = False + # for i in row.iterchildren(): + # if datetime.datetime.strftime(item['exec_date'], testing_logger.date_time_format) == i[1]: + # already_exists = True + # # add a new row + # if not already_exists: + new_row_list = self.build_row_list(entry_type='verification', + version=item['version'], + exec_date=item['exec_date'], + sort_button_active=self.sort_button.get_active(), + tooltip_text=item['descr']) + new_row_iter = tree_store.append(row.iter, new_row_list) + new_row = tree_store[new_row_iter] + # add the information if the step was executed or had an exception + if 'exception' in item: self.build_row_list(row=new_row, - result=True) + status='EXCEPTION', + sort_button_active=self.sort_button.get_active()) else: - self.build_row_list(row=new_row, - result=False) - self.add_detailed_row(new_row_iter, tree_store) - self.restore_expanded_states(tree_store) + if 'end_timestamp' in item: + self.build_row_list(row=new_row, + status='executed', + sort_button_active=self.sort_button.get_active()) + if 'result' in item: + if item['result'] is True: + self.build_row_list(row=new_row, + result=True, + sort_button_active=self.sort_button.get_active()) + else: + self.build_row_list(row=new_row, + result=False, + sort_button_active=self.sort_button.get_active()) + self.add_detailed_row(new_row_iter, tree_store) + self.restore_expanded_states(tree_store) def run(): diff --git a/Tst/testing_library/testlib/analyse_command_log.py b/Tst/testing_library/testlib/analyse_command_log.py index ddf6c26..52d5252 100644 --- a/Tst/testing_library/testlib/analyse_command_log.py +++ b/Tst/testing_library/testlib/analyse_command_log.py @@ -80,18 +80,29 @@ def get_steps_and_commands(filename): :rtype: list of dict """ steps = [] + steps_start = [] + steps_end = [] - def new_step_template(): + def new_step_template_start(): return {'step': None, 'version': '', 'tcs': [], 'date': ''} - new_step = new_step_template() + def new_step_template_end(): + return {'step': None, 'timestamp': '', 'step_id': ''} + + new_step = new_step_template_start() + run_count = 1 with open(filename, 'r') as fileobject: for line in fileobject: + #if report.key_word_found(line, report.cmd_test_start_keyword): + # Get general infos about the whole test, append to every step of this run + #general_step_info = report.parse_step_from_json_string(line, report.cmd_test_start_keyword) + #general_step_info['run_count'] = str(run_count) + #run_count += 1 if report.key_word_found(line, report.cmd_step_keyword): if new_step['step'] is not None: - steps.append(new_step) - new_step = new_step_template() + steps_start.append(new_step) + new_step = new_step_template_start() # get date of the step execution new_step['exec_date'] = testing_logger.extract_date(line) # get the information about the step @@ -100,6 +111,13 @@ def get_steps_and_commands(filename): new_step['step'] = step_start_info['step'] new_step['start_timestamp'] = step_start_info['timestamp'] new_step['version'] = step_start_info['version'] + new_step['descr'] = step_start_info['descr'] + new_step['run_id'] = step_start_info['run_id'] + new_step['step_id'] = step_start_info['step_id'] + #try: + # new_step['general_run_info'] = general_step_info + #except: + # new_step['general_run_info'] = None if tcid.key_word_found(line): new_tc_id = tcid.TcId() new_tc_id.parse_tc_id_from_json_string(line=line) @@ -109,16 +127,29 @@ def get_steps_and_commands(filename): if report.key_word_found(line, report.cmd_step_keyword_done): step_end_info = report.parse_step_from_json_string(line, report.cmd_step_keyword_done) if step_end_info is not None: - if new_step['step'] == step_end_info['step']: - new_step['end_timestamp'] = step_end_info['timestamp'] - else: - print('get_steps_and_commands: the step number in the step-end string is different than the' - 'step number of the last step-start string.') + new_step_end = new_step_template_end() + new_step_end['step'] = step_end_info['step'] + new_step_end['timestamp'] = step_end_info['timestamp'] + new_step_end['step_id'] = step_end_info['step_id'] + steps_end.append(new_step_end) + #if new_step['step'] == step_end_info['step']: + # new_step['end_timestamp'] = step_end_info['timestamp'] + #else: + # print('get_steps_and_commands: the step number in the step-end string is different than the' + # 'step number of the last step-start string.') if new_step['step'] is not None: - steps.append(new_step) + steps_start.append(new_step) fileobject.close() - return steps + if len(steps_end) > len(steps_start): + print('More steps ended than started, something went wrong') + + for start_info in steps_start: + for end_info in steps_end: + if start_info['step_id'] == start_info['step_id']: + start_info['end_timestamp'] = end_info['timestamp'] + + return steps_start if __name__ == '__main__': diff --git a/Tst/testing_library/testlib/analyse_verification_log.py b/Tst/testing_library/testlib/analyse_verification_log.py index 2c3e385..ebc9549 100644 --- a/Tst/testing_library/testlib/analyse_verification_log.py +++ b/Tst/testing_library/testlib/analyse_verification_log.py @@ -15,16 +15,23 @@ def get_verification_steps(filename): end timestamp (CUC) of the verification and the result of the verification for this step :rtype: list of dict """ + vrc_start = [] vrc_end = [] + id_codes = {} with open(filename, 'r') as fileobject: for line in fileobject: if report.key_word_found(line, report.vrc_step_keyword): new_dict = report.parse_step_from_json_string(line, report.vrc_step_keyword) new_dict['exec_date'] = testing_logger.extract_date(line) + #new_dict['id_code'] = line.split('\t')[2] + #id_codes[line.split('\t')[2]] = int(line.split('\t')[2]) vrc_start.append(new_dict) if report.key_word_found(line, report.vrc_step_keyword_done): - vrc_end.append(report.parse_step_from_json_string(line, report.vrc_step_keyword_done)) + new_dict = report.parse_step_from_json_string(line, report.vrc_step_keyword_done) + #new_dict['id_code'] = line.split('\t')[2] + #id_codes[line.split('\t')[2]] = int(line.split('\t')[2]) + vrc_end.append(new_dict) fileobject.close() # print('\nfound {} steps:'.format(len(vrc_start))) @@ -33,6 +40,9 @@ def get_verification_steps(filename): # # for item in vrc_start: # print('Verification end for Step {} @ {}'.format(item['step'], item['timestamp'])) + #exec_count = 1 + if len(vrc_end) > len(vrc_start): + print('There are more steps finished than started, something went wrong') vrc_steps = [] for item in vrc_start: @@ -41,8 +51,12 @@ def get_verification_steps(filename): new_vrc_step['start_timestamp'] = item['timestamp'] new_vrc_step['exec_date'] = item['exec_date'] new_vrc_step['version'] = item['version'] + new_vrc_step['descr'] = item['descr'] + new_vrc_step['run_id'] = item['run_id'] + new_vrc_step['step_id'] = item['step_id'] for element in vrc_end: - if element['step'] == item['step']: + if element['step_id'] == item['step_id']: + #new_vrc_step['run_count'] = id_run_count[element['id_code']] new_vrc_step['end_timestamp'] = element['timestamp'] new_vrc_step['result'] = element['result'] vrc_steps.append(new_vrc_step) diff --git a/Tst/testing_library/testlib/report.py b/Tst/testing_library/testlib/report.py index b08ddb0..2ec9655 100644 --- a/Tst/testing_library/testlib/report.py +++ b/Tst/testing_library/testlib/report.py @@ -3,7 +3,7 @@ Report - writing log entries ============================ """ -import datetime +from datetime import datetime import logging import collections import json @@ -13,15 +13,23 @@ import confignator sys.path.append(confignator.get_option('paths', 'ccs')) import ccs_function_lib as cfl -# create a logger +# create logger logger = logging.getLogger(__name__) +#now = datetime.now() # current date and time +#code = now.strftime("%Y%m%d%H%M%S") +#extra = {'id_code': code} +#logger = logging.LoggerAdapter(logger, extra) + +import datetime +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 DONE' # ATTENTION! The _done keyword must not contain the start keyword +vrc_step_keyword_done = '#VERIFICATION STEP DONE' # ATTENTION! The _done keyword must not contain the start keyword def key_word_found(line, key_word): @@ -40,7 +48,7 @@ def key_word_found(line, key_word): return found -def encode_to_json_string(step_number, timestamp, step_version=None, step_result=None): +def encode_to_json_string(step_number, timestamp, step_version=None, step_result=None, descr=None, run_id=None, step_id=None): """ Make a JSON string out of the step number and timestamp :param step_number: number of the step @@ -54,9 +62,21 @@ def encode_to_json_string(step_number, timestamp, step_version=None, step_result od['version'] = step_version if step_result is not None: od['result'] = step_result + if descr is not None: + od['descr'] = descr + if run_id is not None: + od['run_id'] = run_id + if step_id is not None: + od['step_id'] = step_id json_string = json.dumps(od) return json_string +def make_json_string(*args, **kwargs): + od = {} + for key, value in kwargs.items(): + od[str(key)] = value + json_string = json.dumps(od) + return json_string def parse_step_from_json_string(line, key_word): """ @@ -85,7 +105,7 @@ def parse_step_from_json_string(line, key_word): logger.error('parse_tc_id_from_json_string: parsing of the TC JSON string failed!') -def command_step_begin(step_param, script_version, pool_name, step_start_cuc): +def command_step_begin(step_param, script_version, pool_name, step_start_cuc, run_id, step_id): """ Builds a string and writes it into the logging file. A keyword is set to enable a machine read out of the log file. All information of the step is written in a JSON string. @@ -95,48 +115,57 @@ def command_step_begin(step_param, script_version, pool_name, step_start_cuc): :param step_start_cuc: :return: """ + #print(step_param) logger.info('{} {} {}'.format(cmd_step_keyword, step_param['step_no'], encode_to_json_string(step_number=step_param['step_no'], timestamp=step_start_cuc, - step_version=script_version))) - logger.info(step_param['msg']) + step_version=script_version, + run_id=run_id, + step_id=step_id, + descr=step_param['descr']))) + logger.info(step_param['descr']) if 'comment' in step_param: if len(step_param['comment']) > 0: logger.info('Comment: {}'.format(step_param['comment'])) -def command_step_exception(step_param): - logger.warning('{} {}'.format(cmd_step_exception_keyword, - step_param['step_no'])) +def command_step_exception(step_param, step_id=None): + logger.warning('{} {} {}'.format(cmd_step_exception_keyword, + step_param['step_no'], make_json_string(step_id=step_id))) -def command_step_end(step_param, step_end_cuc): - logger.info('{} {}\n'.format(cmd_step_keyword_done, encode_to_json_string(step_param['step_no'], step_end_cuc))) +def command_step_end(step_param, step_end_cuc, step_id): + logger.info('{} {}\n'.format(cmd_step_keyword_done, encode_to_json_string(step_param['step_no'], step_end_cuc, step_id=step_id))) -def verification_step_begin(step_param, script_version, pool_name, step_start_cuc): +def verification_step_begin(step_param, script_version, pool_name, step_start_cuc, run_id, step_id): + logger.info('{} {} {}'.format(vrc_step_keyword, step_param['step_no'], encode_to_json_string(step_number=step_param['step_no'], timestamp=step_start_cuc, - step_version=script_version))) - logger.info(step_param['msg']) + step_version=script_version, + run_id=run_id, + step_id=step_id, + descr=step_param['descr']))) + logger.info(step_param['descr']) if 'comment' in step_param: if len(step_param['comment']) > 0: logger.info('Comment: {}'.format(step_param['comment'])) -def verification_step_exception(step_param): - logger.warning('{} {}'.format(vrc_step_exception_keyword, - step_param['step_no'])) +def verification_step_exception(step_param, step_id=None): + logger.warning('{} {} {}'.format(vrc_step_exception_keyword, + step_param['step_no'], make_json_string(step_id=step_id))) -def verification_step_end(step_param, step_result, step_end_cuc): +def verification_step_end(step_param, step_result, step_end_cuc, step_id): logger.info('{} {} {}'.format(vrc_step_keyword_done, step_param['step_no'], encode_to_json_string(step_number=step_param['step_no'], timestamp=step_end_cuc, + step_id=step_id, step_result=step_result))) if step_result is True: logger.info('Verification for step {} was passed successful. +++ OK +++\n'.format(step_param['step_no'])) @@ -154,12 +183,12 @@ class StepSummary: def had_exception(self): self.has_exception = True # -------------------------------------------- - +# Command log output def write_log_step_header(step_param, pool_name, step_start_cuc): logger.info('STEP {} (starting from {})' .format(step_param['step_no'], step_start_cuc)) - logger.info(step_param['msg']) + logger.info(step_param['descr']) if 'comment' in step_param: if len(step_param['comment']) > 0: logger.info('Comment: {}'.format(step_param['comment'])) @@ -171,13 +200,20 @@ def write_log_step_footer(step_param, step_result): else: logger.warning('Step {} failed.'.format(step_param['step_no'])) - -def write_log_test_header(test, pool_name): +def write_log_test_header(test, pool_name=None): logger.info('-------------------------------------------------------------------------------') - logger.info('Running test {}\n\t\t\t\t\tversion {}\n\t\t\t\t\tpoolname = {}\n\t\t\t\t\tCUC-timestamp of test ' - 'start = {}\n\t\t\t\t\tlocal time = {}' - .format(test.id, test.version, pool_name, cfl.get_last_pckt_time(pool_name=pool_name, string=False), - datetime.datetime.now().isoformat())) + #logger.info('#Start Test: {}\n\t\t\t\t\tversion {}\n\t\t\t\t\tpoolname = {}\n\t\t\t\t\tCUC-timestamp of test ' + # 'start = {}\n\t\t\t\t\tlocal time = {}' + # .format(test.id, test.version, pool_name, cfl.get_last_pckt_time(pool_name=pool_name, string=False), + # datetime.datetime.now().isoformat())) + date_time = datetime.datetime.now().isoformat() + logger.info('{} {}'.format(cmd_test_start_keyword, make_json_string(test_name=test.id, + # version=test.version, + pool_name=pool_name, + cuc_start_time=cfl.get_last_pckt_time(pool_name=pool_name, string=False), + local_start_time=date_time, + run_id=test.run_id))) + logger.info('#Description: {} \n'.format(test.description)) if test.comment: logger.info('Comment: {}'.format(test.comment)) @@ -270,3 +306,4 @@ def write_postcondition_outcome(result): logger.info('Postconditions are fulfilled.\n') else: logger.warning('Postconditions are NOT fulfilled.\n') + diff --git a/Tst/testing_library/testlib/testing_logger.py b/Tst/testing_library/testlib/testing_logger.py index 242c8d1..7c9fafb 100644 --- a/Tst/testing_library/testlib/testing_logger.py +++ b/Tst/testing_library/testlib/testing_logger.py @@ -7,6 +7,7 @@ import logging.config import os import datetime import confignator +#from datetime import datetime from . import tools @@ -73,7 +74,12 @@ def extract_date(line): def my_formatter(): - return logging.Formatter(fmt='%(levelname)s\t%(asctime)s\tlogger: %(name)s:\t%(message)s') + #return logging.Formatter(fmt='%(levelname)s\t%(asctime)s\t%(id_code)s\t%(name)s:\t%(message)s') + return logging.Formatter(fmt='%(levelname)s\t%(asctime)s\t%(name)s:\t%(message)s') + +#def my_formatter_vrc(): +# return logging.Formatter(fmt='%(levelname)s\t%(asctime)s\t%(id_code)s\t%(name)s:\t%(message)s') + #return logging.Formatter(fmt='%(levelname)s\t%(asctime)s\t%(name)s:\t%(message)s') def cmd_log_handler(file_name): diff --git a/Tst/tst/generator_templates/co_class.py b/Tst/tst/generator_templates/co_class.py index cfbf5c5..a16b433 100644 --- a/Tst/tst/generator_templates/co_class.py +++ b/Tst/tst/generator_templates/co_class.py @@ -15,6 +15,7 @@ class ${testSpecClassName}: self.integrity = True self.exceptions = [] self.do_verification = do_verification + self.run_id = False # some tests are depended on other tests, thus information is stored on class level # insert class variables here diff --git a/Tst/tst/generator_templates/co_footer.py b/Tst/tst/generator_templates/co_footer.py index ceecf91..9372702 100644 --- a/Tst/tst/generator_templates/co_footer.py +++ b/Tst/tst/generator_templates/co_footer.py @@ -15,6 +15,8 @@ """ testing_logger.cmd_log_handler(__name__) + self.run_id = False + self.check_run_and_step_id(pool_name=pool_name) # log the header of this test report.write_log_test_header(test=self, pool_name=pool_name) @@ -56,6 +58,8 @@ # save the packet pool self.save_pool_in_file(pool_name=pool_name, save_pool=save_pool) + self.run_id = False + # log the summary of this test self.successful_steps = report.write_log_test_footer(test=self) @@ -70,3 +74,9 @@ if save_pool is True: pool_file = tools.get_path_for_testing_logs() + self.id + '.tmpool' cfl.savepool(filename=pool_file, pool_name=pool_name) + + def check_run_and_step_id(self, pool_name=None): + now = datetime.now() # current date and time + if not self.run_id and pool_name: + self.run_id = now.strftime("%Y%m%d%H%M%S") + return now.strftime("%Y%m%d%H%M%S%f") \ No newline at end of file diff --git a/Tst/tst/generator_templates/co_header.py b/Tst/tst/generator_templates/co_header.py index 2f220d2..b61b513 100644 --- a/Tst/tst/generator_templates/co_header.py +++ b/Tst/tst/generator_templates/co_header.py @@ -5,6 +5,7 @@ import os import time import importlib import threading +from datetime import datetime import confignator ccs_path = confignator.get_option('paths', 'ccs') sys.path.append(ccs_path) diff --git a/Tst/tst/generator_templates/co_post_condition.py b/Tst/tst/generator_templates/co_post_condition.py index eaf7c8a..b2dabb5 100644 --- a/Tst/tst/generator_templates/co_post_condition.py +++ b/Tst/tst/generator_templates/co_post_condition.py @@ -1,5 +1,5 @@ # VERIFY EVERY STEP ------------------------------------------------------------------------------------------------ - def step_verification(self, pool_name, step_start_cuc, param, summary, tc_id, ver_file, ver_class, ver_func): + def step_verification(self, pool_name, step_start_cuc, param, summary, tc_id, ver_file, ver_class, ver_func, step_id): """ This functions does the verification for every step :param pool_name: str @@ -25,7 +25,7 @@ ver_instance_call = getattr(ver_file, ver_class) instance = ver_instance_call() ver_func_call = getattr(instance, ver_func) - success = ver_func_call(pool_name, start_cuc=step_start_cuc, tc_id=tc_id) + success = ver_func_call(pool_name, start_cuc=step_start_cuc, tc_id=tc_id, run_id=self.run_id, step_id=step_id) summary.result = success except: logger.exception('Exception in the Verification for Step {}'.format(param['step_no'])) @@ -44,7 +44,7 @@ :return: True if all conditions were successfull. :rtype: bool """ - # testing_logger.cmd_log_handler(__name__) + testing_logger.cmd_log_handler(__name__) success = False logger.info('establishing postconditions started') diff --git a/Tst/tst/generator_templates/co_post_condition_entry.py b/Tst/tst/generator_templates/co_post_condition_entry.py index 2a8786a..75c7e19 100644 --- a/Tst/tst/generator_templates/co_post_condition_entry.py +++ b/Tst/tst/generator_templates/co_post_condition_entry.py @@ -13,3 +13,13 @@ print('Hello, I am the whole post-condition') #reset = tc.reset_all_housekeepings(pool_name=pool_name) success = True + + +#####-Save-##### + + + +#####-Save-##### + + + diff --git a/Tst/tst/generator_templates/co_pre_condition.py b/Tst/tst/generator_templates/co_pre_condition.py index 390bca5..2c79e9b 100644 --- a/Tst/tst/generator_templates/co_pre_condition.py +++ b/Tst/tst/generator_templates/co_pre_condition.py @@ -7,7 +7,7 @@ :return: bool True if the preconditions are fulfilled """ - #testing_logger.cmd_log_handler(__name__) + testing_logger.cmd_log_handler(__name__) success = False logger.info('establishing preconditions started') @@ -32,10 +32,11 @@ :return: tc_id: """ testing_logger.cmd_log_handler(__name__) + step_id = self.check_run_and_step_id(pool_name=pool_name) step_start_cuc = cfl.get_last_pckt_time(pool_name=pool_name, string=False) report.command_step_begin(step_param=param, script_version=self.version(), pool_name=pool_name, - step_start_cuc=step_start_cuc) + step_start_cuc=step_start_cuc, run_id=self.run_id, step_id=step_id) summary = report.StepSummary(step_number=param['step_no']) tc_id = None - return step_start_cuc, summary, tc_id + return step_start_cuc, summary, tc_id, step_id diff --git a/Tst/tst/generator_templates/co_pre_condition_entry.py b/Tst/tst/generator_templates/co_pre_condition_entry.py index 2a38ef3..503f308 100644 --- a/Tst/tst/generator_templates/co_pre_condition_entry.py +++ b/Tst/tst/generator_templates/co_pre_condition_entry.py @@ -17,3 +17,13 @@ success = True +#####-Save-##### + + + + + +#####-Save-##### + + + diff --git a/Tst/tst/generator_templates/co_step.py b/Tst/tst/generator_templates/co_step.py index 81e6629..d8b4591 100644 --- a/Tst/tst/generator_templates/co_step.py +++ b/Tst/tst/generator_templates/co_step.py @@ -2,10 +2,10 @@ def step_${testStepNumber}(self, pool_name): param = { 'step_no': '$testStepNumber', - 'msg': '$testStepDescription', + 'descr': '$testStepDescription', 'comment': '$testStepComment' } - step_start_cuc, summary, tc_id = self.begin_steps(pool_name=pool_name, param=param) + step_start_cuc, summary, tc_id, step_id = self.begin_steps(pool_name=pool_name, param=param) try: ########---The defined step starts here---######## @@ -14,16 +14,16 @@ ########---The defined step ends here---######## except Exception as e: - report.command_step_exception(step_param=param) + report.command_step_exception(step_param=param, step_id=step_id) logger.exception('Exception in the try block of the step') summary.result = False summary.had_exception() finally: step_end_cuc = cfl.get_last_pckt_time(pool_name=pool_name, string=False) - report.command_step_end(step_param=param, step_end_cuc=step_end_cuc) + report.command_step_end(step_param=param, step_end_cuc=step_end_cuc, step_id=step_id) summary =self.step_verification(pool_name=pool_name, step_start_cuc=step_start_cuc, param=param, tc_id=tc_id, summary=summary, ver_file=${testSpecFileName}_verification, - ver_class="${testSpecClassName}Verification", ver_func="step_${testStepNumber}") + ver_class="${testSpecClassName}Verification", ver_func="step_${testStepNumber}", step_id=step_id) return summary diff --git a/Tst/tst/generator_templates/run_header.py b/Tst/tst/generator_templates/run_header.py index 789600d..6f5726b 100644 --- a/Tst/tst/generator_templates/run_header.py +++ b/Tst/tst/generator_templates/run_header.py @@ -10,6 +10,7 @@ print('current working directory: {}'.format(os.getcwd())) import confignator ccs_path = confignator.get_option('paths', 'ccs') sys.path.append(ccs_path) +import ccs_function_lib as cfl cfl.add_tst_import_paths() from testlib import tools from testlib import report @@ -18,7 +19,7 @@ from testlib import tc from testlib import precond from testlib import testing_logger from testlib import sim -logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) +logging.basicConfig(stream=sys.stdout, level=logging.INFO) import ${testSpecFileName}_command import ${testSpecFileName}_verification diff --git a/Tst/tst/generator_templates/ver_class.py b/Tst/tst/generator_templates/ver_class.py index 145044d..4e380dd 100644 --- a/Tst/tst/generator_templates/ver_class.py +++ b/Tst/tst/generator_templates/ver_class.py @@ -12,6 +12,7 @@ class ${testSpecClassName}Verification: self.precond_ok = False self.integrity = True self.exceptions = [] + self.run_id = False # some tests are depended on other tests, thus information is stored on class level # insert class variables here @@ -39,9 +40,22 @@ class ${testSpecClassName}Verification: # ------- analyze command log -> get step start CUC timestamps, TCid and step end CUC timestamps ------- # ToDo + self.run_id = False steps = analyse_command_log.get_steps(filename=command_log_file) tcs = analyse_command_log.get_sent_tcs(filename=command_log_file) # ------- loop over the verification steps, show progress ------- # ToDo # ------- show final result ------- # ToDo + + def vrc_step_begin(self, pool_name, param, run_id, step_id): + if run_id: + self.run_id = run_id + else: + if not self.run_id: + now = datetime.now() # current date and time + self.run_id = now.strftime("%Y%m%d%H%M%S") + + step_start_cuc = cfl.get_last_pckt_time(pool_name=pool_name, string=False) + report.verification_step_begin(step_param=param, script_version=self.version(), pool_name=pool_name, + step_start_cuc=step_start_cuc, run_id=self.run_id, step_id=step_id) diff --git a/Tst/tst/generator_templates/ver_header.py b/Tst/tst/generator_templates/ver_header.py index 3fa12b7..c27253d 100644 --- a/Tst/tst/generator_templates/ver_header.py +++ b/Tst/tst/generator_templates/ver_header.py @@ -12,6 +12,7 @@ sys.path.append(confignator.get_option('tst-paths', 'testing_library')) import ccs_function_lib as cfl +from datetime import datetime from testlib import report from testlib import analyse_command_log from testlib import testing_logger diff --git a/Tst/tst/generator_templates/ver_step.py b/Tst/tst/generator_templates/ver_step.py index 4e4e675..5c4f771 100644 --- a/Tst/tst/generator_templates/ver_step.py +++ b/Tst/tst/generator_templates/ver_step.py @@ -1,28 +1,21 @@ # STEP $testStepNumber -------------------------------------------------------------------------------------------------------- - def step_$testStepNumber(self, pool_name, start_cuc=None, tc_id=None): + def step_$testStepNumber(self, pool_name, start_cuc=None, tc_id=None, run_id=None, step_id=None): testing_logger.ver_log_handler(__name__) param = { 'step_no': '$testStepNumber', - 'msg': '$testStepDescription', + 'descr': '$testStepDescription', 'comment': '$testStepComment' } - step_start_cuc = cfl.get_last_pckt_time(pool_name=pool_name, string=False) - report.verification_step_begin(step_param=param, script_version=self.version(), pool_name=pool_name, step_start_cuc=step_start_cuc) - # if online: use provided timestamp when the step started, use provided TcId - if start_cuc is not None: - pass - # if offline: read the command log file and extract the starting timestamp and TcId - else: - pass + self.vrc_step_begin(pool_name=pool_name, param=param, run_id=run_id, step_id=step_id) result = True try: $testStepVerificationCode except Exception as e: - report.verification_step_exception(step_param=param) + report.verification_step_exception(step_param=param, step_id=step_id) logger.exception('Exception in the try block of the step') result = False finally: step_end_cuc = cfl.get_last_pckt_time(pool_name=pool_name, string=False) - report.verification_step_end(step_param=param, step_result=result, step_end_cuc=step_end_cuc) + report.verification_step_end(step_param=param, step_result=result, step_end_cuc=step_end_cuc, step_id=step_id) return result -- GitLab