Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
36d750c
Re-add TLS module report and udpate to new format
jhughesoti Oct 8, 2024
575f126
Update extensions processing
jhughesoti Oct 9, 2024
a946092
pylint
jhughesoti Oct 9, 2024
39b95c5
Merge branch 'dev' into feature/tls_module_report
jhughesoti Oct 9, 2024
e14f2f8
Merge branch 'dev' into feature/tls_module_report
jhughesoti Oct 11, 2024
afe6c9b
Merge branch 'dev' into feature/tls_module_report
jboddey Oct 18, 2024
8025ddc
Change HTML report in unit test
jboddey Oct 18, 2024
52b2423
fixed the failing unit tests (#905)
MariusBaldovin Oct 21, 2024
9ca6dba
Modify report design
jboddey Oct 21, 2024
1cb2da5
Merge branch 'dev' into feature/tls_module_report
jboddey Oct 21, 2024
099a037
Fix unit testing
jboddey Oct 21, 2024
8ee1cf4
Merge branch 'dev' into feature/tls_module_report
jboddey Oct 21, 2024
7102140
Merge branch 'dev' into feature/tls_module_report
jhughesoti Oct 22, 2024
a5350e5
Merge branch 'dev' into feature/tls_module_report
jboddey Oct 25, 2024
d2deaae
Feature/report outbound connections (#877)
jhughesoti Oct 28, 2024
d0d720b
Add sorting to report info
jhughesoti Oct 28, 2024
8d5d18b
fix unit tests
jhughesoti Oct 28, 2024
dacb552
merge dev
jhughesoti Oct 28, 2024
fb12257
pylint
jhughesoti Oct 28, 2024
950b694
pylint
jhughesoti Oct 28, 2024
d6f008b
Merge branch 'dev' into feature/tls_module_report
jboddey Nov 7, 2024
46a8741
Merge branch 'dev' into feature/tls_module_report
jboddey Nov 22, 2024
e74b33f
Add additional device config info and generate pdf
jboddey Nov 22, 2024
4427ff5
Fix pdf report generation
jboddey Nov 22, 2024
f895155
Fix pdf get value
jboddey Nov 22, 2024
f4f4358
Open file as binary
jboddey Nov 22, 2024
b6d65c8
Fix error
jboddey Nov 22, 2024
cfa4c76
Fix some formatting
jboddey Nov 22, 2024
f77ea0c
Update expected reports
jboddey Nov 22, 2024
4592ea7
Fix formatting
jboddey Nov 22, 2024
d5de670
Fix report test
jboddey Nov 22, 2024
8fcbda4
Add additional info to test devices
jboddey Nov 22, 2024
faf9090
beautifulsoup
hitnik Nov 27, 2024
e87bad7
refactor splitting module reports to pages
hitnik Nov 27, 2024
60065f9
Merge branch 'dev' into feature/tls_module_report
jhughesoti Nov 27, 2024
ef6a02b
style changes
hitnik Nov 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,13 @@ jobs:
- name: Run tests for reports
shell: bash {0}
run: bash testing/unit/run_report_test.sh testing/unit/report/report_test.py
- name: Archive HTML reports for modules
if: ${{ always() }}
run: sudo tar --exclude-vcs -czf html_reports.tgz testing/unit/report/output/
- name: Upload HTML reports
- name: Upload reports
uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
if: ${{ always() }}
with:
if-no-files-found: error
name: html-reports_${{ github.run_id }}
path: html_reports.tgz
name: reports_${{ github.run_id }}
path: testing/unit/report/output

pylint:
permissions: {}
Expand Down
153 changes: 100 additions & 53 deletions framework/python/src/common/testreport.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
from test_orc.test_case import TestCase
from jinja2 import Environment, FileSystemLoader
from collections import OrderedDict
import re
from bs4 import BeautifulSoup


DATE_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
RESOURCES_DIR = 'resources/report'
Expand Down Expand Up @@ -330,71 +333,115 @@ def _get_optional_steps_to_resolve(self, json_data):

return tests_with_recommendations


def _split_module_report_to_pages(self, reports):
"""Split report to pages by headers"""
reports_transformed = []

for report in reports:
if len(re.findall('<table class="module-summary"', report)) > 1:
indices = []
index = report.find('<table class="module-summary"')
while index != -1:
indices.append(index)
index = report.find('<table class="module-summary"', index + 1)
pos = 0
for i in indices[1:]:
page = report[pos:i].replace(
'"module-summary"', '"module-summary not-first"'
)
reports_transformed.append(page)
pos = i
page = report[pos:].replace(
'"module-summary"', '"module-summary not-first"'
)
reports_transformed.append(page)
else:
reports_transformed.append(report)

return reports_transformed


def _get_module_pages(self):
content_max_size = 913

reports = []

for module_reports in self._module_reports:
module_reports = self._split_module_report_to_pages(self._module_reports)

for module_report in module_reports:
# ToDo: Figure out how to make this dynamic
# Padding values from CSS
# Element sizes from inspection of rendered report
h1_padding = 8
module_summary_padding = 50 # 25 top and 25 bottom

# Reset values for each module report
data_table_active = False
data_rows_active = False
page_content = ''
content_size = 0
content = module_reports.split('\n')

for line in content:
if '<h1' in line:
content_size += 40 + h1_padding
elif 'module-summary' in line:
content_size += 85.333 + module_summary_padding

# Track module-data table state
elif '<table class="module-data"' in line:
data_table_active=True
elif '</table>' in line and data_table_active:
data_table_active=False

# Add module-data header size, ignore rows, should
# only be one so only care about a header existence
elif '<thead>' in line and data_table_active:
content_size += 41.333

# Track module-data table state
elif '<tbody>' in line and data_table_active:
data_rows_active = True
elif '</tbody>' in line and data_rows_active:
data_rows_active = False

# Add appropriate content size for each data row
# update if CSS changes for this element
elif '<tr>' in line and data_rows_active:
content_size += 42

# If the current line is within the content size limit
# we'll add it to this page, otherweise, we'll put it on the next
# page. Also make sure that if there is less than 40 pixels
# left after a data row, start a new page or the row will get cut off.
# Current row size is 42 # adjust if we update the
# "module-data tbody tr" element.
if content_size >= content_max_size or (
data_rows_active and content_max_size - content_size < 42):
# If in the middle of a table, close the table
if data_rows_active:
page_content += '</tbody></table>'
reports.append(page_content)
content_size = 0
# If in the middle of a data table, restart
# it for the rest of the rows
page_content = ('<table class=module-data></tbody>\n'
if data_rows_active else '')
page_content += line + '\n'
if len(page_content) > 0:
reports.append(page_content)

# Convert module report to list of html tags
soup = BeautifulSoup(module_report, features='html5lib')
children = list(
filter(lambda el: el.name is not None, soup.body.children)
)

for index, el in enumerate(children):
current_size = 0
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;'):
tables = el.findChildren('table', recursive=True)
current_size = max(
map(lambda t: len(
t.findChildren('tr', recursive=True)
), tables)
) * 42
# Table height
elif el.name == 'table':
if el['class'] == 'module-summary':
current_size = 85 + module_summary_padding
else:
current_size = len(el.findChildren('tr', recursive=True)) * 42
# Other elements height
else:
current_size = 50
# Moving tables to the next page.
# Completely transfer tables that are within the maximum
# allowable size, while splitting those that exceed the page size.
if (content_size + current_size) >= content_max_size:
str_el = ''
if current_size > (content_max_size - 85 - module_summary_padding):
rows = el.findChildren('tr', recursive=True)
table_header = str(rows.pop(0))
table_1 = table_2 = f'''
<table class="module-data" style="width:100%">
<thead>{table_header}</thead><tbody>'''
rows_count = (content_max_size - 85 - module_summary_padding) // 42
table_1 += ''.join(map(str, rows[:rows_count-1]))
table_1 += '</tbody></table>'
table_2 += ''.join(map(str, rows[rows_count-1:]))
table_2 += '</tbody></table>'
page_content += table_1
reports.append(page_content)
page_content = table_2
current_size = len(rows[rows_count:]) * 42
else:
if el.name == 'table':
el_header = children[index-1]
if el_header.name.startswith('h'):
page_content = ''.join(page_content.rsplit(str(el_header), 1))
str_el = str(el_header) + str(el)
content_size = current_size + 50
else:
str_el = str(el)
content_size = current_size
reports.append(page_content)
page_content = str_el
else:
page_content += str(el)
content_size += current_size
reports.append(page_content)
return reports
4 changes: 2 additions & 2 deletions framework/python/src/common/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
LOGGER = logger.get_logger('util')


def run_command(cmd, output=True, timeout=None):
def run_command(cmd, output=True, timeout=None, supress_error=False):
"""Runs a process at the os level
By default, returns the standard output and error output
If the caller sets optional output parameter to False,
Expand All @@ -38,7 +38,7 @@ def run_command(cmd, output=True, timeout=None):
stderr=subprocess.PIPE) as process:
stdout, stderr = process.communicate(timeout)

if process.returncode != 0 and output:
if process.returncode != 0 and output and not supress_error:
err_msg = f'{stderr.strip()}. Code: {process.returncode}'
LOGGER.error('Command failed: ' + cmd)
LOGGER.error('Error: ' + err_msg)
Expand Down
2 changes: 1 addition & 1 deletion framework/python/src/net_orc/ip_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def configure_container_interface(self,
def ping_via_gateway(self, host):
"""Ping the host trough the gateway container"""
command = f'timeout 3 docker exec tr-ct-gateway ping -W 1 -c 1 {host}'
output = util.run_command(command)
output = util.run_command(command, supress_error=True)
if '0% packet loss' in output[0]:
return True
return False
Expand Down
1 change: 1 addition & 0 deletions framework/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ APScheduler==3.10.4

# Requirements for reports generation
Jinja2==3.1.4
beautifulsoup4==4.12.3
2 changes: 1 addition & 1 deletion modules/test/ntp/python/src/ntp_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def generate_module_report(self):

if total_requests + total_responses > 0:
table_content = '''
<table class="module-data">
<table class="module-data" style="width:100%;">
<thead>
<tr>
<th>Source</th>
Expand Down
2 changes: 1 addition & 1 deletion modules/test/tls/conf/module_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"docker": {
"depends_on": "base",
"enable_container": true,
"timeout": 300
"timeout": 420
},
"tests":[
{
Expand Down
2 changes: 1 addition & 1 deletion modules/test/tls/python/src/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __init__(self, module):

self._test_module = TLSModule(module)
self._test_module.run_tests()
#self._test_module.generate_module_report()
self._test_module.generate_module_report()

def _handler(self, signum):
LOGGER.debug('SigtermEnum: ' + str(signal.SIGTERM))
Expand Down
Loading