Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
6e96845
WIP: Renaming to pilot recommendation
jboddey Dec 23, 2024
ff8c5b4
Merge branch 'dev' into feature/384032243-pilot-report
jboddey Jan 2, 2025
0d4ca59
Fix color formatting on proceed result
jboddey Jan 2, 2025
095dbbf
Merge branch 'dev' into feature/384032243-pilot-report
jboddey Jan 5, 2025
bdfb591
Merge branch 'dev' into feature/384032243-pilot-report
jboddey Jan 8, 2025
f9bf09f
replace steps to resolve
hitnik Jan 16, 2025
30ca0d0
split optional recomendations to pages
hitnik Jan 16, 2025
21d4bfb
pages num
hitnik Jan 16, 2025
da0155a
required result table column
hitnik Jan 17, 2025
cf2023e
Fix pylint issues
jboddey Jan 17, 2025
b7cf45d
fix failing tests
Jan 20, 2025
2057010
required result field for device report
hitnik Jan 20, 2025
c05a262
split steps to resolve to pages
hitnik Jan 20, 2025
a79887a
fix pylint
hitnik Jan 20, 2025
d59f69e
Adds icon for Required result; adds background for Non-Compliant and …
sofyakurilova Jan 21, 2025
060a255
fix pages num
hitnik Jan 21, 2025
832004e
Remove extra div
sofyakurilova Jan 21, 2025
1d28766
Adds width for Required result
sofyakurilova Jan 21, 2025
5cc448f
Change display grid
sofyakurilova Jan 21, 2025
790c5bd
Change max width for Required result column
sofyakurilova Jan 21, 2025
4430793
Change style for icon
sofyakurilova Jan 21, 2025
4edbcf5
change required result view
OlgaMardvilko Jan 22, 2025
f8556e9
change distance for required result
OlgaMardvilko Jan 22, 2025
e63eaa4
fix device qualification required result column title
hitnik Jan 22, 2025
164830d
fix distance for required result
OlgaMardvilko Jan 22, 2025
f7b1175
change padding for required result
OlgaMardvilko Jan 22, 2025
f4eeb8b
Merge branch 'dev' into feature/384032243-pilot-report
jboddey Jan 23, 2025
7d64a43
fix device edit after pilot testrun
hitnik Jan 24, 2025
6474ece
Generate pilot reports in unit testing (#1076)
jboddey Jan 27, 2025
43f7109
Report proceed status
jboddey Jan 27, 2025
f235c0b
Update message
jboddey Jan 27, 2025
4d1c656
392112885: (feat) [2.1.1 release] rename results modals for Pilot (#1…
OlgaMardvilko Jan 28, 2025
5e9e56b
Adds column order in testing table; adds missing icons for statuses
sofyakurilova Jan 28, 2025
03c9f14
Update result and status
jboddey Jan 30, 2025
eca0f67
Add result field
jboddey Jan 30, 2025
e490cb2
Add new pilot support logic
jboddey Jan 31, 2025
5ee690c
Merge branch 'dev' into feature/384032243-pilot-report
hitnik Feb 3, 2025
c0e9e49
remove unused import
hitnik Feb 3, 2025
66391ae
Adds pilot recommendation to status card
sofyakurilova Feb 4, 2025
3936ada
Fix ESLint issues
sofyakurilova Feb 4, 2025
cda18e6
Fix ESLint issue
sofyakurilova Feb 4, 2025
4c9e29d
392561371: (fix) changes for pilot statuses on the report page (#1084)
OlgaMardvilko Feb 5, 2025
4742d8b
fix testrun status in api
Feb 5, 2025
7c272b8
fix unittest
Feb 5, 2025
36a63d1
Merge branch 'dev' into feature/384032243-pilot-report
jboddey Feb 7, 2025
27b9d31
fix template error
hitnik Feb 7, 2025
162b599
Fix text in test run status card
sofyakurilova Feb 7, 2025
4c07048
Show pilot recommendations only for Proceed and Do not proceed statuses
sofyakurilova Feb 10, 2025
f9ce770
Set status and result at the end
jboddey Feb 10, 2025
dcd2e95
Merge remote-tracking branch 'refs/remotes/origin/feature/384032243-p…
jboddey Feb 10, 2025
bb8ed50
Set status last
jboddey Feb 10, 2025
c5d97ca
Split pilot and qualification report templates (#1105)
hitnik Feb 10, 2025
2668529
fix tls unit test
Feb 10, 2025
ae034d2
tls module unit tests
hitnik Feb 10, 2025
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
20 changes: 12 additions & 8 deletions framework/python/src/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,9 @@ def shutdown(self, response: Response):
# Check that Testrun is not currently running
if (self._session.get_status()
not in [TestrunStatus.CANCELLED,
TestrunStatus.COMPLIANT,
TestrunStatus.NON_COMPLIANT,
TestrunStatus.PROCEED,
TestrunStatus.DO_NOT_PROCEED,
TestrunStatus.COMPLETE,
TestrunStatus.IDLE
]):
LOGGER.debug("Unable to shutdown Testrun as Testrun is in progress")
Expand Down Expand Up @@ -527,12 +528,14 @@ async def delete_device(self, request: Request, response: Response):
if (self._session.get_target_device() == device
and self._session.get_status()
not in [TestrunStatus.CANCELLED,
TestrunStatus.COMPLIANT,
TestrunStatus.NON_COMPLIANT
TestrunStatus.COMPLETE,
TestrunStatus.PROCEED,
TestrunStatus.DO_NOT_PROCEED
]):

response.status_code = 403
return self._generate_msg(
False, "Cannot delete this device whilst " + "it is being tested")
False, "Cannot delete this device whilst it is being tested")

# Delete device
self._testrun.delete_device(device)
Expand All @@ -546,7 +549,7 @@ async def delete_device(self, request: Request, response: Response):
LOGGER.error(e)
response.status_code = 500
return self._generate_msg(
False, "An error occured whilst deleting " + "the device")
False, "An error occured whilst deleting the device")

async def save_device(self, request: Request, response: Response):
LOGGER.debug("Received device post request")
Expand Down Expand Up @@ -650,8 +653,9 @@ async def edit_device(self, request: Request, response: Response):
if (self._session.get_target_device() == device
and self._session.get_status()
not in [TestrunStatus.CANCELLED,
TestrunStatus.COMPLIANT,
TestrunStatus.NON_COMPLIANT
TestrunStatus.COMPLETE,
TestrunStatus.PROCEED,
TestrunStatus.DO_NOT_PROCEED
]):
response.status_code = 403
return self._generate_msg(
Expand Down
13 changes: 9 additions & 4 deletions framework/python/src/common/statuses.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,26 @@


class TestrunStatus:
"""Enum for all possible Testrun statuses"""
"""Statuses for overall testing"""
IDLE = "Idle"
STARTING = "Starting"
WAITING_FOR_DEVICE = "Waiting for Device"
MONITORING = "Monitoring"
IN_PROGRESS = "In Progress"
CANCELLED = "Cancelled"
COMPLIANT = "Compliant"
NON_COMPLIANT = "Non-Compliant"
STOPPING = "Stopping"
VALIDATING = "Validating Network"
COMPLETE = "Complete"
PROCEED = "Proceed"
DO_NOT_PROCEED = "Do Not Proceed"

class TestrunResult:
"""Statuses for the Testrun result"""
COMPLIANT = "Compliant"
NON_COMPLIANT = "Non-Compliant"

class TestResult:
"""Enum for all possible test results"""
"""Statuses for test results"""
IN_PROGRESS = "In Progress"
COMPLIANT = "Compliant"
NON_COMPLIANT = "Non-Compliant"
Expand Down
81 changes: 39 additions & 42 deletions framework/python/src/common/testreport.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
from weasyprint import HTML
from io import BytesIO
from common import util, logger
from common.statuses import TestrunStatus
from common.statuses import TestrunStatus, TestrunResult
from test_orc import test_pack
import base64
import os
from test_orc.test_case import TestCase
Expand All @@ -31,7 +32,10 @@
TESTS_FIRST_PAGE = 11
TESTS_PER_PAGE = 20
TEST_REPORT_STYLES = 'test_report_styles.css'
TEST_REPORT_TEMPLATE = 'test_report_template.html'
TEMPLATES_FOLDER = 'report_templates'
TEST_REPORT_TEMPLATE = 'report_template.html'
ICON = 'icon.png'


LOGGER = logger.get_logger('REPORT')

Expand All @@ -54,13 +58,14 @@ class TestReport():
"""Represents a previous Testrun report."""

def __init__(self,
status=TestrunStatus.NON_COMPLIANT,
result=TestrunResult.NON_COMPLIANT,
started=None,
finished=None,
total_tests=0):
self._device = {}
self._mac_addr = None
self._status: str = status
self._status: TestrunStatus = TestrunStatus.COMPLETE
self._result: TestrunResult = result
self._started = started
self._finished = finished
self._total_tests = total_tests
Expand All @@ -82,6 +87,9 @@ def add_module_templates(self, module_templates):
def get_status(self):
return self._status

def get_result(self):
return self._result

def get_started(self):
return self._started

Expand Down Expand Up @@ -117,6 +125,7 @@ def to_json(self):
report_json['mac_addr'] = self._mac_addr
report_json['device'] = self._device
report_json['status'] = self._status
report_json['result'] = self._result
report_json['started'] = self._started.strftime(DATE_TIME_FORMAT)
report_json['finished'] = self._finished.strftime(DATE_TIME_FORMAT)

Expand Down Expand Up @@ -170,6 +179,10 @@ def from_json(self, json_file):
self._device['device_profile'] = json_file['device']['additional_info']

self._status = json_file['status']

if 'result' in json_file:
self._result = json_file['result']

self._started = datetime.strptime(json_file['started'], DATE_TIME_FORMAT)
self._finished = datetime.strptime(json_file['finished'], DATE_TIME_FORMAT)

Expand Down Expand Up @@ -209,13 +222,22 @@ def to_pdf(self):

def to_html(self):

# Obtain test pack
current_test_pack = test_pack.TestPack.get_test_pack(
self._device['test_pack'])
template_folder = os.path.join(current_test_pack.path,
TEMPLATES_FOLDER)
# Jinja template
template_env = Environment(
loader=FileSystemLoader(report_resource_dir),
loader=FileSystemLoader(
template_folder
),
trim_blocks=True,
lstrip_blocks=True
)
template = template_env.get_template(TEST_REPORT_TEMPLATE)

# Report styles
with open(os.path.join(report_resource_dir,
TEST_REPORT_STYLES),
'r',
Expand All @@ -227,13 +249,11 @@ def to_html(self):
with open(test_run_img_file, 'rb') as f:
logo = base64.b64encode(f.read()).decode('utf-8')

json_data=self.to_json()
# Icon
with open(os.path.join(template_folder, ICON), 'rb') as f:
icon = base64.b64encode(f.read()).decode('utf-8')

# Icons
with open(qualification_icon, 'rb') as f:
icon_qualification = base64.b64encode(f.read()).decode('utf-8')
with open(pilot_icon, 'rb') as f:
icon_pilot = base64.b64encode(f.read()).decode('utf-8')
json_data=self.to_json()

# Convert the timestamp strings to datetime objects
start_time = datetime.strptime(json_data['started'], '%Y-%m-%d %H:%M:%S')
Expand All @@ -249,29 +269,27 @@ def to_html(self):
successful_tests += 1

# Obtain the steps to resolve
steps_to_resolve = self._get_steps_to_resolve(json_data)
logic = current_test_pack.get_logic()
steps_to_resolve_ = logic.get_steps_to_resolve(json_data)

# Obtain optional recommendations
optional_steps_to_resolve = self._get_optional_steps_to_resolve(json_data)
LOGGER.debug(steps_to_resolve_)

module_reports = self._module_reports
env_module = Environment(loader=BaseLoader())
pages_num = self._pages_num(json_data)
module_templates = [
env_module.from_string(s).render(
json_data=json_data,
name=current_test_pack.name,
device=json_data['device'],
logo=logo,
icon_qualification=icon_qualification,
icon_pilot=icon_pilot,
icon=icon,
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,
icon=icon,
version=self._version,
json_data=json_data,
device=json_data['device'],
Expand All @@ -281,8 +299,7 @@ def to_html(self):
successful_tests=successful_tests,
total_tests=self._total_tests,
test_results=json_data['tests']['results'],
steps_to_resolve=steps_to_resolve,
optional_steps_to_resolve=optional_steps_to_resolve,
steps_to_resolve=steps_to_resolve_,
module_reports=module_reports,
pages_num=pages_num,
tests_first_page=TESTS_FIRST_PAGE,
Expand All @@ -297,7 +314,7 @@ def _add_page_counter(self, html):
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()
return str(soup)

def _pages_num(self, json_data):

Expand Down Expand Up @@ -337,23 +354,3 @@ def _device_modules(self, device):
reverse=True)
)
return sorted_modules

def _get_steps_to_resolve(self, json_data):
tests_with_recommendations = []

# Collect all tests with recommendations
for test in json_data['tests']['results']:
if 'recommendations' in test:
tests_with_recommendations.append(test)

return tests_with_recommendations

def _get_optional_steps_to_resolve(self, json_data):
tests_with_recommendations = []

# Collect all tests with recommendations
for test in json_data['tests']['results']:
if 'optional_recommendations' in test:
tests_with_recommendations.append(test)

return tests_with_recommendations
18 changes: 15 additions & 3 deletions framework/python/src/core/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from fastapi.encoders import jsonable_encoder
from common import util, logger, mqtt
from common.risk_profile import RiskProfile
from common.statuses import TestrunStatus, TestResult
from common.statuses import TestrunStatus, TestResult, TestrunResult
from net_orc.ip_control import IPControl

# Certificate dependencies
Expand Down Expand Up @@ -85,6 +85,7 @@ def __init__(self, root_dir):
self._root_dir = root_dir

self._status = TestrunStatus.IDLE
self._result = None
self._description = None

# Target test device
Expand Down Expand Up @@ -133,6 +134,7 @@ def __init__(self, root_dir):

# System network interfaces
self._ifaces = {}

# Loading methods
self._load_version()
self._load_config()
Expand Down Expand Up @@ -386,12 +388,18 @@ def get_ipv4_subnet(self):
def get_ipv6_subnet(self):
return self._ipv6_subnet

def get_status(self):
def get_status(self) -> TestrunStatus:
return self._status

def set_status(self, status):
def set_status(self, status: TestrunStatus):
self._status = status

def get_result(self) -> TestrunResult:
return self._result

def set_result(self, result: TestrunResult):
self._result = result

def set_description(self, desc: str):
self._description = desc

Expand Down Expand Up @@ -807,6 +815,7 @@ def delete_profile(self, profile):

def reset(self):
self.set_status(TestrunStatus.IDLE)
self.set_result(None)
self.set_description(None)
self.set_target_device(None)
self._report_url = None
Expand Down Expand Up @@ -838,6 +847,9 @@ def to_json(self):
'tests': results
}

if self.get_result() is not None:
session_json['result'] = self.get_result()

if self._report_url is not None:
session_json['report'] = self.get_report_url()

Expand Down
5 changes: 1 addition & 4 deletions framework/python/src/core/testrun.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,10 +488,7 @@ def _device_stable(self, mac_addr):

LOGGER.info(f'Device with mac address {mac_addr} is ready for testing.')
self._set_status(TestrunStatus.IN_PROGRESS)
result = self._test_orc.run_test_modules()

if result is not None:
self._set_status(result)
self._test_orc.run_test_modules()

self._stop_network()

Expand Down
Loading
Loading