From 36d8a0f27ba6c096e986480e3330f4bf7661e59c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dominik=20M=C3=B6slinger?= <dominik.moeslinger@univie.ac.at>
Date: Thu, 15 Jul 2021 16:20:00 +0200
Subject: [PATCH] TST: Output File improvement, not fully functional

---
 Ccs/poolview_sql.py                           | 14 ++--
 Tst/progress_view/progress_view.py            | 83 +++++++++++++++++++
 .../testlib/analyse_test_run.py               | 46 +++++++---
 Tst/tst/tst.cfg                               |  9 +-
 Tst/tst/tst.py                                |  2 +
 5 files changed, 131 insertions(+), 23 deletions(-)

diff --git a/Ccs/poolview_sql.py b/Ccs/poolview_sql.py
index cdd2be5..ff31df5 100644
--- a/Ccs/poolview_sql.py
+++ b/Ccs/poolview_sql.py
@@ -1879,7 +1879,7 @@ class TMPoolView(Gtk.Window):
         scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER)
         rule_box = Gtk.HBox()
         rule_box.set_spacing(3)
-        rule_box.pack_start(Gtk.Label('Filters: '), 0, 0, 0)
+        rule_box.pack_start(Gtk.Label(label='Filters: '), 0, 0, 0)
         scrolled_window.add(rule_box)
 
         #scrolled_window.add(resize_view_check_button)
@@ -2012,7 +2012,7 @@ class TMPoolView(Gtk.Window):
     def context_menu(self):
         menu = Gtk.Menu()
 
-        item = Gtk.MenuItem('TEST')
+        item = Gtk.MenuItem(label='TEST')
         item.connect('activate', self.menu_test)
         menu.append(item)
         return menu
@@ -2295,7 +2295,8 @@ class TMPoolView(Gtk.Window):
         self.rawswitch.connect('toggled', self.set_tm_data_view, None, True)
         # self.sortswitch = Gtk.CheckButton.new_with_label('Sort by Name')
         # self.sortswitch.connect('toggled', self.set_tm_data_view, )
-        switchbox = Gtk.Box(Gtk.Orientation.HORIZONTAL)
+        #switchbox = Gtk.Box(Gtk.Orientation.HORIZONTAL)
+        switchbox = Gtk.HBox()
         switchbox.pack_start(self.rawswitch, 0, 0, 0)
         # switchbox.pack_end(self.sortswitch, 0, 0, 0)
 
@@ -3403,10 +3404,9 @@ class ExtractionDialog(Gtk.MessageDialog):
 
 class SavePoolDialog(Gtk.FileChooserDialog):
     def __init__(self, parent=None):
-        super(SavePoolDialog, self).__init__(title="Save packets", parent=parent, action=Gtk.FileChooserAction.SAVE,
-                                             buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
-                                                      Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
-
+        super(SavePoolDialog, self).__init__(title="Save packets", parent=parent, action=Gtk.FileChooserAction.SAVE)
+        self.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+                                                      Gtk.STOCK_SAVE, Gtk.ResponseType.OK)
         # Gtk.FileChooserDialog.__init__(self, "Save packets", parent=parent, action=Gtk.FileChooserAction.SAVE, buttons=(
         #     Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
 
diff --git a/Tst/progress_view/progress_view.py b/Tst/progress_view/progress_view.py
index 2b24cb6..dde08e1 100644
--- a/Tst/progress_view/progress_view.py
+++ b/Tst/progress_view/progress_view.py
@@ -13,6 +13,7 @@ cfl.add_tst_import_paths()
 from testlib import analyse_command_log
 from testlib import analyse_verification_log
 from testlib import testing_logger
+from testlib import analyse_test_run
 import dbus
 import time
 import data_model
@@ -279,6 +280,10 @@ 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.btn_output = Gtk.Button()
+        self.btn_output.set_label('Generate Output File')
+        self.btn_output.connect('clicked', self.on_save_as)
+        self.box_buttons.pack_start(self.btn_output, False, False, 0)
 
         self.sort_label = Gtk.Label()
         self.sort_label.set_text('Sort by Execution')
@@ -579,6 +584,29 @@ class TestProgressView(Gtk.ApplicationWindow):
             vrc_log.write('')
             vrc_log.close()
 
+
+    def on_save_as(self, *args):
+        self.save_as_file_dialog()
+        return
+
+    def save_as_file_dialog(self):
+        dialog = Save_to_File_Dialog(parent=self)
+        response = dialog.run()
+        if response == Gtk.ResponseType.OK:
+            folder = dialog.get_current_folder()
+            run_count = dialog.run_id_selection.get_active()
+            run = None
+            if run_count:
+                for run_id in self.run_count.keys():
+                    if self.run_count[run_id] == run_count:
+                        run = run_id
+            analyse_test_run.save_result_to_file('test', log_file_path=folder, run_id=run)
+            #confignator.save_option('tst-logging', 'output-file-path', folder)
+        elif response == Gtk.ResponseType.CANCEL:
+            pass
+        dialog.destroy()
+        return
+
     def on_destroy(self, *args):
         self.logger.info('Self-Destruct of the ProgressView Window initiated.\n')
         self.destroy()
