From d6dc600cc71524ce86f541cbeb14929bfb57c936 Mon Sep 17 00:00:00 2001 From: Lance Xu Date: Tue, 5 Dec 2023 11:38:42 -0500 Subject: [PATCH] Add rendering collect bundle files to report tool This update adds the collect bundle to report tool. The collect bundle will show after the system info and results section. The layout for collect bundle will be the same as the results section. Test Plan: PASS: Verify the collect bundle section is shown below results section PASS: Verify all collect bundle folders are shown PASS: Verify menus are levelled with '+'/'-' function to show/hide PASS: Verify menus are colored dark green and items are light green PASS: Verify empty folders are showing grey with disabled click PASS: Verify empty files are showing grey with disabled click PASS: Verify '.log', '.conf', '.info', '.json', '.alarm', '.pid', '.list', '.lock', '.txt' files can be directly viewed when opened PASS: Verify handling of files that are not in the above extension PASS: Verify a new window is opened if the file is viewable PASS: Verify the file will be loaded appropriately PASS: Verify a download popup is opened if the file is not viewable PASS: Verify index.html is in a reasonable size PASS: Verify index.html loading time is reasonable PASS: Verify the generated html with css content has no error in console Story: 2010533 Task: 49191 Change-Id: I71c4c6b39ca68464baf09c7d1708348e30989fda Signed-off-by: Lance Xu --- .../collector/debian-scripts/report/render.py | 154 ++++++++++++++++-- 1 file changed, 138 insertions(+), 16 deletions(-) diff --git a/tools/collector/debian-scripts/report/render.py b/tools/collector/debian-scripts/report/render.py index 72aae54b..43f80c14 100755 --- a/tools/collector/debian-scripts/report/render.py +++ b/tools/collector/debian-scripts/report/render.py @@ -6,17 +6,19 @@ # ######################################################################## # -# This file contains the Render function -# The Rendering tool visualizes the collect bundle and generates index.html file +# This file contains the Render function. +# The Rendering tool visualizes the collect bundle and generates +# an index.html file # ######################################################################## from datetime import datetime import os +from pathlib import Path def extract_section(log_contents, start_phrase): - """extract the correlated or plugin content of the summary + """Extract the correlated or plugin content of the summary Parameters: log_contents (string): content of the log @@ -32,7 +34,7 @@ def extract_section(log_contents, start_phrase): def remove_timestamp(text): - """remove timestamp of summary message + """Remove timestamp of summary message Parameters: text (string): the summary message @@ -51,7 +53,7 @@ def remove_timestamp(text): def remove_emptyinfo(text): - """ remove 'INFO' text of summary message + """Remove 'INFO' text of summary message Parameters: text (string): the summary message @@ -66,7 +68,7 @@ def remove_emptyinfo(text): def process_section(section, title): - """return text with timestamp and INFO: removed + """Return text with timestamp and INFO: removed Parameters: section (string): the message of the correlated/plugins section @@ -79,7 +81,7 @@ def process_section(section, title): def classify_node(data): - """classify node type in system_info summary + """Classify node type in system_info summary Parameters: data (string): the summary of system_info @@ -92,7 +94,7 @@ def classify_node(data): def controller_sort(x): - """sort the controller, place the controller-0 first + """Sort the controller, place the controller-0 first Parameters: x (list): list of controller info @@ -101,7 +103,7 @@ def controller_sort(x): def html_css(): - """static css code of the rendering tool + """Static css code of the rendering tool iframe, textarea: the content panel showing information #show-worker: the show more worker button @@ -193,7 +195,7 @@ def html_css(): margin-top: 10px; }} - .content-item, .content-itemtwo {{ + .content-item, .content-itemtwo, .content-itemthree {{ display: none; }} @@ -218,6 +220,31 @@ def html_css(): color: #2F4F4F; }} + .caret {{ + cursor: pointer; + user-select: none; + color: #00857e; + font-weight: bold; + }} + + .caret::before {{ + content: '+'; + color: #2F4F4F; + margin-right: 6px; + }} + + .caret-down::before {{ + color: #2F4F4F; + content: '-'; + }} + + .text-color {{ + color: #00ada4; + }} + + .nested {{ display: none; }} + .active {{ display: block; }} + """ @@ -225,7 +252,7 @@ def html_css(): def html_script(): - """static script code + """Static script code Functions: toggleContent: show content in System Info section @@ -234,6 +261,7 @@ def html_script(): showContentStorage: display content of selected storage item showContentWorker: display content of selected worker item showContentTwo: display content of result section + toggleTree: show the collect bundle """ html_content_script = """ """ @@ -402,7 +466,7 @@ def html_script(): def html_info(sys_section): - """system info part generation + """System info part generation reads from plugin/system_info and show by different types order: controller, storage(if there exists), worker(if there exists) @@ -505,7 +569,7 @@ def html_info(sys_section): def html_result(log_contents, output_dir): - """result part generation in the menu-content style + """Result part generation in the menu-content style generates correlated results, plugin results, and the items under them subitems for plugins and correlated results under separate menus @@ -575,13 +639,70 @@ def html_result(log_contents, output_dir): html_content_two += f'

Plugin Results

' html_content_two += """ - - +
""" return html_content_two +def html_collect(): + """Collect bundle code generation + + Calls a helper function to to generate the collect bundle + """ + os.chdir('../../') + current_directory = Path('.') + tree_html = "" + content_html = "
" + target_dir = current_directory.resolve() + newtree_html, newcontent_html = generate_directory_tree(current_directory, target_dir, True) + tree_html += newtree_html + content_html += newcontent_html + content_html += "
" + html_content_three = """
" + content_html + "
" + return html_content_three + + +def generate_directory_tree(directory_path, target_dir, is_top_level=False): + """Helper function for Collect bundle generation + + Parameters: + directory_path(Path): the path of the directory in each call + target_dir(string): the path of the file/folder + is_top_level(bool): if the level is the top level of the collect bundle + """ + directory_name = directory_path.name + tree_html = "" + content_html = "" + approved_list = ['.log', '.conf', '.info', '.json', '.alarm', '.pid', '.list', '.lock', '.txt'] + if not is_top_level: + tree_html = f'
  • {directory_name}
      ' + for item in directory_path.iterdir(): + try: + if item.is_dir() and item.name != "report_analysis": + nested_tree_html, nested_content_html = generate_directory_tree(item, target_dir) + tree_html += nested_tree_html + content_html += nested_content_html + elif item.is_file(): + if os.path.getsize(item) == 0: + tree_html += f'
    • {item}
    • ' + else: + if item.name.endswith(tuple(approved_list)): + tree_html += f'
    • {item.name}
    • ' + content_html += f'

      {item.name}

      ' + else: + if not item.name.endswith(".tgz"): + tree_html += f'
    • {item}
    • ' + # if it's permission error, just skip reading the file or folder + except PermissionError as e: + continue + if not is_top_level: + tree_html += '
  • ' + + return tree_html, content_html + + # main def main(input_dir, output_dir): reportlog_path = os.path.join(output_dir, 'report.log') @@ -596,8 +717,9 @@ def main(input_dir, output_dir): html_file = os.path.abspath(os.path.join(output_dir, 'index.html')) sys_section = sysinfo_contents.strip().split("\n\n") - html_content = html_css() + html_info(sys_section) + html_result(log_contents, output_dir) + html_script() + html_content = html_css() + html_info(sys_section) + html_result(log_contents, output_dir) html_content = html_content.format() + html_content += html_collect() + html_script() # write the HTML content to file with open(html_file, "w") as file: