diff --git a/framework/python/src/common/testreport.py b/framework/python/src/common/testreport.py index 6acc6eac0..df31a5441 100644 --- a/framework/python/src/common/testreport.py +++ b/framework/python/src/common/testreport.py @@ -16,12 +16,12 @@ from datetime import datetime from weasyprint import HTML from io import BytesIO -from common import util +from common import util, logger from common.statuses import TestrunStatus import base64 import os from test_orc.test_case import TestCase -from jinja2 import Environment, FileSystemLoader +from jinja2 import Environment, FileSystemLoader, BaseLoader from collections import OrderedDict import re from bs4 import BeautifulSoup @@ -34,6 +34,8 @@ TEST_REPORT_STYLES = 'test_report_styles.css' TEST_REPORT_TEMPLATE = 'test_report_template.html' +LOGGER = logger.get_logger('REPORT') + # Locate parent directory current_dir = os.path.dirname(os.path.realpath(__file__)) @@ -65,12 +67,16 @@ def __init__(self, self._total_tests = total_tests self._results = [] self._module_reports = [] + self._module_templates = [] self._report_url = '' self._cur_page = 0 def add_module_reports(self, module_reports): self._module_reports = module_reports + def add_module_templates(self, module_templates): + self._module_templates = module_templates + def get_status(self): return self._status @@ -243,16 +249,20 @@ def to_html(self): optional_steps_to_resolve = self._get_optional_steps_to_resolve(json_data) module_reports = self._get_module_pages() + env_module = Environment(loader=BaseLoader()) pages_num = self._pages_num(json_data) - total_pages = pages_num + len(module_reports) + 1 - if len(steps_to_resolve) > 0: - total_pages += 1 - if (len(optional_steps_to_resolve) > 0 - and json_data['device']['test_pack'] == 'Pilot Assessment' - ): - total_pages += 1 - - return template.render(styles=styles, + module_templates = [ + env_module.from_string(s).render( + json_data=json_data, + device=json_data['device'], + logo=logo, + icon_qualification=icon_qualification, + icon_pilot=icon_pilot, + version=self._version, + ) for s in self._module_templates + ] + + return self._add_page_counter(template.render(styles=styles, logo=logo, icon_qualification=icon_qualification, icon_pilot=icon_pilot, @@ -269,10 +279,19 @@ def to_html(self): optional_steps_to_resolve=optional_steps_to_resolve, module_reports=module_reports, pages_num=pages_num, - total_pages=total_pages, tests_first_page=TESTS_FIRST_PAGE, tests_per_page=TESTS_PER_PAGE, - ) + module_templates=module_templates + )) + + def _add_page_counter(self, html): + # Add page nums and total page + soup = BeautifulSoup(html, features='html5lib') + page_index_divs = soup.find_all('div', class_='page-index') + total_pages = len(page_index_divs) + for index, div in enumerate(page_index_divs): + div.string = f'Page {index+1}/{total_pages}' + return soup.prettify() def _pages_num(self, json_data): @@ -391,8 +410,8 @@ def _get_module_pages(self): if el.name == 'h1': current_size += 40 + h1_padding # Calculating the height of paired tables - elif (el.name == 'div' - and el['style'] == 'display:flex;justify-content:space-between;'): + elif (el.name == 'div' and el.has_attr('id') + and el['id'] == 'paired'): tables = el.findChildren('table', recursive=True) current_size = max( map(lambda t: len( diff --git a/framework/python/src/core/session.py b/framework/python/src/core/session.py index f2e5466d3..ffbb9d26f 100644 --- a/framework/python/src/core/session.py +++ b/framework/python/src/core/session.py @@ -100,6 +100,9 @@ def __init__(self, root_dir): # All historical reports self._module_reports = [] + # Module report templates + self._module_templates = [] + # Parameters specified when starting Testrun self._runtime_params = [] @@ -398,6 +401,9 @@ def get_test_results(self): def get_module_reports(self): return self._module_reports + def get_module_templates(self): + return self._module_templates + def get_report_tests(self): """Returns the current test results in JSON-friendly format (in Python dictionary)""" @@ -465,6 +471,9 @@ def set_test_result_error(self, result): def add_module_report(self, module_report): self._module_reports.append(module_report) + def add_module_template(self, module_template): + self._module_templates.append(module_template) + def get_all_reports(self): reports = [] @@ -658,7 +667,7 @@ def _remove_invalid_questions(self, questions): valid_questions.append(question) else: - LOGGER.debug(f'Removed unrecognised question: {question["question"]}') + LOGGER.debug(f'Removed unrecognised question: {question["question"]}') # pylint: disable=W1405 # Return the list of valid questions return valid_questions @@ -704,7 +713,7 @@ def validate_profile_json(self, profile_json): question.get('question')) if format_q is None: - LOGGER.error(f'Unrecognised question: {question.get("question")}') + LOGGER.error(f'Unrecognised question: {question.get("question")}') # pylint: disable=W1405 # Just ignore additional questions continue @@ -789,6 +798,7 @@ def reset(self): self._report_url = None self._total_tests = 0 self._module_reports = [] + self._module_templates = [] self._results = [] self._started = None self._finished = None diff --git a/framework/python/src/test_orc/test_orchestrator.py b/framework/python/src/test_orc/test_orchestrator.py index d133fefd9..787de08e6 100644 --- a/framework/python/src/test_orc/test_orchestrator.py +++ b/framework/python/src/test_orc/test_orchestrator.py @@ -177,6 +177,7 @@ def run_test_modules(self): generated_report_json = self._generate_report() report.from_json(generated_report_json) report.add_module_reports(self.get_session().get_module_reports()) + report.add_module_templates(self.get_session().get_module_templates()) device.add_report(report) self._write_reports(report) @@ -549,8 +550,17 @@ def _run_test_module(self, module): self.get_session().add_module_report(module_report) except (FileNotFoundError, PermissionError): LOGGER.debug("Test module did not produce a html module report") + # Get the Jinja report + jinja_file = f"{module.container_runtime_dir}/{module.name}_report.j2.html" + try: + with open(jinja_file, "r", encoding="utf-8") as f: + module_template = f.read() + LOGGER.debug(f"Adding module template for module {module.name}") + self.get_session().add_module_template(module_template) + except (FileNotFoundError, PermissionError): + LOGGER.debug("Test module did not produce a module template") - LOGGER.info(f"Test module {module.name} has finished") + # LOGGER.info(f"Test module {module.name} has finished") def _get_container_logs(self, log_stream): """Resolve all current log data in the containers log_stream diff --git a/modules/test/base/base.Dockerfile b/modules/test/base/base.Dockerfile index 253270ea9..7a82301a7 100644 --- a/modules/test/base/base.Dockerfile +++ b/modules/test/base/base.Dockerfile @@ -80,5 +80,13 @@ COPY --from=builder /usr/local/etc/oui.txt /usr/local/etc/oui.txt # Activate the virtual environment by setting the PATH ENV PATH="/opt/venv/bin:$PATH" +# Common resource folder +ENV REPORT_TEMPLATE_PATH=/testrun/resources +# Jinja base template +ENV BASE_TEMPLATE_FILE=module_report_base.jinja2 + +# Copy base template +COPY resources/report/$BASE_TEMPLATE_FILE $REPORT_TEMPLATE_PATH/ + # Start the test module ENTRYPOINT [ "/testrun/bin/start" ] \ No newline at end of file diff --git a/modules/test/base/python/requirements.txt b/modules/test/base/python/requirements.txt index 0ed8a792d..5d12be720 100644 --- a/modules/test/base/python/requirements.txt +++ b/modules/test/base/python/requirements.txt @@ -6,4 +6,7 @@ protobuf==5.28.0 # User defined packages grpcio==1.67.1 grpcio-tools==1.67.1 -netifaces==0.11.0 \ No newline at end of file +netifaces==0.11.0 + +# Requirements for reports generation +Jinja2==3.1.4 \ No newline at end of file diff --git a/modules/test/base/python/src/test_module.py b/modules/test/base/python/src/test_module.py index 21de78143..42ee3ff85 100644 --- a/modules/test/base/python/src/test_module.py +++ b/modules/test/base/python/src/test_module.py @@ -42,6 +42,8 @@ def __init__(self, self._ipv6_subnet = os.environ.get('IPV6_SUBNET', '') self._dev_iface_mac = os.environ.get('DEV_IFACE_MAC', '') self._device_test_pack = json.loads(os.environ.get('DEVICE_TEST_PACK', '')) + self._report_template_folder = os.environ.get('REPORT_TEMPLATE_PATH') + self._base_template_file=os.environ.get('BASE_TEMPLATE_FILE') self._add_logger(log_name=log_name) self._config = self._read_config( conf_file=conf_file if conf_file is not None else CONF_FILE) @@ -137,14 +139,14 @@ def run_tests(self): else: result = getattr(self, test_method_name)() except Exception as e: # pylint: disable=W0718 - LOGGER.error(f'An error occurred whilst running {test["name"]}') + LOGGER.error(f'An error occurred whilst running {test["name"]}') # pylint: disable=W1405 LOGGER.error(e) traceback.print_exc() else: - LOGGER.error(f'Test {test["name"]} has not been implemented') + LOGGER.error(f'Test {test["name"]} has not been implemented') # pylint: disable=W1405 result = TestResult.ERROR, 'This test could not be found' else: - LOGGER.debug(f'Test {test["name"]} is disabled') + LOGGER.debug(f'Test {test["name"]} is disabled') # pylint: disable=W1405 result = (TestResult.DISABLED, 'This test did not run because it is disabled') diff --git a/modules/test/ntp/ntp.Dockerfile b/modules/test/ntp/ntp.Dockerfile index 4d9701464..c7ae7fee1 100644 --- a/modules/test/ntp/ntp.Dockerfile +++ b/modules/test/ntp/ntp.Dockerfile @@ -31,4 +31,7 @@ COPY $MODULE_DIR/conf /testrun/conf COPY $MODULE_DIR/bin /testrun/bin # Copy over all python files -COPY $MODULE_DIR/python /testrun/python \ No newline at end of file +COPY $MODULE_DIR/python /testrun/python + +# Copy Jinja template +COPY $MODULE_DIR/resources/report_template.jinja2 $REPORT_TEMPLATE_PATH/ \ No newline at end of file diff --git a/modules/test/ntp/python/src/ntp_module.py b/modules/test/ntp/python/src/ntp_module.py index 22fbf40ed..6a64b101c 100644 --- a/modules/test/ntp/python/src/ntp_module.py +++ b/modules/test/ntp/python/src/ntp_module.py @@ -16,19 +16,21 @@ from scapy.all import rdpcap, IP, IPv6, NTP, UDP, Ether import os from collections import defaultdict +from jinja2 import Environment, FileSystemLoader LOG_NAME = 'test_ntp' -MODULE_REPORT_FILE_NAME = 'ntp_report.html' +MODULE_REPORT_FILE_NAME = 'ntp_report.j2.html' NTP_SERVER_CAPTURE_FILE = '/runtime/network/ntp.pcap' STARTUP_CAPTURE_FILE = '/runtime/device/startup.pcap' MONITOR_CAPTURE_FILE = '/runtime/device/monitor.pcap' LOGGER = None +REPORT_TEMPLATE_FILE = 'report_template.jinja2' class NTPModule(TestModule): """NTP Test module""" - def __init__(self, + def __init__(self, # pylint: disable=R0917 module, conf_file=None, results_dir=None, @@ -49,11 +51,34 @@ def __init__(self, LOGGER = self._get_logger() def generate_module_report(self): + # Load Jinja2 template + page_max_height = 910 + header_height = 48 + summary_height = 135 + row_height = 42 + loader=FileSystemLoader(self._report_template_folder) + template = Environment(loader=loader).get_template(REPORT_TEMPLATE_FILE) + module_header='NTP Module' + # Summary table headers + summary_headers = [ + 'Requests to local NTP server', + 'Requests to external NTP servers', + 'Total NTP requests', + 'Total NTP responses' + ] + # Module data Headers + module_data_headers = [ + 'Source', + 'Destination', + 'Type', + 'Version', + 'Count', + 'Sync Request Average', + ] + # Extract NTP data from the pcap file ntp_table_data = self.extract_ntp_data() - html_content = '