@@ -1202,6 +1230,61 @@ class TestProgressView(Gtk.ApplicationWindow):
             self.restore_expanded_states(tree_store)
 
 
+class Save_to_File_Dialog(Gtk.FileChooserDialog):
+    def __init__(self, parent=None):
+        super(Save_to_File_Dialog, self).__init__(title='Please choose a Folder to save the Test Run',
+                                       parent=parent,
+                                       action=Gtk.FileChooserAction.SELECT_FOLDER)
+
+        self.win = parent
+        self.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK)
+        self.set_current_folder(confignator.get_option(section='tst-logging', option='output-file-path'))
+
+        area = self.get_content_area()
+
+        self.savedetailes = Gtk.HBox()  # Store everything in this box
+        self.savedetailes.set_border_width(15)
+
+        run_id_label = Gtk.Label(label='Select Run ID: ')
+
+        # Select the Run ID which should be printed to the File
+        self.run_id_selection = Gtk.ComboBoxText.new()  # Make the Combobox
+        if not self.win.sort_button.get_active():  # If sorted by steps, run id is not defined
+            self.run_id_selection.append_text('Whole Log File')  # Only possible selection is to save whole file
+            self.run_id_selection.set_button_sensitivity(False)
+            self.run_id_selection.set_active(0)
+            self.run_id_selection.set_tooltip_text('If Sorted by Executions, it is possible to limit the Output File to just one Run')
+        else:  # If sorted by executions add all available run ids
+            self.run_id_selection.append('0', 'Whole Log File')  # Give also the possibility to save whole file
+            for run_id in self.win.run_count:
+                self.run_id_selection.append(run_id, 'Run ' + self.win.run_count[run_id])  # Add all Run ids
+
+            model, iter = self.win.view.get_selection().get_selected()  # Get selected treeview row
+            if iter:  # If a selection is made try to set it as active row, otherwise Whole file is active row
+                selected_step_id = model.get_value(iter, 12)  # Get the value
+                if not selected_step_id:  # Only execution rows ('Run X') have entry at coloumn 12, others dont
+                    self.run_id_selection.set_active(0)
+                else:
+                    self.run_id_selection.set_active(int(self.win.run_count[selected_step_id]))
+            else:
+                self.run_id_selection.set_active(0)
+            self.run_id_selection.set_tooltip_text('Define which Run should be saved or the whole Log File')
+
+        test_report_label = Gtk.Label(label='Test Report: ')
+
+        self.test_report_int = Gtk.Entry()
+        self.test_report_int.set_tooltip_text('Select the Test Report Number (1-999) NOTE: Prior Versions could be overwritten, If emtpy it will be automatically generated')
+
+        self.savedetailes.pack_end(self.run_id_selection, False, True, 10)
+        self.savedetailes.pack_end(run_id_label, False, True, 10)
+        self.savedetailes.pack_end(self.test_report_int, False, True, 10)
+        self.savedetailes.pack_end(test_report_label, False, True, 10)
+
+        area.pack_start(self.savedetailes, False, True, 0)
+
+        self.show_all()
+        return
+
 def run():
     bus_name = confignator.get_option('dbus_names', 'progress-view')
     dbus.validate_bus_name(bus_name)
diff --git a/Tst/testing_library/testlib/analyse_test_run.py b/Tst/testing_library/testlib/analyse_test_run.py
index b5a89ff..6234ef1 100644
--- a/Tst/testing_library/testlib/analyse_test_run.py
+++ b/Tst/testing_library/testlib/analyse_test_run.py
@@ -8,6 +8,8 @@ import datetime
 import os
 from os import listdir
 from os.path import isfile, join
+import os, os.path
+import errno
 
 import sys
 sys.path.append(confignator.get_option('paths', 'ccs'))
@@ -22,10 +24,10 @@ test_name = 'test'
 cmd_log_file_end = '_command.log'
 vrc_log_file_end = '_verification.log'
 basic_log_file_path = confignator.get_option('tst-logging', 'test_run')
-basic_output_file_path = confignator.get_option('tst-logging', 'test_run')  # TODO: Set basic output path (Dominik)
+basic_output_file_path = confignator.get_option('tst-logging', 'output-file-path')
 output_file_header = ['Item', 'Description', 'Verification', 'TestResult']
 
