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