Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
26 changes: 13 additions & 13 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
timeout-minutes: 20
steps:
- name: Checkout source
uses: actions/checkout@v4.1.1
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Install dependencies
shell: bash {0}
run: cmd/prepare
Expand All @@ -36,7 +36,7 @@ jobs:
timeout-minutes: 45
steps:
- name: Checkout source
uses: actions/checkout@v4.1.1
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Install dependencies
shell: bash {0}
run: cmd/prepare
Expand All @@ -53,7 +53,7 @@ jobs:
if: ${{ always() }}
run: sudo tar --exclude-vcs -czf runtime.tgz /usr/local/testrun/runtime/
- name: Upload runtime results
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
if: ${{ always() }}
with:
if-no-files-found: error
Expand All @@ -67,7 +67,7 @@ jobs:
timeout-minutes: 40
steps:
- name: Checkout source
uses: actions/checkout@v4.1.1
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Install dependencies
shell: bash {0}
run: cmd/prepare
Expand All @@ -85,7 +85,7 @@ jobs:
if: ${{ always() }}
run: sudo tar --exclude-vcs -czf runtime.tgz /usr/local/testrun/runtime/ /usr/local/testrun/local/
- name: Upload runtime results
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
if: ${{ always() }}
with:
if-no-files-found: error
Expand All @@ -99,7 +99,7 @@ jobs:
timeout-minutes: 5
steps:
- name: Checkout source
uses: actions/checkout@v4.1.1
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Run pylint
shell: bash {0}
run: testing/pylint/test_pylint
Expand All @@ -111,12 +111,12 @@ jobs:
timeout-minutes: 5
steps:
- name: Checkout source
uses: actions/checkout@v4.1.1
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Package Testrun
shell: bash {0}
run: cmd/package
- name: Archive package
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
with:
name: testrun_installer
path: testrun*.deb
Expand All @@ -126,9 +126,9 @@ jobs:
name: UI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Install Node
uses: actions/setup-node@v4
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
with:
node-version: 18.13.0
- name: Install Chromium Browser
Expand All @@ -149,9 +149,9 @@ jobs:
name: ESLint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Install Node
uses: actions/setup-node@v4
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
with:
node-version: 18.13.0
- name: Install dependencies
Expand All @@ -162,4 +162,4 @@ jobs:
working-directory: ./modules/ui
- name: Run format check
run: npm run format
working-directory: ./modules/ui
working-directory: ./modules/ui
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ error
pylint.out
__pycache__/
build/