-def result_as_csv(test_name, log_file_path=None, output_file_path=None):
+def save_result_to_file(test_name, log_file_path=None, output_file_path=None, run_id=None):
     """
     Analyses the command and verification log file and creates a csv output table
     :param str test_name: the name of the test and of its log files
@@ -42,15 +44,35 @@ def result_as_csv(test_name, log_file_path=None, output_file_path=None):
     cmd_steps = analyse_command_log.get_steps_and_commands(cmd_log_file)
     vrc_steps = analyse_verification_log.get_verification_steps(vrc_log_file)
 
-    name_start = 'IASW-{}-TS-{}-TR-'.format(test_name, cmd_steps[0]['version'])  # TODO: Check which name should be used, version always same in log file?
-    file_versions = []
+    cmd_steps_filtered = []
+    vrc_steps_filtered = []
+    # Filter for a specific run
+    if run_id:
+        for step in cmd_steps:
+            if step['run_id'] == run_id:
+                cmd_steps_filtered.append(step)
+
+        for step in vrc_steps:
+            if step['run_id'] == run_id:
+                vrc_steps_filtered.append(step)
 
-    for file_name in listdir(output_file_path):
-        if file_name.startswith(name_start):
-            file_versions.append(int(file_name.split('-')[-1].split('.')[0]))
+        cmd_steps = cmd_steps_filtered
+        vrc_steps = vrc_steps_filtered
+
+    name_start = '{}-TS-{}-TR-'.format(test_name, cmd_steps[0]['version'])
+    file_versions = []
+    try:
+        for file_name in listdir(output_file_path):
+            if file_name.startswith(name_start):
+                file_versions.append(int(file_name.split('-')[-1].split('.')[0]))
+
+        file_versions.sort()
+        file_count = file_versions[-1] + 1 if file_versions else 1
+    except FileNotFoundError:
+        print('Used Folder: "{}" does not yet exist, is now created'.format(output_file_path))
+        file_count = 1
+        os.makedirs(output_file_path)
 
-    file_versions.sort()
-    file_count = file_versions[-1] + 1 if file_versions else 1
     output_file_name_path = output_file_path + name_start + f'{file_count:03d}' + '.txt'
 
     with open(output_file_name_path, 'w', encoding='UTF8', newline='') as file:
@@ -76,7 +98,7 @@ def result_as_csv(test_name, log_file_path=None, output_file_path=None):
         # write comment line
         writer.writerow(['Comment', 'This is NOT a comment, still working on it', '', ''])  # TODO: Where is the comment given?
 
-        # write comment line
+        # write step line
         for step in cmd_steps:
             for vrc_step in vrc_steps:
                 if step['step_id'] == vrc_step['step_id']:
@@ -101,7 +123,7 @@ def get_version(steps):
     version_list = []
     for step in steps:
         if step['version'] not in version_list:
-            version_list.append()
+            version_list.append(step['version'])
     for count, version in enumerate(version_list):
         if count == 0:
             version_final = version
@@ -146,5 +168,5 @@ def show_basic_results(test_name, log_file_path=None):
     return
 
 if __name__ == '__main__':
-    result_as_csv(test_name)
+    save_result_to_file(test_name, run_id='20210713140200')
     #show_basic_results(test_name)
diff --git a/Tst/tst/tst.cfg b/Tst/tst/tst.cfg
index 2ba810c..b88eb80 100644
--- a/Tst/tst/tst.cfg
+++ b/Tst/tst/tst.cfg
@@ -10,14 +10,15 @@ level = DEBUG
 log-file-path = ${logging:log-dir}/tst/tst.log
 poolmanager = ${paths:tst}/logs_poolmanager/poolmanager.log
 test_run = ${paths:tst}/logs_test_runs/
+output-file-path = ${paths:tst}/logs_test_runs/output_files/
 
 [tst-preferences]
 show-json-view = True
-main-window-height = 1016
-main-window-width = 1848
-paned-position = 919
+main-window-height = 1025
+main-window-width = 1581
+paned-position = 960
 paned-position-codeblockreuse = 520
 
 [tst-history]
-last-folder = /home/sebastian/CCS/Tst/test_specs
+last-folder = /data/home/moeslinged94/smile/CCS/Tst/test_specs
 
diff --git a/Tst/tst/tst.py b/Tst/tst/tst.py
index a145c22..7ffa48a 100755
--- a/Tst/tst/tst.py
+++ b/Tst/tst/tst.py
@@ -536,11 +536,13 @@ class TstAppWindow(Gtk.ApplicationWindow):
         self.save_as_file_dialog()
 
     def save_as_file_dialog(self):
+        current_name = self.current_model().name
         current_model = self.current_model()
         dialog = Gtk.FileChooserDialog('Please choose a file',
                                        self,
                                        Gtk.FileChooserAction.SAVE,
                                        (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
+        dialog.set_current_name(current_name+'.json')
         self.add_filters(dialog)
         response = dialog.run()
         if response == Gtk.ResponseType.OK:
-- 
GitLab