Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
83 changes: 26 additions & 57 deletions framework/python/src/common/testreport.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from io import BytesIO
from common import util, logger
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 Down Expand Up @@ -218,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 @@ -236,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 @@ -258,30 +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)
is_pilot = json_data['device']['test_pack'] == 'Pilot Assessment'
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 @@ -291,13 +299,11 @@ 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,
tests_per_page=TESTS_PER_PAGE,
is_pilot = is_pilot,
module_templates=module_templates
))

Expand Down Expand Up @@ -348,40 +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 self._split_steps_to_resolve_to_pages(
tests_with_recommendations, 4, 4)

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 self._split_steps_to_resolve_to_pages(
tests_with_recommendations, 3, 4)

def _split_steps_to_resolve_to_pages(self, steps, start_page=4, page=4):
# Split steps to resolve to pages.
# First <start_page> steps, <page> steps on other pages.
if len(steps) < start_page:
return [steps]

splitted = [steps[:3]]

index = start_page
while index < len(steps):
splitted.append(steps[index:index + page])
index += page

return splitted
48 changes: 2 additions & 46 deletions framework/python/src/test_orc/test_orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
import re
import time
import shutil
import sys
import docker
import importlib.util
from datetime import datetime
from common import logger, util
from common.testreport import TestReport
Expand Down Expand Up @@ -665,46 +663,7 @@ def _get_module_container(self, module):

def _load_test_packs(self):

for test_pack_folder in os.listdir(TEST_PACKS_DIR):

LOGGER.debug(f"Loading test pack {test_pack_folder}")

test_pack_path = os.path.join(
self._root_path,
TEST_PACKS_DIR,
test_pack_folder
)

with open(os.path.join(
test_pack_path,
TEST_PACK_CONFIG_FILE), encoding="utf-8") as f:
test_pack_json = json.load(f)

test_pack: TestPack = TestPack(
name = test_pack_json["name"],
tests = test_pack_json["tests"],
language = test_pack_json["language"],
pack_logic = self._load_logic(
os.path.join(test_pack_path, TEST_PACK_LOGIC_FILE),
"test_pack_" + test_pack_folder + "_logic"
)
)

self._test_packs.append(test_pack)

def _load_logic(self, source, module_name=None):
"""Reads file source and loads it as a module"""

spec = importlib.util.spec_from_file_location(module_name, source)
module = importlib.util.module_from_spec(spec)

# Add the module to sys.modules
sys.modules[module_name] = module

# Execute the module
spec.loader.exec_module(module)

return module
self._test_packs = TestPack.get_test_packs()

def _load_test_modules(self):
"""Load network modules from module_config.json."""
Expand Down Expand Up @@ -767,10 +726,7 @@ def get_test_packs(self) -> List[TestPack]:
return self._test_packs

def get_test_pack(self, name: str) -> TestPack:
for test_pack in self._test_packs:
if test_pack.name.lower() == name.lower():
return test_pack
return None
return TestPack.get_test_pack(name, self._test_packs)

def _stop_modules(self, kill=False):
LOGGER.info("Stopping test modules")
Expand Down
70 changes: 70 additions & 0 deletions framework/python/src/test_orc/test_pack.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@
from typing import List, Dict
from dataclasses import dataclass, field
from collections import defaultdict
import os
import sys
import json
import importlib

RESOURCES_DIR = "resources"

TEST_PACKS_DIR = os.path.join(RESOURCES_DIR, "test_packs")
TEST_PACK_CONFIG_FILE = "config.json"
TEST_PACK_LOGIC_FILE = "test_pack.py"


@dataclass
Expand All @@ -28,6 +38,7 @@ class TestPack: # pylint: disable=too-few-public-methods,too-many-instance-attr
tests: List[dict] = field(default_factory=lambda: [])
language: Dict = field(default_factory=lambda: defaultdict(dict))
pack_logic: ModuleType = None
path: str = ""

def get_test(self, test_name: str) -> str:
"""Get details of a test from the test pack"""
Expand Down Expand Up @@ -61,3 +72,62 @@ def to_dict(self):
"tests": self.tests,
"language": self.language
}

@staticmethod
def load_logic(source, module_name=None):
"""Reads file source and loads it as a module"""

spec = importlib.util.spec_from_file_location(module_name, source)
module = importlib.util.module_from_spec(spec)

# Add the module to sys.modules
sys.modules[module_name] = module

# Execute the module
spec.loader.exec_module(module)

return module

@staticmethod
def get_test_packs() -> List["TestPack"]:

root_path = os.path.dirname(
os.path.dirname(
os.path.dirname(
os.path.dirname(os.path.dirname(os.path.realpath(__file__))))))
test_packs = []

for test_pack_folder in os.listdir(TEST_PACKS_DIR):
test_pack_path = os.path.join(
root_path,
TEST_PACKS_DIR,
test_pack_folder
)

with open(os.path.join(
test_pack_path,
TEST_PACK_CONFIG_FILE), encoding="utf-8") as f:
test_pack_json = json.load(f)

test_pack: TestPack = TestPack(
name = test_pack_json["name"],
tests = test_pack_json["tests"],
language = test_pack_json["language"],
pack_logic = TestPack.load_logic(
os.path.join(test_pack_path, TEST_PACK_LOGIC_FILE),
"test_pack_" + test_pack_folder + "_logic"
),
path = test_pack_path
)
test_packs.append(test_pack)

return test_packs

@staticmethod
def get_test_pack(name: str, test_packs: List["TestPack"]=None) -> "TestPack":
if test_packs is None:
test_packs = TestPack.get_test_packs()
for test_pack in test_packs:
if test_pack.name.lower() == name.lower():
return test_pack
return None
4 changes: 2 additions & 2 deletions modules/test/dns/python/src/dns_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ def __init__(self, # pylint: disable=R0917

def generate_module_report(self):
# Load Jinja2 template
page_max_height = 910
page_max_height = 850
header_height = 48
summary_height = 135
row_height = 42
row_height = 44
loader=FileSystemLoader(self._report_template_folder)
template = Environment(
loader=loader,
Expand Down
9 changes: 2 additions & 7 deletions resources/report/module_report_base.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@
<div class="header-info">
{# Badge #}
<p class="header-info-badge">
{% if json_data['device']['test_pack'] == 'Device Qualification' %}
<img src="data:image/png;base64, {{ icon_qualification }}" alt="">
<span>Device Qualification</span>
{% else %}
<img src="data:image/png;base64, {{ icon_pilot }}" alt="">
<span>Pilot Assessment</span>
{% endif %}
<img src="data:image/png;base64, {{ icon }}" alt="">
<span>{{ name }}</span>
</p>
<span style="font-weight:600">{{ title }}</span>
</div>
Expand Down
Loading
Loading