NTP Module

' - # Set the summary variables local_requests = sum( 1 for row in ntp_table_data @@ -67,6 +92,14 @@ def generate_module_report(self): total_responses = sum(1 for row in ntp_table_data if row['Type'] == 'Server') + # Summary table data + summary_data = [ + local_requests, + external_requests, + total_requests, + total_responses + ] + # Initialize a dictionary to store timestamps for each unique combination timestamps = defaultdict(list) @@ -94,42 +127,9 @@ def generate_module_report(self): average_time_between_requests[key] = avg_diff - # Add summary table - html_content += (f''' - - - - - - - - - - - - - - - - - -
Requests to local NTP serverRequests to external NTP serversTotal NTP requestsTotal NTP responses
{local_requests}{external_requests}{total_requests}{total_responses}
- ''') - + # Module table data + module_table_data = [] if total_requests + total_responses > 0: - table_content = ''' - - - - - - - - - - - - ''' # Generate the HTML table with the count column for (src, dst, typ, @@ -144,37 +144,44 @@ def generate_module_report(self): else: avg_formatted_time = 'N/A' - table_content += f''' - - - - - - - - ''' - - table_content += ''' - -
SourceDestinationTypeVersionCountSync Request Average
{src}{dst}{typ}{version}{cnt}{avg_formatted_time}
- ''' - html_content += table_content - - else: - html_content += (''' -
-
- No NTP traffic detected from the device -
''') - - LOGGER.debug('Module report:\n' + html_content) + module_table_data.append({ + 'src': src, + 'dst': dst, + 'typ': typ, + 'version': version, + 'cnt': cnt, + 'avg_fmt': avg_formatted_time + }) + + # Handling the possible table split + table_height = (len(module_table_data) + 1) * row_height + page_useful_space = page_max_height - header_height - summary_height + pages = table_height // (page_useful_space) + rows_on_page = ((page_useful_space) // row_height) - 1 + start = 0 + report_html = '' + for page in range(pages+1): + end = start + min(len(module_table_data), rows_on_page) + module_header_repr = module_header if page == 0 else None + page_html = template.render( + base_template=self._base_template_file, + module_header=module_header_repr, + summary_headers=summary_headers, + summary_data=summary_data, + module_data_headers=module_data_headers, + module_data=module_table_data[start:end] + ) + report_html += page_html + start = end + + LOGGER.debug('Module report:\n' + report_html) # Use os.path.join to create the complete file path report_path = os.path.join(self._results_dir, MODULE_REPORT_FILE_NAME) # Write the content to a file with open(report_path, 'w', encoding='utf-8') as file: - file.write(html_content) + file.write(report_html) LOGGER.info('Module report generated at: ' + str(report_path)) diff --git a/modules/test/ntp/resources/report_template.jinja2 b/modules/test/ntp/resources/report_template.jinja2 new file mode 100644 index 000000000..c3601b67b --- /dev/null +++ b/modules/test/ntp/resources/report_template.jinja2 @@ -0,0 +1,31 @@ +{% extends base_template %} +{% block content %} +{% if module_data %} + + + + {% for header in module_data_headers %} + + {% endfor %} + + + + {% for row in module_data %} + + + + + + + + + {% endfor %} + +
{{ header }}
{{ row['src'] }}{{ row['dst'] }}{{ row['typ'] }}{{ row['version'] }}{{ row['cnt'] }}{{ row['avg_fmt'] }}
+{% else %} +
+
+ No NTP traffic detected from the device +
+{% endif %} +{% endblock %} \ No newline at end of file diff --git a/modules/test/tls/python/src/tls_module.py b/modules/test/tls/python/src/tls_module.py index 1405ad31c..ca7bed260 100644 --- a/modules/test/tls/python/src/tls_module.py +++ b/modules/test/tls/python/src/tls_module.py @@ -229,7 +229,7 @@ def generate_module_report(self): summary_table = f'\n{summary_table}' summary_table += f''' -
+
Certificate Information
{cert_table} diff --git a/resources/report/module_report_base.jinja2 b/resources/report/module_report_base.jinja2 new file mode 100644 index 000000000..009b7646d --- /dev/null +++ b/resources/report/module_report_base.jinja2 @@ -0,0 +1,55 @@ +{% raw %} +
+
+
+ {# Badge #} +

+ {% if json_data['device']['test_pack'] == 'Device Qualification' %} + + Device Qualification + {% else %} + + Pilot Assessment + {% endif %} +

+ {{ title }} +
+ + {{ device['manufacturer'] }} + {{ device['model']}} + + Testrun +
+{% endraw %} +
+ {% if module_header %} +

{{ module_header }}

+ + {% else %} +
+ {% endif %} + + + {% for header in summary_headers %} + + {% endfor %} + + + + + {% for cell in summary_data %} + + {% endfor %} + + +
{{ header }}
{{ cell }}
+ {% block content %}{% endblock content %} +
+{% raw %} + +
+
+{% endraw %} \ No newline at end of file diff --git a/resources/report/test_report_template.html b/resources/report/test_report_template.html index fbd8d1c68..0d08f65ea 100644 --- a/resources/report/test_report_template.html +++ b/resources/report/test_report_template.html @@ -10,10 +10,8 @@ - {% set page_index = namespace(value=0) %} {# Test Results #} {% for page in range(pages_num) %} - {% set page_index.value = page_index.value+1 %}
{{ header_macros.header(loop.first, "Testrun report", json_data, device, logo, icon_qualification, icon_pilot)}} {% if loop.first %} @@ -105,14 +103,13 @@

Results List ({{ successful_tests }}/{{ tot

{% endfor %} {# Steps to resolve Device qualification #} {% if steps_to_resolve|length > 0 and json_data['device']['test_pack'] == 'Device Qualification' %} - {% set page_index.value = page_index.value+1 %}
{{ header_macros.header(False, "Testrun report", json_data, device, logo, icon_qualification, icon_pilot)}}

Non-compliant tests and suggested steps to resolve

@@ -137,13 +134,16 @@

Non-compliant tests and suggested steps to resolve

{% endfor %}
{% endif %} + {# Modules reports Jinja #} + {% for template in module_templates %} + {{ template }} + {% endfor %} {# Modules reports #} {% for module in module_reports %} - {% set page_index.value = page_index.value+1 %}
{{ header_macros.header(False, "Testrun report", json_data, device, logo, icon_qualification, icon_pilot)}}
@@ -151,13 +151,12 @@

Non-compliant tests and suggested steps to resolve

{% endfor %} {# Device profile #} - {% set page_index.value = page_index.value+1 %}
{{ header_macros.header(False, "Testrun report", json_data, device, logo, icon_qualification, icon_pilot)}}

Device profile

@@ -186,13 +185,12 @@

Device profile

{# Pilot steps to resolve#} {% if json_data['device']['test_pack'] == 'Pilot Assessment' and optional_steps_to_resolve|length > 0 %} - {% set page_index.value = page_index.value + 1 %}
{{ header_macros.header(False, "Testrun report", json_data, device, logo, icon_qualification, icon_pilot)}}

Recommendations for Device Qualification

@@ -233,7 +231,7 @@

Recommendations for Device Qualification

{% endfor %}
{% endif %} diff --git a/testing/unit/ntp/ntp_module_test.py b/testing/unit/ntp/ntp_module_test.py index 52bd32aa9..3b865d531 100644 --- a/testing/unit/ntp/ntp_module_test.py +++ b/testing/unit/ntp/ntp_module_test.py @@ -26,6 +26,7 @@ OUTPUT_DIR = os.path.join(TEST_FILES_DIR,'output/') REPORTS_DIR = os.path.join(TEST_FILES_DIR,'reports/') CAPTURES_DIR = os.path.join(TEST_FILES_DIR,'captures/') +MODULE_FILES_DIR = 'modules/test/' + MODULE LOCAL_REPORT = os.path.join(REPORTS_DIR,'ntp_report_local.html') LOCAL_REPORT_NO_NTP = os.path.join(REPORTS_DIR,'ntp_report_local_no_ntp.html') @@ -67,7 +68,6 @@ def ntp_module_report_test(self): new_report_name = 'ntp_local.html' new_report_path = os.path.join(OUTPUT_DIR, new_report_name) shutil.copy(report_out_path, new_report_path) - self.assertEqual(report_out, report_local) # Test the module report generation if no DNS traffic @@ -100,7 +100,7 @@ def ntp_module_report_no_ntp_test(self): wrpcap(startup_cap_file, packets_startup) wrpcap(monitor_cap_file, packets_monitor) - ntp_module = NTPModule(module='dns', + ntp_module = NTPModule(module=MODULE, results_dir=OUTPUT_DIR, ntp_server_capture_file=ntp_server_cap_file, startup_capture_file=startup_cap_file, @@ -136,4 +136,3 @@ def ntp_module_report_no_ntp_test(self): if not test_result.wasSuccessful(): sys.exit(1) # Return a non-zero exit code for failures sys.exit(0) # Return zero for success - \ No newline at end of file diff --git a/testing/unit/ntp/reports/ntp_report_local.html b/testing/unit/ntp/reports/ntp_report_local.html index 1fe5e3f3a..89e736e17 100644 --- a/testing/unit/ntp/reports/ntp_report_local.html +++ b/testing/unit/ntp/reports/ntp_report_local.html @@ -1,115 +1,179 @@ -

NTP Module

- - - - - - - - - - - - - - - - - -
Requests to local NTP serverRequests to external NTP serversTotal NTP requestsTotal NTP responses
6338101104
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SourceDestinationTypeVersionCountSync Request Average
10.10.10.15216.239.35.12Client4837.942 seconds
216.239.35.1210.10.10.15Server48N/A
10.10.10.15216.239.35.4Client4837.834 seconds
216.239.35.410.10.10.15Server48N/A
10.10.10.15216.239.35.8Client4838.056 seconds
216.239.35.810.10.10.15Server48N/A
10.10.10.15216.239.35.0Client41420.601 seconds
216.239.35.010.10.10.15Server417N/A
10.10.10.1510.10.10.5Client46313.057 seconds
10.10.10.510.10.10.15Server463N/A
- \ No newline at end of file + +
+
+
+ {# Badge #} +

+ {% if json_data['device']['test_pack'] == 'Device Qualification' %} + + Device Qualification + {% else %} + + Pilot Assessment + {% endif %} +

+ {{ title }} +
+ + {{ device['manufacturer'] }} + {{ device['model']}} + + Testrun +
+ +
+ +

NTP Module

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Requests to local NTP serverRequests to external NTP serversTotal NTP requestsTotal NTP responses
6338101104
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SourceDestinationTypeVersionCountSync Request Average
10.10.10.15216.239.35.12Client4837.942 seconds
216.239.35.1210.10.10.15Server48N/A
10.10.10.15216.239.35.4Client4837.834 seconds
216.239.35.410.10.10.15Server48N/A
10.10.10.15216.239.35.8Client4838.056 seconds
216.239.35.810.10.10.15Server48N/A
10.10.10.15216.239.35.0Client41420.601 seconds
216.239.35.010.10.10.15Server417N/A
10.10.10.1510.10.10.5Client46313.057 seconds
10.10.10.510.10.10.15Server463N/A
+ + +
+ + +
+
diff --git a/testing/unit/ntp/reports/ntp_report_local_no_ntp.html b/testing/unit/ntp/reports/ntp_report_local_no_ntp.html index c93ab885f..abe616a38 100644 --- a/testing/unit/ntp/reports/ntp_report_local_no_ntp.html +++ b/testing/unit/ntp/reports/ntp_report_local_no_ntp.html @@ -1,24 +1,71 @@ -

NTP Module

- - - - - - - - - - - - - - - - - -
Requests to local NTP serverRequests to external NTP serversTotal NTP requestsTotal NTP responses
0000
- -
-
- No NTP traffic detected from the device -
\ No newline at end of file + +
+
+
+ {# Badge #} +

+ {% if json_data['device']['test_pack'] == 'Device Qualification' %} + + Device Qualification + {% else %} + + Pilot Assessment + {% endif %} +

+ {{ title }} +
+ + {{ device['manufacturer'] }} + {{ device['model']}} + + Testrun +
+ +
+ +

NTP Module

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Requests to local NTP serverRequests to external NTP serversTotal NTP requestsTotal NTP responses
0000
+ + +
+
+ No NTP traffic detected from the device +
+ + +
+ + +
+
diff --git a/testing/unit/tls/reports/tls_report_ext_local.html b/testing/unit/tls/reports/tls_report_ext_local.html index 7e691f66a..bde424a0e 100644 --- a/testing/unit/tls/reports/tls_report_ext_local.html +++ b/testing/unit/tls/reports/tls_report_ext_local.html @@ -22,7 +22,7 @@

TLS Module

-
+
Certificate Information
@@ -121,7 +121,7 @@
Certificate Extensions
-
+
Certificate Information
diff --git a/testing/unit/tls/reports/tls_report_local.html b/testing/unit/tls/reports/tls_report_local.html index 72b2e5a1a..4d1af0404 100644 --- a/testing/unit/tls/reports/tls_report_local.html +++ b/testing/unit/tls/reports/tls_report_local.html @@ -22,7 +22,7 @@

TLS Module

-
+
Certificate Information
@@ -151,7 +151,7 @@
Certificate Extensions
-
+
Certificate Information
@@ -281,7 +281,7 @@
Certificate Extensions
-
+
Certificate Information
@@ -411,7 +411,7 @@
Certificate Extensions
-
+
Certificate Information
diff --git a/testing/unit/tls/reports/tls_report_single.html b/testing/unit/tls/reports/tls_report_single.html index 36adffb94..0f6a5a4d6 100644 --- a/testing/unit/tls/reports/tls_report_single.html +++ b/testing/unit/tls/reports/tls_report_single.html @@ -22,7 +22,7 @@

TLS Module

-
+
Certificate Information
@@ -125,7 +125,7 @@
Subject Information
-
+
Certificate Information