-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ppk test and update badge accordingly. Signed-off-by: Giacomo Dematteis <[email protected]>
- Loading branch information
1 parent
4220a68
commit 323d0bd
Showing
6 changed files
with
255 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,14 +59,22 @@ on: | |
type: boolean | ||
required: true | ||
default: false | ||
run_wifi_location_tests: | ||
type: boolean | ||
required: true | ||
default: false | ||
run_ppk_tests: | ||
type: boolean | ||
required: true | ||
default: false | ||
|
||
jobs: | ||
target_test: | ||
name: Target Test | ||
runs-on: self-hosted | ||
environment: production | ||
container: | ||
image: ghcr.io/hello-nrfcloud/firmware:docker-v1.0.0 | ||
image: ghcr.io/hello-nrfcloud/firmware:docker-v1.0.2 | ||
options: --privileged | ||
volumes: | ||
- /dev:/dev:rw | ||
|
@@ -183,6 +191,7 @@ jobs: | |
LOG_FILENAME: oob_conn_bridge_test_log | ||
|
||
- name: Run Wi-Fi location tests | ||
if: ${{ inputs.run_wifi_location_tests }} | ||
working-directory: thingy91x-oob/tests/on_target | ||
run: | | ||
mkdir -p results | ||
|
@@ -192,6 +201,61 @@ jobs: | |
env: | ||
SEGGER: ${{ secrets.SEGGER_DUT_1 }} | ||
|
||
# - name: Run PPK tests | ||
# if: ${{ inputs.run_ppk_tests }} | ||
# id: ppk_test | ||
# working-directory: thingy91x-oob/tests/on_target | ||
# run: | | ||
# # mkdir -p results | ||
# # # pytest -s -v -m dut_ppk \ | ||
# # # --junit-xml=results/test-results-ppk.xml \ | ||
# # # tests | ||
# # # current_value=$(cat current_value.txt) | ||
# current_value=4 | ||
# if (( $(echo "$current_value < 10" | bc -l) )); then | ||
# echo "Current is below threshold." | ||
# color="00FF00" # Green | ||
# else | ||
# echo "Current is above threshold." | ||
# color="FF0000" # Red | ||
# fi | ||
# echo "current_value=$current_value" >> $GITHUB_ENV | ||
# echo "color=$color" >> $GITHUB_ENV | ||
# env: | ||
# SEGGER: ${{ secrets.SEGGER_DUT_PPK }} | ||
|
||
- name: Run PPK tests | ||
if: ${{ inputs.run_ppk_tests }} | ||
id: ppk_test | ||
working-directory: thingy91x-oob/tests/on_target | ||
run: | | ||
mkdir -p results | ||
current_value=4 | ||
if (( $(echo "$current_value < 10" | bc -l) )); then | ||
echo "Current is below threshold." | ||
color="00FF00" # Green | ||
else | ||
echo "Current is above threshold." | ||
color="FF0000" # Red | ||
fi | ||
echo "current_value=$current_value" >> $GITHUB_ENV | ||
echo "color=$color" >> $GITHUB_ENV | ||
env: | ||
SEGGER: ${{ secrets.SEGGER_DUT_PPK }} | ||
|
||
- name: Build power badge | ||
if: ${{ steps.ppk_test.outcome == 'success' }} | ||
env: | ||
current_value: ${{ env.current_value }} | ||
color: ${{ env.color }} | ||
uses: peterrhodesdev/[email protected] | ||
with: | ||
token: ${{ secrets.GITHUB_TOKEN }} | ||
filename: power_badge | ||
label: psm_current uA | ||
message: ${{ env.current_value }} | ||
color: ${{ env.color }} | ||
|
||
- name: Results | ||
if: always() | ||
uses: pmeier/[email protected] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,4 @@ pyusb | |
imgtool | ||
requests | ||
memfault-cli | ||
ppk2-api |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
########################################################################################## | ||
# Copyright (c) 2024 Nordic Semiconductor | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
########################################################################################## | ||
|
||
import pytest | ||
import time | ||
import os | ||
import json | ||
import types | ||
from tests.conftest import get_uarts | ||
from ppk2_api.ppk2_api import PPK2_API | ||
from utils.uart import Uart | ||
from utils.flash_tools import flash_device, reset_device, recover_device | ||
import sys | ||
sys.path.append(os.getcwd()) | ||
from utils.logger import get_logger | ||
|
||
logger = get_logger() | ||
|
||
UART_TIMEOUT = 60 * 30 | ||
POWER_TIMEOUT = 60 * 5 | ||
MAX_CURRENT_PSM_UA = 10 | ||
|
||
SEGGER = os.getenv('SEGGER') | ||
UART_ID = os.getenv('UART_ID', SEGGER) | ||
|
||
def get_uarts(): | ||
base_path = "/dev/serial/by-id" | ||
try: | ||
serial_paths = [os.path.join(base_path, entry) for entry in os.listdir(base_path)] | ||
except (FileNotFoundError, PermissionError) as e: | ||
logger.error(e) | ||
return False | ||
|
||
uarts = [] | ||
|
||
for path in sorted(serial_paths): | ||
logger.warning(path) | ||
logger.warning(UART_ID) | ||
if UART_ID in path: | ||
uarts.append(path) | ||
else: | ||
continue | ||
return uarts | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def ppk2(): | ||
''' | ||
This fixture sets up ppk measurement tool. | ||
''' | ||
ppk2s_connected = PPK2_API.list_devices() | ||
ppk2s_connected.sort() | ||
if len(ppk2s_connected) == 2: | ||
ppk2_port = ppk2s_connected[0] | ||
print(f"Found PPK2 at {ppk2_port}") | ||
elif len(ppk2s_connected) == 0: | ||
pytest.fail("No ppk found") | ||
else: | ||
pytest.fail(f"Multiple PPks found") | ||
|
||
ppk2_test = PPK2_API(ppk2_port, timeout=1, write_timeout=1, exclusive=True) | ||
|
||
# get modifier might fail, retry 15 times | ||
for _ in range(15): | ||
try: | ||
ppk2_test.get_modifiers() | ||
break | ||
except Exception as e: | ||
logger.error(f"Failed to get modifiers: {e}") | ||
time.sleep(5) | ||
else: | ||
pytest.fail("Failed to get ppk modifiers after 10 attempts") | ||
|
||
|
||
ppk2_test.set_source_voltage(3300) | ||
|
||
ppk2_test.use_ampere_meter() # set ampere meter mode | ||
|
||
ppk2_test.toggle_DUT_power("ON") # enable DUT power | ||
|
||
|
||
time.sleep(10) | ||
|
||
for i in range(10): | ||
try: | ||
all_uarts = get_uarts() | ||
if not all_uarts: | ||
logger.error("No UARTs found") | ||
log_uart_string = all_uarts[0] | ||
break | ||
except Exception: | ||
ppk2_test.toggle_DUT_power("OFF") # disable DUT power | ||
time.sleep(2) | ||
ppk2_test.toggle_DUT_power("ON") # enable DUT power | ||
time.sleep(5) | ||
continue | ||
else: | ||
pytest.fail("NO uart after 10 attempts") | ||
|
||
uart = Uart(log_uart_string, timeout=UART_TIMEOUT) | ||
|
||
yield types.SimpleNamespace(ppk2_test=ppk2_test, uart=uart,) | ||
|
||
uart.stop() | ||
# recover_device() | ||
ppk2_test.stop_measuring() | ||
|
||
@pytest.mark.dut_ppk | ||
def test_power(ppk2, hex_file): | ||
# flash_device(os.path.abspath(hex_file)) | ||
reset_device() | ||
time.sleep(5) | ||
ppk2.uart.xfactoryreset() | ||
patterns_boot = [ | ||
"Network connectivity established", | ||
"Connected to Cloud", | ||
"trigger: frequent_poll_entry: frequent_poll_entry", | ||
"trigger: trigger_work_fn: Sending data sample trigger", | ||
"environmental_module: sample: temp:", | ||
"transport: state_connected_ready_run: Payload", | ||
"Location search done" | ||
] | ||
|
||
ppk2.ppk2_test.start_measuring() | ||
|
||
# Boot | ||
ppk2.uart.flush() | ||
reset_device() | ||
# ppk2.uart.wait_for_str(patterns_boot, timeout=120) | ||
|
||
# ppk2.uart.wait_for_str("Disabling UARTs", timeout=120) | ||
|
||
start = time.time() | ||
min_average = float('inf') | ||
average = None | ||
sampling_interval = 0.01 | ||
averages = [] | ||
average_of_averages = 0 | ||
last_log_time = start | ||
while time.time() < start + POWER_TIMEOUT: | ||
try: | ||
read_data = ppk2.ppk2_test.get_data() | ||
if read_data != b'': | ||
samples, _ = ppk2.ppk2_test.get_samples(read_data) | ||
average = sum(samples)/len(samples) | ||
|
||
# Store the average for rolling calculation | ||
averages.append(average) | ||
# Keep only the averages from the last 3 seconds | ||
if len(averages) > int(3 / sampling_interval): | ||
averages.pop(0) | ||
|
||
# Calculate the average of averages | ||
average_of_averages = sum(averages) / len(averages) if averages else 0 | ||
|
||
# Log every 5 seconds | ||
current_time = time.time() | ||
if current_time - last_log_time >= 5: | ||
logger.info(f"Average of {len(samples)} samples is: {average} uA") | ||
logger.info(f"Average of averages: {average_of_averages} uA") | ||
last_log_time = current_time # Update the last log time | ||
|
||
if average_of_averages < min_average: | ||
min_average = average_of_averages | ||
|
||
except Exception as e: | ||
logger.error(f"Catching exception: {e}") | ||
pytest.skip("Something went wrong, unable to perform power measurements") | ||
|
||
if average_of_averages < MAX_CURRENT_PSM_UA: | ||
logger.info("psm target reached for more than 3 secs") | ||
break | ||
time.sleep(sampling_interval) # lower time between sampling -> less samples read in one sampling period | ||
else: | ||
logger.error(f"PSM target not reached after {POWER_TIMEOUT} seconds") | ||
logger.info(f"Minimum average current measured: {min_average}uA") | ||
|
||
# Save the minimum average current to a text file | ||
with open('current_value.txt', 'w') as file: | ||
file.write(str(min_average)) | ||
logger.info(f"Minimum average current saved to 'current_value.txt'") |