# Ignore generated files from unit tests
testing/unit_test/temp/
testing/unit/dns/output/
testing/unit/nmap/output/
testing/unit/ntp/output/
Expand Down
5 changes: 2 additions & 3 deletions framework/python/src/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Provides Testrun data via REST API."""

from fastapi import FastAPI, APIRouter, Response, Request, status
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware
Expand Down Expand Up @@ -187,7 +186,8 @@ async def start_test_run(self, request: Request, response: Response):
]:
LOGGER.debug("Testrun is already running. Cannot start another instance")
response.status_code = status.HTTP_409_CONFLICT
return self._generate_msg(False, "Testrun is already running")
return self._generate_msg(False, "Testrun cannot be started " +
"whilst a test is running on another device")

# Check if requested device is known in the device repository
if device is None:
Expand Down Expand Up @@ -386,7 +386,6 @@ async def delete_device(self, request: Request, response: Response):
"the device")

async def save_device(self, request: Request, response: Response):

LOGGER.debug("Received device post request")

try:
Expand Down
8 changes: 8 additions & 0 deletions framework/python/src/common/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
MONITOR_PERIOD_KEY = 'monitor_period'
STARTUP_TIMEOUT_KEY = 'startup_timeout'
LOG_LEVEL_KEY = 'log_level'
API_URL_KEY = 'api_url'
API_PORT_KEY = 'api_port'
MAX_DEVICE_REPORTS_KEY = 'max_device_reports'

Expand Down Expand Up @@ -81,6 +82,7 @@ def _get_default_config(self):
'startup_timeout': 60,
'monitor_period': 30,
'max_device_reports': 5,
'api_url': 'http://localhost',
'api_port': 8000
}

Expand Down Expand Up @@ -118,6 +120,9 @@ def _load_config(self):
if LOG_LEVEL_KEY in config_file_json:
self._config[LOG_LEVEL_KEY] = config_file_json.get(LOG_LEVEL_KEY)

if API_URL_KEY in config_file_json:
self._config[API_URL_KEY] = config_file_json.get(API_URL_KEY)

if API_PORT_KEY in config_file_json:
self._config[API_PORT_KEY] = config_file_json.get(API_PORT_KEY)

Expand Down Expand Up @@ -165,6 +170,9 @@ def get_monitor_period(self):
def get_startup_timeout(self):
return self._config.get(STARTUP_TIMEOUT_KEY)

def get_api_url(self):
return self._config.get(API_URL_KEY)

def get_api_port(self):
return self._config.get(API_PORT_KEY)

Expand Down
57 changes: 48 additions & 9 deletions framework/python/src/common/testreport.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ def generate_results(self, json_data, page_num):
result_list = '''
<img style="margin-bottom:10px;width:100%;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABFgAAAABCAYAAADqzRqJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA3SURBVHgB7cAxAQAQFEXRJ4MIMkjwS9hklMCoi1EBWljePWlHvQIAMy2mAMDNKV3ADysPAYCbB6fxBrzkZ2KOAAAAAElFTkSuQmCC" />
<div class="result-list">
<span class="result-list-title">Results List</span>
<h3>Results List</h3>
<div class="result-line" style="margin-top: 10px;border-top-left-radius:4px;border-top-right-radius:4px;">
<div class="result-list-header-label" style="left: .1in">Name</div>
<div class="result-list-header-label" style="left: 2.8in">Description</div>
Expand Down Expand Up @@ -374,8 +374,8 @@ def generate_header(self, json_data):
tr_img_b64 = base64.b64encode(f.read()).decode('utf-8')
return f'''
<div class="header">
<h3 class="header-text">Testrun report</h3>
<h1 class="header-title" style="top: 50%;">{json_data["device"]["manufacturer"]} {json_data["device"]["model"]}</h1>
<h1>Testrun report</h1>
<h2 style="top: 50%;">{json_data["device"]["manufacturer"]} {json_data["device"]["model"]}</h2>
<img src="data:image/png;base64,{tr_img_b64}" alt="Test Run" width="90" style="position: absolute;top: 40%; right: 0px;"></img>
</div>
'''
Expand Down Expand Up @@ -431,6 +431,36 @@ def generate_summary(self, json_data):

summary += '</div>'

# Add device configuration
summary += '''
<div class="summary-device-modules">
<div class="summary-item-label" style="margin-bottom:10px;">
<h4>Device Configuration</h4>
</div>
'''

if 'test_modules' in json_data['device']:

sorted_modules = {}

for test_module in json_data['device']['test_modules']:
if 'enabled' in json_data['device']['test_modules'][test_module]:
sorted_modules[test_module] = json_data['device']['test_modules'][
test_module]['enabled']

# Sort the modules by enabled first
sorted_modules = sorted(sorted_modules.items(),
key=lambda x:x[1],
reverse=True)

for module in sorted_modules:
summary += self.generate_device_module_label(
module[0],
module[1]
)

summary += '</div>'

# Add the result summary
summary += self.generate_result_summary(json_data)

Expand Down Expand Up @@ -485,7 +515,7 @@ def generate_result_summary_item(self, key, value, style=None):

def generate_device_summary_label(self, key, value, trailing_space=True):
label = f'''
<div class="summary-item-label">{key}</div>
<div class="summary-item-label"><h4>{key}</h4></div>
<div class="summary-item-value">{value}</div>
'''
if trailing_space:
Expand Down Expand Up @@ -563,18 +593,30 @@ def generate_css(self):
position: relative;
}

.header-text {
h1 {
margin: 0 0 8px 0;
font-size: 20px;
font-weight: 400;
}

.header-title {
h2 {
margin: 0px;
font-size: 48px;
font-weight: 700;
}

h3 {
font-size: 24px;
}

h4 {
font-size: 12px;
font-weight: 500;
color: #5F6368;
margin-bottom: 0;
margin-top: 0;
}

/* Define the summary related css elements*/
.summary-content {
position: relative;
Expand All @@ -586,9 +628,6 @@ def generate_css(self):

.summary-item-label {
position: relative;
font-size: 12px;
font-weight: 500;
color: #5F6368;
}

.summary-item-value {
Expand Down
Loading