Added GNSS-Monitoring test cases
Change-Id: I0e3211b81c16b91c47e68aa5c573b7b6b3b065e4 Signed-off-by: Guntaka Umashankar Reddy <umashankarguntaka.reddy@windriver.com>
This commit is contained in:
272
keywords/cloud_platform/system/ptp/gnss_monitoring_keywords.py
Normal file
272
keywords/cloud_platform/system/ptp/gnss_monitoring_keywords.py
Normal file
@@ -0,0 +1,272 @@
|
||||
from framework.logging.automation_logger import get_logger
|
||||
from framework.validation.validation import validate_equals, validate_equals_with_retry, validate_str_contains
|
||||
from keywords.base_keyword import BaseKeyword
|
||||
from keywords.cloud_platform.command_wrappers import source_openrc
|
||||
from keywords.cloud_platform.fault_management.alarms.alarm_list_keywords import AlarmListKeywords
|
||||
from keywords.cloud_platform.fault_management.alarms.objects.alarm_list_object import AlarmListObject
|
||||
from keywords.cloud_platform.system.ptp.objects.gnss_monitoring_data_output import GnssMonitoringDataOutput
|
||||
from keywords.cloud_platform.system.ptp.system_ptp_instance_keywords import SystemPTPInstanceKeywords
|
||||
from keywords.files.file_keywords import FileKeywords
|
||||
from keywords.linux.systemctl.systemctl_status_keywords import SystemCTLStatusKeywords
|
||||
from keywords.ptp.cat.cat_ptp_config_keywords import CatPtpConfigKeywords
|
||||
from keywords.ptp.cat.gnss_monitor_conf_keywords import GnssMonitorConfKeywords
|
||||
|
||||
|
||||
class GnssMonitoringKeywords(BaseKeyword):
|
||||
"""
|
||||
Keywords for GNSS monitoring operations using existing system keywords.
|
||||
"""
|
||||
|
||||
def __init__(self, ssh_connection):
|
||||
"""
|
||||
Initialize GNSS monitoring keywords.
|
||||
|
||||
Args:
|
||||
ssh_connection (SSHConnection): SSH connection to the target host.
|
||||
"""
|
||||
self.ssh_connection = ssh_connection
|
||||
|
||||
def get_gnss_monitoring_data(self, device_path: str) -> GnssMonitoringDataOutput:
|
||||
"""
|
||||
Get GNSS monitoring data using the CLI tool.
|
||||
|
||||
Args:
|
||||
device_path (str): Path to the GNSS device (e.g., "/dev/ttyACM0").
|
||||
|
||||
Returns:
|
||||
GnssMonitoringDataOutput: Parsed monitoring data output.
|
||||
"""
|
||||
get_logger().log_info(f"Getting GNSS monitoring data for device {device_path}")
|
||||
cli_command = f"python /usr/rootdirs/opt/collectd/extensions/python/ptp_gnss_monitor_cli.py --devices {device_path}"
|
||||
output = self.ssh_connection.send_as_sudo(cli_command)
|
||||
self.validate_success_return_code(self.ssh_connection)
|
||||
return GnssMonitoringDataOutput(output)
|
||||
|
||||
def create_monitoring_instance(self, instance_name: str) -> None:
|
||||
"""
|
||||
Create a GNSS monitoring PTP instance.
|
||||
|
||||
Args:
|
||||
instance_name (str): Name of the monitoring instance.
|
||||
|
||||
Returns: None
|
||||
"""
|
||||
self.ptp_instance_keywords = SystemPTPInstanceKeywords(self.ssh_connection)
|
||||
get_logger().log_info(f"Creating GNSS monitoring instance {instance_name}")
|
||||
return self.ptp_instance_keywords.system_ptp_instance_add(instance_name, "gnss-monitor")
|
||||
|
||||
def verify_monitoring_configuration_file(self, expected_satellite_count: int, expected_signal_quality: int, expected_devices: str) -> None:
|
||||
"""
|
||||
Verify the monitoring configuration file contains expected values.
|
||||
|
||||
Args:
|
||||
expected_satellite_count (int): Expected satellite count threshold.
|
||||
expected_signal_quality (int): Expected signal quality threshold.
|
||||
expected_devices (str): Expected device paths.
|
||||
|
||||
Returns: None
|
||||
"""
|
||||
get_logger().log_info("Verifying monitoring configuration file")
|
||||
|
||||
gnss_conf_output = GnssMonitorConfKeywords((self.ssh_connection)).cat_gnss_monitor_conf("/etc/linuxptp/ptpinstance/gnss-monitor-ptp.conf")
|
||||
gnss_conf_object = gnss_conf_output.get_gnss_monitor_conf_object()
|
||||
|
||||
actual_devices = gnss_conf_object.get_devices()
|
||||
actual_satellite_count = gnss_conf_object.get_satellite_count()
|
||||
actual_signal_quality_db = gnss_conf_object.get_signal_quality_db()
|
||||
|
||||
validate_equals(actual_satellite_count, expected_satellite_count, "satellite_count not found in configuration")
|
||||
|
||||
validate_equals(actual_signal_quality_db, expected_signal_quality, "signal_quality_db not found in configuration")
|
||||
|
||||
validate_equals(actual_devices, expected_devices, "devices not found in configuration")
|
||||
|
||||
def wait_for_monitoring_configuration_file(self, expected_satellite_count: int, expected_signal_quality: int, expected_devices: str) -> None:
|
||||
"""
|
||||
Wait for monitoring configuration file to contain expected values.
|
||||
|
||||
Args:
|
||||
expected_satellite_count (int): Expected satellite count threshold.
|
||||
expected_signal_quality (int): Expected signal quality threshold.
|
||||
expected_devices (str): Expected device paths.
|
||||
|
||||
Returns: None
|
||||
|
||||
Raises:
|
||||
TimeoutError: raised when validate does not equal in the required time
|
||||
"""
|
||||
get_logger().log_info("Waiting for monitoring configuration file to match expected values")
|
||||
|
||||
def check_monitoring_config_matches() -> bool:
|
||||
"""
|
||||
Check if configuration file matches expected values.
|
||||
|
||||
Returns:
|
||||
bool: True if all values match, False otherwise.
|
||||
"""
|
||||
gnss_conf_output = GnssMonitorConfKeywords(self.ssh_connection).cat_gnss_monitor_conf("/etc/linuxptp/ptpinstance/gnss-monitor-ptp.conf")
|
||||
gnss_conf_object = gnss_conf_output.get_gnss_monitor_conf_object()
|
||||
actual_devices = gnss_conf_object.get_devices()
|
||||
actual_satellite_count = gnss_conf_object.get_satellite_count()
|
||||
actual_signal_quality_db = gnss_conf_object.get_signal_quality_db()
|
||||
return actual_satellite_count == expected_satellite_count and actual_signal_quality_db == expected_signal_quality and actual_devices == expected_devices
|
||||
|
||||
validate_equals_with_retry(check_monitoring_config_matches, True, "monitoring configuration file to match expected values", 120, 10)
|
||||
|
||||
def verify_gpsd_service_status(self, devices: list[str], expected_status: str = "active") -> None:
|
||||
"""
|
||||
Verify gpsd service status and gpspipe services for devices.
|
||||
|
||||
Args:
|
||||
devices (list[str]): List of device paths (e.g., ["/dev/ttyACM0", "/dev/gnssx"]).
|
||||
expected_status (str): Expected service status (default: "active").
|
||||
|
||||
Returns: None
|
||||
"""
|
||||
get_logger().log_info("Verifying gpsd service status")
|
||||
service_status = SystemCTLStatusKeywords(self.ssh_connection).get_status("gpsd.service")
|
||||
status_output = "\n".join(service_status) if isinstance(service_status, list) else service_status
|
||||
validate_str_contains(status_output, f"Active: {expected_status}", "gpsd service status")
|
||||
|
||||
for device in devices:
|
||||
device_name = device.replace("/dev/", "").replace("/", "-")
|
||||
gpspipe_service = f"gpspipe@-dev-{device_name}.service"
|
||||
validate_str_contains(status_output, gpspipe_service, f"gpspipe service for {device_name} should be running")
|
||||
|
||||
def verify_pty_device_exists(self, device_path: str, should_exist: bool = True) -> None:
|
||||
"""
|
||||
Verify PTY device exists or doesn't exist.
|
||||
|
||||
Args:
|
||||
device_path (str): Path to the original device (e.g., "/dev/ttyACM0").
|
||||
should_exist (bool): Whether the PTY device should exist (default: True).
|
||||
|
||||
Returns: None
|
||||
"""
|
||||
pty_path = f"{device_path}.pty"
|
||||
get_logger().log_info(f"Verifying PTY device {pty_path} existence: {should_exist}")
|
||||
|
||||
file_keywords = FileKeywords(self.ssh_connection)
|
||||
pty_exists = file_keywords.file_exists(pty_path)
|
||||
|
||||
validate_equals(pty_exists, should_exist, f"PTY device {pty_path} expected existance: {should_exist}")
|
||||
|
||||
def wait_for_monitoring_services_active(self, devices: list[str]) -> None:
|
||||
"""
|
||||
Wait for monitoring services to be active and running.
|
||||
|
||||
Args:
|
||||
devices (list[str]): List of device paths (e.g., ["/dev/ttyACM0", "/dev/gnssx"]).
|
||||
|
||||
Returns: None
|
||||
|
||||
Raises:
|
||||
TimeoutError: raised when validate does not equal in the required time
|
||||
"""
|
||||
get_logger().log_info("Waiting for monitoring services to be active")
|
||||
|
||||
def check_services_active() -> bool:
|
||||
"""
|
||||
Checks if gpsd and gpspipe services are active and running.
|
||||
|
||||
Returns:
|
||||
bool: True if all services are active and running, False otherwise.
|
||||
"""
|
||||
gpsd_status_output = SystemCTLStatusKeywords(self.ssh_connection).get_status("gpsd")
|
||||
if not any("Active: active (running)" in line for line in gpsd_status_output or []):
|
||||
return False
|
||||
|
||||
for device in devices:
|
||||
device_name = device.replace("/dev/", "").replace("/", "-")
|
||||
gpspipe_service = f"gpspipe@-dev-{device_name}.service"
|
||||
gpspipe_status_output = SystemCTLStatusKeywords(self.ssh_connection).get_status(gpspipe_service)
|
||||
if not any("Active: active (running)" in line for line in gpspipe_status_output or []):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
validate_equals_with_retry(check_services_active, True, "systemctl status for gpsd services to be active", 180, 30)
|
||||
|
||||
alarm_list_object = AlarmListObject()
|
||||
alarm_list_object.set_alarm_id("250.001")
|
||||
AlarmListKeywords(self.ssh_connection).set_timeout_in_seconds(180)
|
||||
AlarmListKeywords(self.ssh_connection).wait_for_alarms_cleared([alarm_list_object])
|
||||
|
||||
def wait_for_monitoring_services_inactive(self) -> None:
|
||||
"""
|
||||
Wait for monitoring services to be inactive.
|
||||
|
||||
Returns: None
|
||||
|
||||
Raises:
|
||||
TimeoutError: raised when validate does not equal in the required time
|
||||
"""
|
||||
get_logger().log_info("Waiting for monitoring services to be inactive")
|
||||
|
||||
def check_services_inactive() -> bool:
|
||||
"""
|
||||
Checks if gpsd service is inactive.
|
||||
|
||||
Returns:
|
||||
bool: True if gpsd service is inactive, False otherwise.
|
||||
"""
|
||||
gpsd_status_output = SystemCTLStatusKeywords(self.ssh_connection).get_status("gpsd")
|
||||
return any("Active: inactive (dead)" in line for line in gpsd_status_output or [])
|
||||
|
||||
validate_equals_with_retry(check_services_inactive, True, "systemctl status for gpsd services to be inactive", 120, 30)
|
||||
|
||||
alarm_objects = []
|
||||
for alarm_id in ["250.001", "100.119"]:
|
||||
alarm_obj = AlarmListObject()
|
||||
alarm_obj.set_alarm_id(alarm_id)
|
||||
alarm_objects.append(alarm_obj)
|
||||
AlarmListKeywords(self.ssh_connection).wait_for_alarms_cleared(alarm_objects)
|
||||
|
||||
def verify_device_exists(self, device_path: str) -> None:
|
||||
"""
|
||||
Verify that a device exists on the system.
|
||||
|
||||
Args:
|
||||
device_path (str): Path to the device (e.g., "/dev/ttyACM0").
|
||||
|
||||
Returns: None
|
||||
"""
|
||||
get_logger().log_info(f"Verifying device {device_path} exists")
|
||||
device_check = self.ssh_connection.send(f"ls {device_path}")
|
||||
device_check_str = "\n".join(device_check) if isinstance(device_check, list) else device_check
|
||||
validate_str_contains(device_check_str, device_path, f"Device {device_path} should exist")
|
||||
|
||||
def verify_gnss_pty_data(self, device_path: str) -> None:
|
||||
"""
|
||||
Verify GNSS data through PTY device.
|
||||
|
||||
Args:
|
||||
device_path (str): Path to the original device (e.g., "/dev/ttyACM0").
|
||||
|
||||
Returns: None
|
||||
"""
|
||||
pty_path = f"{device_path}.pty"
|
||||
get_logger().log_info(f"Verifying GNSS data from PTY device {pty_path}")
|
||||
gnss_data = self.ssh_connection.send_as_sudo(f"timeout 60 cat {pty_path} | head -20")
|
||||
gnss_data_str = "\n".join(gnss_data) if isinstance(gnss_data, list) else gnss_data
|
||||
validate_str_contains(gnss_data_str, "$GP", "Should receive NMEA data through PTY device")
|
||||
|
||||
def verify_ts2phc_config_serialport(self, instance_name: str, expected_serialport: str) -> None:
|
||||
"""
|
||||
Verify ts2phc configuration file contains correct nmea_serialport setting.
|
||||
|
||||
Args:
|
||||
instance_name (str): Name of the PTP instance.
|
||||
expected_serialport (str): Expected serialport path (e.g., "/dev/ttyACM0" or "/dev/ttyACM0.pty").
|
||||
|
||||
Returns: None
|
||||
"""
|
||||
config_file = f"/etc/linuxptp/ptpinstance/ts2phc-{instance_name}.conf"
|
||||
get_logger().log_info(f"Verifying ts2phc config file {config_file}")
|
||||
|
||||
cat_ptp_config_keywords = CatPtpConfigKeywords(self.ssh_connection)
|
||||
cat_ptp_config_output = cat_ptp_config_keywords.cat_ptp_config(config_file)
|
||||
get_pmc_get_default_data_set_object = cat_ptp_config_output.data_set_output.get_pmc_get_default_data_set_object()
|
||||
observed_serialport = get_pmc_get_default_data_set_object.get_ts2phc_nmea_serialport()
|
||||
|
||||
validate_equals(observed_serialport, expected_serialport, "verify ts2phc.nmea_serialport")
|
||||
@@ -0,0 +1,142 @@
|
||||
class GnssMonitoringDataObject:
|
||||
"""
|
||||
Represents GNSS monitoring data for a single device.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initializes a GnssMonitoringDataObject instance.
|
||||
"""
|
||||
self.device_path = None
|
||||
self.gpsd_running = None
|
||||
self.lock_state = None
|
||||
self.satellite_count = None
|
||||
self.signal_quality_min = None
|
||||
self.signal_quality_max = None
|
||||
self.signal_quality_avg = None
|
||||
|
||||
def set_device_path(self, device_path: str):
|
||||
"""
|
||||
Setter for device path.
|
||||
|
||||
Args:
|
||||
device_path (str): Path to the GNSS device.
|
||||
"""
|
||||
self.device_path = device_path
|
||||
|
||||
def get_device_path(self) -> str:
|
||||
"""
|
||||
Getter for device path.
|
||||
|
||||
Returns:
|
||||
str: Path to the GNSS device.
|
||||
"""
|
||||
return self.device_path
|
||||
|
||||
def set_gpsd_running(self, gpsd_running: int):
|
||||
"""
|
||||
Setter for gpsd running status.
|
||||
|
||||
Args:
|
||||
gpsd_running (int): GPSD running status (1 for running, 0 for not running).
|
||||
"""
|
||||
self.gpsd_running = gpsd_running
|
||||
|
||||
def get_gpsd_running(self) -> int:
|
||||
"""
|
||||
Getter for gpsd running status.
|
||||
|
||||
Returns:
|
||||
int: GPSD running status.
|
||||
"""
|
||||
return self.gpsd_running
|
||||
|
||||
def set_lock_state(self, lock_state: int):
|
||||
"""
|
||||
Setter for lock state.
|
||||
|
||||
Args:
|
||||
lock_state (int): Lock state (1 for locked, 0 for not locked).
|
||||
"""
|
||||
self.lock_state = lock_state
|
||||
|
||||
def get_lock_state(self) -> int:
|
||||
"""
|
||||
Getter for lock state.
|
||||
|
||||
Returns:
|
||||
int: Lock state.
|
||||
"""
|
||||
return self.lock_state
|
||||
|
||||
def set_satellite_count(self, satellite_count: int):
|
||||
"""
|
||||
Setter for satellite count.
|
||||
|
||||
Args:
|
||||
satellite_count (int): Number of satellites.
|
||||
"""
|
||||
self.satellite_count = satellite_count
|
||||
|
||||
def get_satellite_count(self) -> int:
|
||||
"""
|
||||
Getter for satellite count.
|
||||
|
||||
Returns:
|
||||
int: Number of satellites.
|
||||
"""
|
||||
return self.satellite_count
|
||||
|
||||
def set_signal_quality_min(self, signal_quality_min: float):
|
||||
"""
|
||||
Setter for minimum signal quality.
|
||||
|
||||
Args:
|
||||
signal_quality_min (float): Minimum signal quality in dB-Hz.
|
||||
"""
|
||||
self.signal_quality_min = signal_quality_min
|
||||
|
||||
def get_signal_quality_min(self) -> float:
|
||||
"""
|
||||
Getter for minimum signal quality.
|
||||
|
||||
Returns:
|
||||
float: Minimum signal quality.
|
||||
"""
|
||||
return self.signal_quality_min
|
||||
|
||||
def set_signal_quality_max(self, signal_quality_max: float):
|
||||
"""
|
||||
Setter for maximum signal quality.
|
||||
|
||||
Args:
|
||||
signal_quality_max (float): Maximum signal quality in dB-Hz.
|
||||
"""
|
||||
self.signal_quality_max = signal_quality_max
|
||||
|
||||
def get_signal_quality_max(self) -> float:
|
||||
"""
|
||||
Getter for maximum signal quality.
|
||||
|
||||
Returns:
|
||||
float: Maximum signal quality.
|
||||
"""
|
||||
return self.signal_quality_max
|
||||
|
||||
def set_signal_quality_avg(self, signal_quality_avg: float):
|
||||
"""
|
||||
Setter for average signal quality.
|
||||
|
||||
Args:
|
||||
signal_quality_avg (float): Average signal quality in dB-Hz.
|
||||
"""
|
||||
self.signal_quality_avg = signal_quality_avg
|
||||
|
||||
def get_signal_quality_avg(self) -> float:
|
||||
"""
|
||||
Getter for average signal quality.
|
||||
|
||||
Returns:
|
||||
float: Average signal quality.
|
||||
"""
|
||||
return self.signal_quality_avg
|
||||
@@ -0,0 +1,85 @@
|
||||
import re
|
||||
from typing import Union
|
||||
|
||||
from keywords.cloud_platform.system.ptp.objects.gnss_monitoring_data_object import GnssMonitoringDataObject
|
||||
|
||||
|
||||
class GnssMonitoringDataOutput:
|
||||
"""
|
||||
This class parses GNSS monitoring CLI tool output and creates GnssMonitoringDataObject instances.
|
||||
"""
|
||||
|
||||
def __init__(self, cli_output: Union[str, list[str]]):
|
||||
"""
|
||||
Initialize with CLI tool output.
|
||||
|
||||
Args:
|
||||
cli_output (Union[str, list[str]]): Output from GNSS monitoring CLI tool.
|
||||
"""
|
||||
self.raw_output = cli_output
|
||||
self.monitoring_data = self._parse_monitoring_data()
|
||||
|
||||
def _parse_monitoring_data(self) -> list[GnssMonitoringDataObject]:
|
||||
"""
|
||||
Parse the CLI output and create monitoring data objects.
|
||||
|
||||
Returns:
|
||||
list[GnssMonitoringDataObject]: List of parsed monitoring data objects.
|
||||
"""
|
||||
monitoring_data = []
|
||||
|
||||
# Convert to string if it's a list
|
||||
if isinstance(self.raw_output, list):
|
||||
output_text = "\n".join(self.raw_output)
|
||||
else:
|
||||
output_text = self.raw_output
|
||||
|
||||
# Parse device data using regex
|
||||
# Example: /dev/ttyACM0's gps_data: GpsData(gpsd_running=1, lock_state=1, satellite_count=21, signal_quality_db=SignalQualityDb(min=42.0, max=47.0, avg=44.571))
|
||||
device_pattern = r"(/dev/\w+)'s gps_data: GpsData\(gpsd_running=(\d+), lock_state=(\d+), satellite_count=(\d+), signal_quality_db=SignalQualityDb\(min=([\d.]+), max=([\d.]+), avg=([\d.]+)\)\)"
|
||||
|
||||
matches = re.findall(device_pattern, output_text)
|
||||
|
||||
for match in matches:
|
||||
device_path, gpsd_running, lock_state, satellite_count, sig_min, sig_max, sig_avg = match
|
||||
|
||||
data_obj = GnssMonitoringDataObject()
|
||||
data_obj.set_device_path(device_path)
|
||||
data_obj.set_gpsd_running(int(gpsd_running))
|
||||
data_obj.set_lock_state(int(lock_state))
|
||||
data_obj.set_satellite_count(int(satellite_count))
|
||||
data_obj.set_signal_quality_min(float(sig_min))
|
||||
data_obj.set_signal_quality_max(float(sig_max))
|
||||
data_obj.set_signal_quality_avg(float(sig_avg))
|
||||
|
||||
monitoring_data.append(data_obj)
|
||||
|
||||
return monitoring_data
|
||||
|
||||
def get_monitoring_data(self) -> list[GnssMonitoringDataObject]:
|
||||
"""
|
||||
Get all monitoring data objects.
|
||||
|
||||
Returns:
|
||||
list[GnssMonitoringDataObject]: List of monitoring data objects.
|
||||
"""
|
||||
return self.monitoring_data
|
||||
|
||||
def get_monitoring_data_for_device(self, device_path: str) -> GnssMonitoringDataObject:
|
||||
"""
|
||||
Get monitoring data for a specific device.
|
||||
|
||||
Args:
|
||||
device_path (str): Path to the device.
|
||||
|
||||
Returns:
|
||||
GnssMonitoringDataObject: Monitoring data for the specified device.
|
||||
|
||||
Raises:
|
||||
ValueError: If device not found in monitoring data.
|
||||
"""
|
||||
for data in self.monitoring_data:
|
||||
if data.get_device_path() == device_path:
|
||||
return data
|
||||
|
||||
raise ValueError(f"Device '{device_path}' not found in monitoring data")
|
||||
@@ -55,4 +55,4 @@ class SystemPTPInstanceOutput:
|
||||
Returns:
|
||||
str: ptp instance parameters
|
||||
"""
|
||||
return PTPParametersParser(self.system_ptp_instance_object.get_parameters()).process_cmdline_opts()
|
||||
return PTPParametersParser(self.system_ptp_instance_object.get_parameters()).process_parameters()
|
||||
|
||||
@@ -47,3 +47,34 @@ class PTPParametersParser:
|
||||
output_str = parameters_str
|
||||
|
||||
return output_str
|
||||
|
||||
def process_parameters(self) -> str:
|
||||
"""
|
||||
Processes all PTP parameters, handling both string and list inputs,
|
||||
to ensure values are properly quoted.
|
||||
|
||||
Returns:
|
||||
str: The modified string with parameter values properly quoted.
|
||||
"""
|
||||
if isinstance(self.parameters, list):
|
||||
parameters_str = " ".join(self.parameters) # Convert list to string
|
||||
else:
|
||||
parameters_str = self.parameters
|
||||
|
||||
# Process devices parameter
|
||||
devices_match = re.search(r"(devices=)(.*?)(?=\s+\w+=|$)", parameters_str)
|
||||
if devices_match:
|
||||
prefix, value = devices_match.group(1), devices_match.group(2).strip()
|
||||
if " " in value and not (value.startswith("'") and value.endswith("'")):
|
||||
value = f"'{value}'"
|
||||
parameters_str = parameters_str.replace(devices_match.group(0), f"{prefix}{value}")
|
||||
|
||||
# Process cmdline_opts parameter
|
||||
cmdline_match = re.search(r"(cmdline_opts=)(.*?)(?=\s+\w+=|$)", parameters_str)
|
||||
if cmdline_match:
|
||||
prefix, value = cmdline_match.group(1), cmdline_match.group(2).strip()
|
||||
if not (value.startswith("'") and value.endswith("'")):
|
||||
value = f"'{value}'"
|
||||
parameters_str = parameters_str.replace(cmdline_match.group(0), f"{prefix}{value}")
|
||||
|
||||
return parameters_str
|
||||
|
||||
@@ -228,22 +228,16 @@ class PTPSetupExecutorKeywords(BaseKeyword):
|
||||
|
||||
validate_equals_with_retry(check_ptp4l_status, True, "systemctl status for ptp4l", 120, 30)
|
||||
|
||||
# wait for SMA status
|
||||
for clock_instance_obj in self.clock_setup_list:
|
||||
|
||||
ifaces_to_check = [(host, iface) for host in clock_instance_obj.get_instance_hostnames() for ptp_host_if in clock_instance_obj.get_ptp_interfaces() if "input" in ptp_host_if.get_ptp_interface_parameter() for iface in filter(None, ptp_host_if.get_interfaces_for_hostname(host))]
|
||||
|
||||
for host, interface in ifaces_to_check:
|
||||
pci_address = gnss_keywords.get_pci_slot_name(host, interface)
|
||||
cgu_location = f"/sys/kernel/debug/ice/{pci_address}/cgu"
|
||||
gnss_keywords.validate_sma1_and_gnss_1pps_eec_pps_dpll_status_with_retry(host, cgu_location, "SMA1", timeout=180, polling_interval=30)
|
||||
|
||||
# wait for GNSS status
|
||||
for ts2phc_instance_obj in self.ts2phc_setup_list:
|
||||
expected_gnss_port = gnss_keywords.extract_gnss_port(ts2phc_instance_obj.get_instance_parameters())
|
||||
if not expected_gnss_port:
|
||||
continue
|
||||
|
||||
if expected_gnss_port == "ttyACM0":
|
||||
get_logger().log_info(f"Skipping CGU debug validation for {expected_gnss_port} - not valid for USB serial device type")
|
||||
return
|
||||
|
||||
ifaces_to_check = []
|
||||
for host in ts2phc_instance_obj.get_instance_hostnames():
|
||||
for ptp_host_if in ts2phc_instance_obj.get_ptp_interfaces():
|
||||
@@ -257,3 +251,13 @@ class PTPSetupExecutorKeywords(BaseKeyword):
|
||||
pci_address = gnss_keywords.get_pci_slot_name(host, interface)
|
||||
cgu_location = f"/sys/kernel/debug/ice/{pci_address}/cgu"
|
||||
gnss_keywords.validate_sma1_and_gnss_1pps_eec_pps_dpll_status_with_retry(host, cgu_location, timeout=180, polling_interval=30)
|
||||
|
||||
# wait for SMA status
|
||||
for clock_instance_obj in self.clock_setup_list:
|
||||
|
||||
ifaces_to_check = [(host, iface) for host in clock_instance_obj.get_instance_hostnames() for ptp_host_if in clock_instance_obj.get_ptp_interfaces() if "input" in ptp_host_if.get_ptp_interface_parameter() for iface in filter(None, ptp_host_if.get_interfaces_for_hostname(host))]
|
||||
|
||||
for host, interface in ifaces_to_check:
|
||||
pci_address = gnss_keywords.get_pci_slot_name(host, interface)
|
||||
cgu_location = f"/sys/kernel/debug/ice/{pci_address}/cgu"
|
||||
gnss_keywords.validate_sma1_and_gnss_1pps_eec_pps_dpll_status_with_retry(host, cgu_location, "SMA1", timeout=210, polling_interval=60)
|
||||
|
||||
@@ -81,6 +81,10 @@ class PTPVerifyConfigKeywords(BaseKeyword):
|
||||
get_logger().log_info("Validation skipped as expected; GNSS port is None")
|
||||
continue
|
||||
|
||||
if expected_gnss_port == "ttyACM0":
|
||||
get_logger().log_info(f"Skipping CGU debug validation for {expected_gnss_port} - not valid for USB serial device type")
|
||||
return
|
||||
|
||||
for ptp_host_if in ts2phc_instance_obj.get_ptp_interfaces():
|
||||
for host in hosts:
|
||||
interfaces = ptp_host_if.get_interfaces_for_hostname(host.get_host_name())
|
||||
|
||||
27
keywords/ptp/cat/gnss_monitor_conf_keywords.py
Normal file
27
keywords/ptp/cat/gnss_monitor_conf_keywords.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from framework.ssh.ssh_connection import SSHConnection
|
||||
from keywords.base_keyword import BaseKeyword
|
||||
from keywords.ptp.cat.objects.gnss_monitor_conf_output import GnssMonitorConfOutput
|
||||
|
||||
|
||||
class GnssMonitorConfKeywords(BaseKeyword):
|
||||
"""
|
||||
Class for GNSS Monitor Conf Keywords.
|
||||
"""
|
||||
|
||||
def __init__(self, ssh_connection: SSHConnection):
|
||||
self.ssh_connection = ssh_connection
|
||||
|
||||
def cat_gnss_monitor_conf(self, gnss_monitor_conf_location: str) -> GnssMonitorConfOutput:
|
||||
"""
|
||||
Runs the command sudo cat <gnss_monitor_conf_location> ex. /etc/linuxptp/ptpinstance/gnss-monitor-ptp.conf.
|
||||
|
||||
Args:
|
||||
gnss_monitor_conf_location (str): the GNSS monitor conf location.
|
||||
|
||||
Returns:
|
||||
GnssMonitorConfOutput: the GnssMonitorConfOutput.
|
||||
|
||||
"""
|
||||
output = self.ssh_connection.send_as_sudo(f"cat {gnss_monitor_conf_location}")
|
||||
gnss_monitor_conf_output = GnssMonitorConfOutput(output)
|
||||
return gnss_monitor_conf_output
|
||||
59
keywords/ptp/cat/gnss_monitor_conf_parser.py
Normal file
59
keywords/ptp/cat/gnss_monitor_conf_parser.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from framework.exceptions.keyword_exception import KeywordException
|
||||
|
||||
|
||||
class GnssMonitorConfParser:
|
||||
"""
|
||||
Class for GNSS monitor conf parsing
|
||||
|
||||
Example:
|
||||
[global]
|
||||
##
|
||||
## Default Data Set
|
||||
##
|
||||
devices /dev/ttyACM0 /dev/gnssx
|
||||
satellite_count 8
|
||||
signal_quality_db 30
|
||||
"""
|
||||
|
||||
def __init__(self, gnss_monitor_conf_output: list[str]):
|
||||
"""
|
||||
Constructor
|
||||
|
||||
Args:
|
||||
gnss_monitor_conf_output (list[str]): a list of strings representing the output of a 'cat gnss-monitor-ptp.conf' command.
|
||||
"""
|
||||
self.gnss_monitor_conf_output = gnss_monitor_conf_output
|
||||
|
||||
def get_output_values_dict(self) -> dict:
|
||||
"""
|
||||
Getter for output values dict
|
||||
|
||||
Returns:
|
||||
dict: the output values dict
|
||||
|
||||
"""
|
||||
output_values_dict = {}
|
||||
|
||||
for row in self.gnss_monitor_conf_output:
|
||||
if "~$" in row or "Password:" in row:
|
||||
continue # these prompts should be ignored
|
||||
|
||||
# Skip empty lines, comments, and section headers
|
||||
stripped_row = row.strip()
|
||||
if not stripped_row or stripped_row.startswith("#") or stripped_row.startswith("["):
|
||||
continue
|
||||
|
||||
# Split on first space to handle values with spaces
|
||||
parts = stripped_row.split(None, 1)
|
||||
if len(parts) == 2:
|
||||
key, value = parts
|
||||
output_values_dict[key.strip()] = value.strip()
|
||||
elif len(parts) == 1:
|
||||
# Handle cases where there might be a key without value
|
||||
key = parts[0].strip()
|
||||
if key:
|
||||
output_values_dict[key] = ""
|
||||
else:
|
||||
raise KeywordException(f"Line with values: {row} was not in the expected format")
|
||||
|
||||
return output_values_dict
|
||||
69
keywords/ptp/cat/objects/gnss_monitor_conf_object.py
Normal file
69
keywords/ptp/cat/objects/gnss_monitor_conf_object.py
Normal file
@@ -0,0 +1,69 @@
|
||||
class GnssMonitorConfObject:
|
||||
"""
|
||||
Object to hold the values of GNSS Monitor conf Object
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.devices: str = ""
|
||||
self.satellite_count: int = 0
|
||||
self.signal_quality_db: int = 0
|
||||
|
||||
def set_devices(self, devices: str):
|
||||
"""
|
||||
Setter for devices
|
||||
|
||||
Args:
|
||||
devices (str): the devices
|
||||
|
||||
"""
|
||||
self.devices = devices
|
||||
|
||||
def get_devices(self) -> str:
|
||||
"""
|
||||
Getter for devices
|
||||
|
||||
Returns:
|
||||
str: the devices
|
||||
|
||||
"""
|
||||
return self.devices
|
||||
|
||||
def set_satellite_count(self, satellite_count: int):
|
||||
"""
|
||||
Setter for satellite_count
|
||||
|
||||
Args:
|
||||
satellite_count (int): the satellite_count
|
||||
|
||||
"""
|
||||
self.satellite_count = satellite_count
|
||||
|
||||
def get_satellite_count(self) -> int:
|
||||
"""
|
||||
Getter for satellite_count
|
||||
|
||||
Returns:
|
||||
int: the satellite_count
|
||||
|
||||
"""
|
||||
return self.satellite_count
|
||||
|
||||
def set_signal_quality_db(self, signal_quality_db: int):
|
||||
"""
|
||||
Setter for signal_quality_db
|
||||
|
||||
Args:
|
||||
signal_quality_db (int): the signal_quality_db
|
||||
|
||||
"""
|
||||
self.signal_quality_db = signal_quality_db
|
||||
|
||||
def get_signal_quality_db(self) -> int:
|
||||
"""
|
||||
Getter for signal_quality_db
|
||||
|
||||
Returns:
|
||||
int: the signal_quality_db
|
||||
|
||||
"""
|
||||
return self.signal_quality_db
|
||||
50
keywords/ptp/cat/objects/gnss_monitor_conf_output.py
Normal file
50
keywords/ptp/cat/objects/gnss_monitor_conf_output.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from keywords.ptp.cat.gnss_monitor_conf_parser import GnssMonitorConfParser
|
||||
from keywords.ptp.cat.objects.gnss_monitor_conf_object import GnssMonitorConfObject
|
||||
|
||||
|
||||
class GnssMonitorConfOutput:
|
||||
"""
|
||||
This class parses the output of cat GNSS monitor conf file
|
||||
|
||||
Example:
|
||||
[global]
|
||||
##
|
||||
## Default Data Set
|
||||
##
|
||||
devices /dev/ttyACM0 /dev/gnssx
|
||||
satellite_count 8
|
||||
signal_quality_db 30
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, gnss_monitor_conf_output: list[str]):
|
||||
"""
|
||||
Create an internal GnssMonitorConfObject from the passed parameter.
|
||||
|
||||
Args:
|
||||
gnss_monitor_conf_output (list[str]): a list of strings representing the GNSS monitor conf output
|
||||
|
||||
"""
|
||||
gnss_monitor_conf_parser = GnssMonitorConfParser(gnss_monitor_conf_output)
|
||||
output_values = gnss_monitor_conf_parser.get_output_values_dict()
|
||||
|
||||
self.gnss_monitor_conf_object = GnssMonitorConfObject()
|
||||
|
||||
if "devices" in output_values:
|
||||
self.gnss_monitor_conf_object.set_devices(output_values["devices"])
|
||||
|
||||
if "satellite_count" in output_values:
|
||||
self.gnss_monitor_conf_object.set_satellite_count(int(output_values["satellite_count"]))
|
||||
|
||||
if "signal_quality_db" in output_values:
|
||||
self.gnss_monitor_conf_object.set_signal_quality_db(int(output_values["signal_quality_db"]))
|
||||
|
||||
def get_gnss_monitor_conf_object(self) -> GnssMonitorConfObject:
|
||||
"""
|
||||
Getter for GnssMonitorConfObject.
|
||||
|
||||
Returns:
|
||||
GnssMonitorConfObject: The GnssMonitorConfObject
|
||||
|
||||
"""
|
||||
return self.gnss_monitor_conf_object
|
||||
@@ -76,9 +76,18 @@ class PTPServiceStatusValidator(BaseKeyword):
|
||||
observed_service_status = service_status_output.get_ptp4l_object(name).get_active()
|
||||
get_command = service_status_output.get_ptp4l_object(name).get_command()
|
||||
|
||||
# From the input string "cmdline_opts='-s enpXXs0f2 -O -37 -m'"
|
||||
# The extracted output string is '-s enpXXs0f2 -O -37 -m'
|
||||
instance_parameter = eval(instance_parameters.split("=")[1])
|
||||
# Extract cmdline_opts parameter from the instance_parameters string
|
||||
# Handle cases like "cmdline_opts='-w -s eno1' domainNumber=24 uds_address=/var/run/ptp4l-ptp-inst1"
|
||||
cmdline_match = re.search(r"cmdline_opts='([^']+)'", instance_parameters)
|
||||
if cmdline_match:
|
||||
instance_parameter = cmdline_match.group(1)
|
||||
else:
|
||||
# Fallback for simple cases without quotes
|
||||
parts = instance_parameters.split("=", 1)
|
||||
if len(parts) > 1:
|
||||
instance_parameter = parts[1].split()[0] # Take first part before space
|
||||
else:
|
||||
instance_parameter = ""
|
||||
|
||||
if expected_service_status in observed_service_status and instance_parameter in get_command:
|
||||
get_logger().log_info(f"Validation Successful - systemctl status {service_name}")
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from config.configuration_manager import ConfigurationManager
|
||||
|
||||
|
||||
class PTPHostInterfaceSetup:
|
||||
"""
|
||||
@@ -19,6 +21,8 @@ class PTPHostInterfaceSetup:
|
||||
Exception: If the setup_dict does not contain required controller interfaces.
|
||||
Exception: If the setup_dict does not contain required compute interfaces.
|
||||
"""
|
||||
lab_type = ConfigurationManager.get_lab_config().get_lab_type()
|
||||
|
||||
if "name" not in setup_dict:
|
||||
raise Exception("Every ptp host interface entry should have a name.")
|
||||
self.name = setup_dict["name"]
|
||||
@@ -31,9 +35,9 @@ class PTPHostInterfaceSetup:
|
||||
raise Exception(f"The ptp host interface entry {self.name} must have controller_0_interfaces defined.")
|
||||
self.controller_0_interfaces = setup_dict["controller_0_interfaces"]
|
||||
|
||||
if "controller_1_interfaces" not in setup_dict:
|
||||
if "controller_1_interfaces" not in setup_dict and lab_type != "Simplex":
|
||||
raise Exception(f"The ptp host interface entry {self.name} must have controller_1_interfaces defined.")
|
||||
self.controller_1_interfaces = setup_dict["controller_1_interfaces"]
|
||||
self.controller_1_interfaces = setup_dict.get("controller_1_interfaces")
|
||||
|
||||
self.compute_0_interfaces = None
|
||||
if "compute_0_interfaces" in setup_dict:
|
||||
|
||||
102
resources/ptp/setup/ptp_configuration_expectation_gnr_d.json5
Normal file
102
resources/ptp/setup/ptp_configuration_expectation_gnr_d.json5
Normal file
@@ -0,0 +1,102 @@
|
||||
{
|
||||
// PTP Configuration Expectation for GNR-D GNSS
|
||||
// This file defines the expected PTP configuration for AIO-SX system
|
||||
// Based on the provided system commands for PTP setup
|
||||
|
||||
// Service types:
|
||||
// - T-TSC: Telecom Time Slave Clock - Synchronizes to an upstream master clock via GNSS
|
||||
|
||||
// Time sources:
|
||||
// - GNSS: Global Navigation Satellite System provides time via /dev/ttyACM0
|
||||
|
||||
ptp_instances: {
|
||||
|
||||
ptp4l: [
|
||||
{
|
||||
// PTP-INST1 instance - Telecom Time Slave Clock (T-TSC)
|
||||
// Receives time from GNSS via ts2phc and distributes via eno1
|
||||
// Domain 24 with G.8275.x profile
|
||||
name: "ptp-inst1",
|
||||
instance_hostnames : ["controller-0"],
|
||||
instance_parameters: "domainNumber=24 tx_timestamp_timeout=700 dataset_comparison=G.8275.x fault_reset_interval=0 logAnnounceInterval=-3 logMinDelayReqInterval=-4 logSyncInterval=-4",
|
||||
ptp_interface_names: [
|
||||
"ptp-iface1",
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// phc2sys - Synchronizes system clock to PTP hardware clock
|
||||
// Uses eno1 interface with specific command line options
|
||||
phc2sys : [
|
||||
{
|
||||
// PHC-INST1 instance - Synchronizes controller-0 system clock
|
||||
// Uses eno1 interface with wait mode and specific UDS address
|
||||
name: "phc-inst1",
|
||||
instance_hostnames : ["controller-0"],
|
||||
instance_parameters: "cmdline_opts='-w -s {{ controller_0.nic1.nic_connection.interface }}' domainNumber=24 uds_address=/var/run/ptp4l-ptp-inst1",
|
||||
ptp_interface_names: [],
|
||||
},
|
||||
],
|
||||
|
||||
// ts2phc - Synchronizes PTP hardware clock to external time source
|
||||
// Uses GNSS receiver via NMEA serial port /dev/ttyACM0
|
||||
ts2phc : [
|
||||
{
|
||||
// TS1 instance - Synchronizes controller-0 to GNSS time source
|
||||
// Uses NMEA serial port /dev/ttyACM0 for GNSS connection
|
||||
name: "ts1",
|
||||
instance_hostnames : ["controller-0"],
|
||||
instance_parameters: "ts2phc.nmea_serialport=/dev/ttyACM0",
|
||||
ptp_interface_names: [
|
||||
"tsint1",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// PTP Host Interfaces - Maps logical PTP interfaces to physical network interfaces
|
||||
// Defines which physical interfaces are used for each PTP instance on each host
|
||||
ptp_host_ifs: [
|
||||
{
|
||||
name: "ptp-iface1",
|
||||
controller_0_interfaces: ["{{ controller_0.nic1.nic_connection.interface }}"],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
{
|
||||
name: "tsint1",
|
||||
controller_0_interfaces: ["{{ controller_0.nic1.nic_connection.interface }}"],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
],
|
||||
|
||||
// This section is for validation purposes. All expected values are maintained here
|
||||
// Used by test framework to verify correct PTP configuration and behavior
|
||||
// Defines expected port states, parent-child relationships, and clock settings
|
||||
"expected_dict": {
|
||||
"ptp4l": [
|
||||
{
|
||||
"name": "ptp-inst1",
|
||||
"controller-0": {
|
||||
"parent_data_set" : {
|
||||
"gm_clock_class": [6, 7],
|
||||
"gm_clock_accuracy": "0x20",
|
||||
"gm_offset_scaled_log_variance": "0x4e5d"
|
||||
},
|
||||
"time_properties_data_set": {
|
||||
"current_utc_offset": 37,
|
||||
"current_utc_offset_valid": 0,
|
||||
"time_traceable": 1,
|
||||
"frequency_traceable": 1
|
||||
},
|
||||
"grandmaster_settings": {{ grandmaster_settings.grandmaster_settings_tgm_default }},
|
||||
"port_data_set": [
|
||||
{
|
||||
"interface" : "{{ controller_0.nic1.nic_connection.interface }}",
|
||||
"port_state": "MASTER"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
947
testcases/cloud_platform/regression/ptp/test_gnss_monitoring.py
Normal file
947
testcases/cloud_platform/regression/ptp/test_gnss_monitoring.py
Normal file
@@ -0,0 +1,947 @@
|
||||
from pytest import mark
|
||||
|
||||
from framework.logging.automation_logger import get_logger
|
||||
from framework.resources.resource_finder import get_stx_resource_path
|
||||
from framework.validation.validation import validate_equals, validate_str_contains
|
||||
from keywords.cloud_platform.fault_management.alarms.alarm_list_keywords import AlarmListKeywords
|
||||
from keywords.cloud_platform.fault_management.alarms.objects.alarm_list_object import AlarmListObject
|
||||
from keywords.cloud_platform.ssh.lab_connection_keywords import LabConnectionKeywords
|
||||
from keywords.cloud_platform.system.host.system_host_list_keywords import SystemHostListKeywords
|
||||
from keywords.cloud_platform.system.host.system_host_lock_keywords import SystemHostLockKeywords
|
||||
from keywords.cloud_platform.system.host.system_host_reboot_keywords import SystemHostRebootKeywords
|
||||
from keywords.cloud_platform.system.ptp.gnss_monitoring_keywords import GnssMonitoringKeywords
|
||||
from keywords.cloud_platform.system.ptp.ptp_readiness_keywords import PTPReadinessKeywords
|
||||
from keywords.cloud_platform.system.ptp.ptp_setup_executor_keywords import PTPSetupExecutorKeywords
|
||||
from keywords.cloud_platform.system.ptp.ptp_teardown_executor_keywords import PTPTeardownExecutorKeywords
|
||||
from keywords.cloud_platform.system.ptp.ptp_verify_config_keywords import PTPVerifyConfigKeywords
|
||||
from keywords.cloud_platform.system.ptp.system_host_ptp_instance_keywords import SystemHostPTPInstanceKeywords
|
||||
from keywords.cloud_platform.system.ptp.system_ptp_instance_keywords import SystemPTPInstanceKeywords
|
||||
from keywords.cloud_platform.system.ptp.system_ptp_instance_parameter_keywords import SystemPTPInstanceParameterKeywords
|
||||
from keywords.files.file_keywords import FileKeywords
|
||||
from keywords.ptp.setup.ptp_setup_reader import PTPSetupKeywords
|
||||
|
||||
|
||||
@mark.p0
|
||||
@mark.lab_has_gnr_d
|
||||
def test_delete_and_add_all_ptp_configuration() -> None:
|
||||
"""This test verifies that all PTP configurations can be cleanly removed
|
||||
and re-added, ensuring proper system state management.
|
||||
|
||||
Test Steps:
|
||||
1. Delete all existing PTP configurations
|
||||
2. Add all PTP configurations from template
|
||||
3. Verify all PTP configurations are properly applied
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
|
||||
get_logger().log_info("Delete all PTP configuration")
|
||||
ptp_teardown_keywords = PTPTeardownExecutorKeywords(ssh_connection)
|
||||
ptp_teardown_keywords.delete_all_ptp_configurations()
|
||||
|
||||
get_logger().log_info("Add all PTP configuration")
|
||||
ptp_setup_template_path = get_stx_resource_path("resources/ptp/setup/ptp_configuration_expectation_gnr_d.json5")
|
||||
ptp_setup_executor_keywords = PTPSetupExecutorKeywords(ssh_connection, ptp_setup_template_path)
|
||||
ptp_setup_executor_keywords.add_all_ptp_configurations()
|
||||
|
||||
ptp_readiness_keywords = PTPReadinessKeywords(LabConnectionKeywords().get_ssh_for_hostname("controller-0"))
|
||||
ptp_readiness_keywords.wait_for_port_state_appear_in_port_data_set("ptp-inst1", ["MASTER"])
|
||||
ptp_readiness_keywords.wait_for_gm_clock_class_appear_in_parent_data_set("ptp-inst1", [6, 7])
|
||||
|
||||
get_logger().log_info("Verify all PTP configuration")
|
||||
ptp_setup_keywords = PTPSetupKeywords()
|
||||
ptp_setup = ptp_setup_keywords.generate_ptp_setup_from_template(ptp_setup_template_path)
|
||||
ptp_verify_config_keywords = PTPVerifyConfigKeywords(ssh_connection, ptp_setup)
|
||||
ptp_verify_config_keywords.verify_all_ptp_configurations()
|
||||
|
||||
|
||||
@mark.p0
|
||||
@mark.lab_has_gnr_d
|
||||
def test_gnss_environment_setup_verification(request) -> None:
|
||||
"""Verify test environment setup and GNSS device availability for monitoring functionality.
|
||||
|
||||
This test ensures that all required GNSS hardware and software components
|
||||
are properly configured and operational before running monitoring tests.
|
||||
|
||||
Args:
|
||||
request (pytest.FixtureRequest): Pytest request fixture for test cleanup registration.
|
||||
|
||||
Test Steps:
|
||||
1. Check GNSS device availability at /dev/ttyACM0
|
||||
2. Verify GNSS data stream contains NMEA sentences
|
||||
3. Check zl3073x kernel module is loaded
|
||||
4. Verify network interface is UP with IP address
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
|
||||
get_logger().log_test_case_step("Checking GNSS device availability")
|
||||
gnss_monitoring_keywords = GnssMonitoringKeywords(ssh_connection)
|
||||
gnss_monitoring_keywords.verify_device_exists("/dev/ttyACM0")
|
||||
|
||||
get_logger().log_test_case_step("Verifying GNSS data stream")
|
||||
gnss_data = ssh_connection.send_as_sudo("timeout 5 cat /dev/ttyACM0 | head -10")
|
||||
validate_str_contains(gnss_data, "$GN", "Should receive NMEA sentences")
|
||||
|
||||
get_logger().log_test_case_step("Checking zl3073x module")
|
||||
module_check = ssh_connection.send("lsmod | grep zl3073x")
|
||||
validate_str_contains(module_check, "zl3073x", "zl3073x module should be loaded")
|
||||
|
||||
get_logger().log_test_case_step("Verifying network interface")
|
||||
ptp_setup_template_path = get_stx_resource_path("resources/ptp/setup/ptp_configuration_expectation_gnr_d.json5")
|
||||
ptp_setup_keywords = PTPSetupKeywords()
|
||||
ptp_setup = ptp_setup_keywords.generate_ptp_setup_from_template(ptp_setup_template_path)
|
||||
|
||||
interfaces = ptp_setup.get_ptp4l_setup("ptp1").get_ptp_interface("ptp1if1").get_interfaces_for_hostname("controller-0")
|
||||
if not interfaces:
|
||||
raise Exception("No interfaces found for controller-0 NIC1")
|
||||
ctrl0_nic1_interface = interfaces[0]
|
||||
|
||||
interface_check = ssh_connection.send(f"ip a sh {ctrl0_nic1_interface}")
|
||||
validate_str_contains(interface_check, "UP", "Interface should be UP")
|
||||
validate_str_contains(interface_check, "inet", "Interface should have IP address")
|
||||
|
||||
|
||||
@mark.p0
|
||||
@mark.lab_has_gnr_d
|
||||
def test_gnss_monitoring_basic_instance_creation(request) -> None:
|
||||
"""Verify GNSS monitoring instance can be created and configured with proper service activation.
|
||||
|
||||
This test validates the complete lifecycle of creating a GNSS monitoring
|
||||
instance, configuring parameters, and verifying proper operation including
|
||||
service activation and alarm generation.
|
||||
|
||||
Args:
|
||||
request (pytest.FixtureRequest): Pytest request fixture for test cleanup registration.
|
||||
|
||||
Test Steps:
|
||||
1. Create and configure GNSS monitoring instance
|
||||
2. Apply configuration and verify services
|
||||
3. Verify PTY devices and data flow
|
||||
4. Check metrics and alarm conditions
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
ptp_instance_keywords = SystemPTPInstanceKeywords(ssh_connection)
|
||||
gnss_monitoring_keywords = GnssMonitoringKeywords(ssh_connection)
|
||||
ptp_parameter_keywords = SystemPTPInstanceParameterKeywords(ssh_connection)
|
||||
host_ptp_instance_keywords = SystemHostPTPInstanceKeywords(ssh_connection)
|
||||
alarm_keywords = AlarmListKeywords(ssh_connection)
|
||||
|
||||
def cleanup_monitoring_instance():
|
||||
"""Clean up GNSS monitoring instance."""
|
||||
get_logger().log_teardown_step("Cleaning up GNSS monitoring instance")
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_remove_with_error("controller-0", "test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "satellite_count=150")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "signal_quality_db=300")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'devices="/dev/ttyACM0 /dev/gnssx"')
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'cmdline_opts="-D 7"')
|
||||
ptp_instance_keywords.system_ptp_instance_delete_with_error("test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_inactive()
|
||||
|
||||
request.addfinalizer(cleanup_monitoring_instance)
|
||||
|
||||
get_logger().log_test_case_step("Creating GNSS monitor instance")
|
||||
gnss_monitoring_keywords.create_monitoring_instance("test-monitor")
|
||||
|
||||
get_logger().log_test_case_step("Configuring monitoring parameters")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "satellite_count=150")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "signal_quality_db=300")
|
||||
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'devices="/dev/ttyACM0 /dev/gnssx"')
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'cmdline_opts="-D 7"')
|
||||
|
||||
get_logger().log_test_case_step("Assigning to host")
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_assign("controller-0", "test-monitor")
|
||||
|
||||
get_logger().log_test_case_step("Applying configuration")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
|
||||
get_logger().log_test_case_step("Waiting for services to be ready")
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(devices=["/dev/ttyACM0", "/dev/gnssx"])
|
||||
|
||||
get_logger().log_test_case_step("Verifying GNSS monitor configuration file")
|
||||
gnss_monitoring_keywords.verify_monitoring_configuration_file(150, 300, "/dev/ttyACM0 /dev/gnssx")
|
||||
|
||||
get_logger().log_test_case_step("Verify ts2phc configuration for nmea_serialport")
|
||||
gnss_monitoring_keywords.verify_ts2phc_config_serialport("ts1", "/dev/ttyACM0.pty")
|
||||
|
||||
get_logger().log_test_case_step("Verifying PTY devices created")
|
||||
gnss_monitoring_keywords.verify_pty_device_exists("/dev/ttyACM0", True)
|
||||
gnss_monitoring_keywords.verify_device_exists("/dev/ttyACM0.pty")
|
||||
|
||||
get_logger().log_test_case_step("Testing GNSS data through PTY")
|
||||
gnss_monitoring_keywords.verify_gnss_pty_data("/dev/ttyACM0")
|
||||
|
||||
get_logger().log_test_case_step("Checking current satellite count and signal quality for /dev/ttyACM0")
|
||||
get_gnss_monitoring_data = gnss_monitoring_keywords.get_gnss_monitoring_data("/dev/ttyACM0")
|
||||
get_satellite_count_ttyACM0 = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_satellite_count()
|
||||
get_signal_quality_max_ttyACM0 = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_signal_quality_max()
|
||||
get_logger().log_info(f"Current GNSS satellite count for /dev/ttyACM0: {get_satellite_count_ttyACM0}")
|
||||
get_logger().log_info(f"Current GNSS signal quality for /dev/ttyACM0: {get_signal_quality_max_ttyACM0}")
|
||||
|
||||
get_logger().log_test_case_step("Checking current satellite count and signal quality for /dev/gnssx")
|
||||
get_gnss_monitoring_data = gnss_monitoring_keywords.get_gnss_monitoring_data("/dev/gnssx")
|
||||
get_satellite_count_gnssx = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/gnssx").get_satellite_count()
|
||||
get_signal_quality_max_gnssx = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/gnssx").get_signal_quality_max()
|
||||
get_logger().log_info(f"Current GNSS satellite count for /dev/gnssx: {get_satellite_count_gnssx}")
|
||||
get_logger().log_info(f"Current GNSS signal quality for /dev/gnssx: {get_signal_quality_max_gnssx}")
|
||||
|
||||
get_logger().log_test_case_step("Verifying alarm conditions")
|
||||
expected_alarms = []
|
||||
|
||||
# Check conditions and add expected alarms with dynamic values
|
||||
get_logger().log_info(f"gnssx satellite count {get_satellite_count_gnssx} < 150, expecting satellite alarm")
|
||||
satellite_alarm_gnssx = AlarmListObject()
|
||||
satellite_alarm_gnssx.set_alarm_id("100.119")
|
||||
satellite_alarm_gnssx.set_reason_text(f"controller-0 GNSS satellite count below threshold state: satellite count {get_satellite_count_gnssx} \(expected: >= 150\)")
|
||||
satellite_alarm_gnssx.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/gnssx.ptp=GNSS-satellite-count")
|
||||
expected_alarms.append(satellite_alarm_gnssx)
|
||||
|
||||
get_logger().log_info(f"gnssx signal quality {get_signal_quality_max_gnssx} < 300, expecting signal quality alarm")
|
||||
signal_quality_alarm_gnssx = AlarmListObject()
|
||||
signal_quality_alarm_gnssx.set_alarm_id("100.119")
|
||||
signal_quality_alarm_gnssx.set_reason_text(r"controller-0 GNSS signal quality db below threshold state: signal_quality_db [\d\.]+\s+\(expected: >= 300.0\)")
|
||||
signal_quality_alarm_gnssx.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/gnssx.ptp=GNSS-signal-quality-db")
|
||||
expected_alarms.append(signal_quality_alarm_gnssx)
|
||||
|
||||
get_logger().log_info(f"ttyACM0 satellite count {get_satellite_count_ttyACM0} < 150, expecting satellite alarm")
|
||||
satellite_alarm_ttyACM0 = AlarmListObject()
|
||||
satellite_alarm_ttyACM0.set_alarm_id("100.119")
|
||||
satellite_alarm_ttyACM0.set_reason_text(f"controller-0 GNSS satellite count below threshold state: satellite count {get_satellite_count_ttyACM0} \(expected: >= 150\)")
|
||||
satellite_alarm_ttyACM0.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-satellite-count")
|
||||
expected_alarms.append(satellite_alarm_ttyACM0)
|
||||
|
||||
get_logger().log_info(f"ttyACM0 signal quality {get_signal_quality_max_ttyACM0} < 300, expecting signal quality alarm")
|
||||
signal_quality_alarm_ttyACM0 = AlarmListObject()
|
||||
signal_quality_alarm_ttyACM0.set_alarm_id("100.119")
|
||||
signal_quality_alarm_ttyACM0.set_reason_text(r"controller-0 GNSS signal quality db below threshold state: signal_quality_db [\d\.]+\s+\(expected: >= 300.0\)")
|
||||
signal_quality_alarm_ttyACM0.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-signal-quality-db")
|
||||
expected_alarms.append(signal_quality_alarm_ttyACM0)
|
||||
|
||||
# Always expect signal loss alarm for gnssx
|
||||
signal_loss_alarm = AlarmListObject()
|
||||
signal_loss_alarm.set_alarm_id("100.119")
|
||||
signal_loss_alarm.set_reason_text("controller-0 GNSS signal loss state: signal lock False \(expected: True\)")
|
||||
signal_loss_alarm.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/gnssx.ptp=GNSS-signal-loss")
|
||||
expected_alarms.append(signal_loss_alarm)
|
||||
|
||||
get_logger().log_info(f"Expecting {len(expected_alarms)} alarms based on current conditions")
|
||||
|
||||
# Wait for expected alarms to appear
|
||||
alarm_keywords.set_timeout_in_seconds(180)
|
||||
alarm_keywords.wait_for_alarms_to_appear(expected_alarms)
|
||||
get_logger().log_info("All expected alarms appeared successfully")
|
||||
|
||||
get_logger().log_test_case_step("Validate that only expected alarms are present")
|
||||
all_alarms = alarm_keywords.alarm_list()
|
||||
gnss_alarms = [alarm for alarm in all_alarms if "100.119" in alarm.get_alarm_id()]
|
||||
validate_equals(len(gnss_alarms), len(expected_alarms), "Number of GNSS alarms should match expected count")
|
||||
|
||||
|
||||
@mark.p0
|
||||
@mark.lab_has_gnr_d
|
||||
def test_gnss_monitoring_satellite_count_alarm(request) -> None:
|
||||
"""Test GNSS monitoring satellite count alarm generation and clearing.
|
||||
|
||||
This test verifies that satellite count alarms are properly raised when
|
||||
the threshold is set above current satellite count and cleared when
|
||||
the threshold is lowered below current count.
|
||||
|
||||
Args:
|
||||
request (pytest.FixtureRequest): Pytest request fixture for test cleanup.
|
||||
|
||||
Test Steps:
|
||||
1. Create monitoring instance with high satellite threshold
|
||||
2. Wait for satellite count alarm to appear
|
||||
3. Lower threshold and verify alarm clears
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
ptp_instance_keywords = SystemPTPInstanceKeywords(ssh_connection)
|
||||
ptp_parameter_keywords = SystemPTPInstanceParameterKeywords(ssh_connection)
|
||||
host_ptp_instance_keywords = SystemHostPTPInstanceKeywords(ssh_connection)
|
||||
gnss_monitoring_keywords = GnssMonitoringKeywords(ssh_connection)
|
||||
|
||||
get_logger().log_setup_step("Creating monitoring instance with high satellite threshold")
|
||||
gnss_monitoring_keywords.create_monitoring_instance("test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "satellite_count=15")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'devices="/dev/ttyACM0"')
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_assign("controller-0", "test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
|
||||
get_logger().log_setup_step("Get current satellite count for /dev/ttyACM0 device")
|
||||
get_gnss_monitoring_data = gnss_monitoring_keywords.get_gnss_monitoring_data("/dev/ttyACM0")
|
||||
get_satellite_count = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_satellite_count()
|
||||
get_logger().log_info(f"Current GNSS satellite count for /dev/ttyACM0 device: {get_satellite_count}")
|
||||
|
||||
# Increasing satellite count to trigger alarm - ensure it's always higher than current
|
||||
if get_satellite_count > 15:
|
||||
satellite_count = get_satellite_count + 15
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete("test-monitor", "satellite_count=15")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", f"satellite_count={satellite_count}")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
else:
|
||||
satellite_count = get_satellite_count
|
||||
|
||||
# Calculate lowering satellite threshold to clear alarm - must be less than current count
|
||||
lowering_satellite_count = max(0, get_satellite_count // 2)
|
||||
get_logger().log_info(f"Will lower satellite threshold to {lowering_satellite_count} to clear alarm")
|
||||
|
||||
def cleanup_monitoring_instance():
|
||||
"""Clean up GNSS monitoring instance."""
|
||||
get_logger().log_teardown_step("Cleaning up GNSS monitoring instance")
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_remove_with_error("controller-0", "test-monitor")
|
||||
if lowering_satellite_count is not None:
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", f"satellite_count={lowering_satellite_count}")
|
||||
else:
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", f"satellite_count={satellite_count}")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'devices="/dev/ttyACM0"')
|
||||
ptp_instance_keywords.system_ptp_instance_delete_with_error("test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_inactive()
|
||||
|
||||
request.addfinalizer(cleanup_monitoring_instance)
|
||||
|
||||
get_logger().log_test_case_step("Waiting for satellite count alarm to appear")
|
||||
satellite_alarm = AlarmListObject()
|
||||
satellite_alarm.set_alarm_id("100.119")
|
||||
satellite_alarm.set_reason_text(f"controller-0 GNSS satellite count below threshold state: satellite count {get_satellite_count} \(expected: >= {satellite_count}\)")
|
||||
satellite_alarm.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-satellite-count")
|
||||
|
||||
alarm_keywords = AlarmListKeywords(ssh_connection)
|
||||
alarm_keywords.set_timeout_in_seconds(240)
|
||||
alarm_keywords.wait_for_alarms_to_appear([satellite_alarm])
|
||||
|
||||
get_logger().log_test_case_step("Lowering satellite threshold to clear alarm")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete("test-monitor", f"satellite_count={satellite_count}")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", f"satellite_count={lowering_satellite_count}")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
|
||||
get_logger().log_test_case_step("Waiting for alarm to clear")
|
||||
lowering_satellite_alarm = AlarmListObject()
|
||||
lowering_satellite_alarm.set_alarm_id("100.119")
|
||||
lowering_satellite_alarm.set_reason_text(f"controller-0 GNSS satellite count below threshold state: satellite count {get_satellite_count} \(expected: >= {lowering_satellite_count}\)")
|
||||
lowering_satellite_alarm.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-satellite-count")
|
||||
alarm_keywords.set_timeout_in_seconds(240)
|
||||
alarm_keywords.wait_for_alarms_cleared([satellite_alarm, lowering_satellite_alarm])
|
||||
|
||||
|
||||
@mark.p0
|
||||
@mark.lab_has_gnr_d
|
||||
def test_gnss_monitoring_signal_quality_alarm(request) -> None:
|
||||
"""Test GNSS monitoring signal quality alarm generation and clearing.
|
||||
|
||||
This test verifies that signal quality alarms are properly raised when
|
||||
the threshold is set above current signal quality and cleared when
|
||||
the threshold is lowered below current quality.
|
||||
|
||||
Args:
|
||||
request (pytest.FixtureRequest): Pytest request fixture for test cleanup registration.
|
||||
|
||||
Test Steps:
|
||||
1. Create monitoring instance with high signal quality threshold
|
||||
2. Wait for signal quality alarm to appear
|
||||
3. Lower threshold and verify alarm clears
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
ptp_instance_keywords = SystemPTPInstanceKeywords(ssh_connection)
|
||||
ptp_parameter_keywords = SystemPTPInstanceParameterKeywords(ssh_connection)
|
||||
host_ptp_instance_keywords = SystemHostPTPInstanceKeywords(ssh_connection)
|
||||
gnss_monitoring_keywords = GnssMonitoringKeywords(ssh_connection)
|
||||
|
||||
get_logger().log_setup_step("Creating monitoring instance with high signal quality threshold")
|
||||
gnss_monitoring_keywords.create_monitoring_instance("test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'devices="/dev/ttyACM0"')
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_assign("controller-0", "test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
|
||||
get_logger().log_setup_step("Get current GNSS signal quality for /dev/ttyACM0 device")
|
||||
get_gnss_monitoring_data = gnss_monitoring_keywords.get_gnss_monitoring_data("/dev/ttyACM0")
|
||||
get_signal_quality_max = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_signal_quality_max()
|
||||
get_logger().log_info(f"Current GNSS signal quality for /dev/ttyACM0 device: {get_signal_quality_max}")
|
||||
|
||||
# Increasing signal quality db to trigger alarm - ensure it's always higher than current
|
||||
if get_signal_quality_max > 30:
|
||||
signal_quality_db = get_signal_quality_max + 30
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", f"signal_quality_db={signal_quality_db}")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
else:
|
||||
signal_quality_db = get_signal_quality_max
|
||||
|
||||
# Calculate lowering signal quality db threshold to clear alarm - must be less than current count
|
||||
lowering_signal_quality_db = max(0, get_signal_quality_max // 2)
|
||||
get_logger().log_info(f"Will lower signal quality db threshold to {lowering_signal_quality_db} to clear alarm")
|
||||
|
||||
def cleanup_monitoring_instance():
|
||||
"""Clean up GNSS monitoring instance."""
|
||||
get_logger().log_teardown_step("Cleaning up GNSS monitoring instance")
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_remove_with_error("controller-0", "test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "satellite_count=8")
|
||||
if lowering_signal_quality_db is not None:
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", f"signal_quality_db={lowering_signal_quality_db}")
|
||||
else:
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", f"signal_quality_db={signal_quality_db}")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'devices="/dev/ttyACM0"')
|
||||
ptp_instance_keywords.system_ptp_instance_delete_with_error("test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_inactive()
|
||||
|
||||
request.addfinalizer(cleanup_monitoring_instance)
|
||||
|
||||
get_logger().log_test_case_step("Waiting for signal quality alarm to appear")
|
||||
signal_quality_alarm = AlarmListObject()
|
||||
signal_quality_alarm.set_alarm_id("100.119")
|
||||
signal_quality_alarm.set_reason_text(r"controller-0 GNSS signal quality db below threshold state: signal_quality_db [\d\.]+\s+\(expected: >= [\d\.]+\)")
|
||||
signal_quality_alarm.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-signal-quality-db")
|
||||
|
||||
alarm_keywords = AlarmListKeywords(ssh_connection)
|
||||
alarm_keywords.set_timeout_in_seconds(240)
|
||||
alarm_keywords.wait_for_alarms_to_appear([signal_quality_alarm])
|
||||
|
||||
get_logger().log_test_case_step("Lowering signal quality threshold to clear alarm")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete("test-monitor", f"signal_quality_db={signal_quality_db}")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", f"signal_quality_db={lowering_signal_quality_db}")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
|
||||
get_logger().log_test_case_step("Waiting for alarm to clear")
|
||||
alarm_keywords.set_timeout_in_seconds(240)
|
||||
alarm_keywords.wait_for_alarms_cleared([signal_quality_alarm])
|
||||
|
||||
|
||||
@mark.p1
|
||||
@mark.lab_has_gnr_d
|
||||
def test_gnss_monitoring_parameter_updates(request) -> None:
|
||||
"""Test dynamic parameter updates and reconfiguration of GNSS monitoring.
|
||||
|
||||
This test verifies that monitoring parameters can be updated dynamically
|
||||
and that the changes are properly applied to the running configuration.
|
||||
|
||||
Args:
|
||||
request (pytest.FixtureRequest): Pytest request fixture for test cleanup registration.
|
||||
|
||||
Test Steps:
|
||||
1. Create monitoring instance with initial parameters
|
||||
2. Update parameters to new values
|
||||
3. Verify updated configuration and alarm conditions
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
ptp_instance_keywords = SystemPTPInstanceKeywords(ssh_connection)
|
||||
gnss_monitoring_keywords = GnssMonitoringKeywords(ssh_connection)
|
||||
ptp_parameter_keywords = SystemPTPInstanceParameterKeywords(ssh_connection)
|
||||
host_ptp_instance_keywords = SystemHostPTPInstanceKeywords(ssh_connection)
|
||||
alarm_keywords = AlarmListKeywords(ssh_connection)
|
||||
|
||||
def cleanup_monitoring_instance():
|
||||
"""Clean up GNSS monitoring instance."""
|
||||
get_logger().log_teardown_step("Cleaning up GNSS monitoring instance")
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_remove_with_error("controller-0", "test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "satellite_count=150")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "signal_quality_db=300")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'devices="/dev/ttyACM0"')
|
||||
ptp_instance_keywords.system_ptp_instance_delete_with_error("test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_inactive()
|
||||
|
||||
request.addfinalizer(cleanup_monitoring_instance)
|
||||
|
||||
get_logger().log_setup_step("Creating monitoring instance with initial parameters")
|
||||
gnss_monitoring_keywords.create_monitoring_instance("test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'devices="/dev/ttyACM0"')
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_assign("controller-0", "test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
|
||||
get_logger().log_setup_step("Verifying initial configuration")
|
||||
gnss_monitoring_keywords.verify_monitoring_configuration_file(8, 30, "/dev/ttyACM0")
|
||||
|
||||
get_logger().log_test_case_step("Updating ptp instance parameters")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete("test-monitor", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "satellite_count=150")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "signal_quality_db=300")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
|
||||
get_logger().log_test_case_step("Waiting for updated configuration")
|
||||
gnss_monitoring_keywords.wait_for_monitoring_configuration_file(150, 300, "/dev/ttyACM0")
|
||||
|
||||
get_logger().log_test_case_step("Testing GNSS data through PTY")
|
||||
gnss_monitoring_keywords.verify_gnss_pty_data("/dev/ttyACM0")
|
||||
|
||||
get_logger().log_test_case_step("Get current satellite count and signal quality for /dev/ttyACM0")
|
||||
get_gnss_monitoring_data = gnss_monitoring_keywords.get_gnss_monitoring_data("/dev/ttyACM0")
|
||||
get_satellite_count = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_satellite_count()
|
||||
get_signal_quality_max = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_signal_quality_max()
|
||||
get_logger().log_info(f"Current GNSS satellite count for /dev/ttyACM0: {get_satellite_count}")
|
||||
get_logger().log_info(f"Current GNSS signal quality for /dev/ttyACM0: {get_signal_quality_max}")
|
||||
|
||||
get_logger().log_test_case_step("Verifying alarm conditions")
|
||||
expected_alarms = []
|
||||
get_logger().log_info(f"ttyACM0 satellite count {get_satellite_count} < 150, expecting satellite alarm")
|
||||
satellite_alarm = AlarmListObject()
|
||||
satellite_alarm.set_alarm_id("100.119")
|
||||
satellite_alarm.set_reason_text(f"controller-0 GNSS satellite count below threshold state: satellite count {get_satellite_count} \(expected: >= 150\)")
|
||||
satellite_alarm.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-satellite-count")
|
||||
expected_alarms.append(satellite_alarm)
|
||||
|
||||
get_logger().log_info(f"ttyACM0 signal quality {get_signal_quality_max} < 300, expecting signal quality alarm")
|
||||
signal_quality_alarm = AlarmListObject()
|
||||
signal_quality_alarm.set_alarm_id("100.119")
|
||||
signal_quality_alarm.set_reason_text(r"controller-0 GNSS signal quality db below threshold state: signal_quality_db [\d\.]+\s+\(expected: >= [\d\.]+\)")
|
||||
signal_quality_alarm.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-signal-quality-db")
|
||||
expected_alarms.append(signal_quality_alarm)
|
||||
|
||||
# Wait for expected alarms to appear
|
||||
alarm_keywords.set_timeout_in_seconds(240)
|
||||
alarm_keywords.wait_for_alarms_to_appear(expected_alarms)
|
||||
get_logger().log_info("All expected alarms appeared successfully")
|
||||
|
||||
# Validate that only expected alarms are present
|
||||
all_alarms = alarm_keywords.alarm_list()
|
||||
gnss_alarms = [alarm for alarm in all_alarms if "100.119" in alarm.get_alarm_id()]
|
||||
validate_equals(len(gnss_alarms), len(expected_alarms), "Number of GNSS alarms should match expected count")
|
||||
|
||||
|
||||
@mark.p1
|
||||
@mark.lab_has_gnr_d
|
||||
def test_gnss_monitoring_persistence_after_reboot(request) -> None:
|
||||
"""Test GNSS monitoring persistence after host operations.
|
||||
|
||||
This test verifies that GNSS monitoring configuration and functionality
|
||||
persist through host lock/unlock operations and system reboots.
|
||||
|
||||
Args:
|
||||
request (pytest.FixtureRequest): Pytest request fixture for test cleanup registration.
|
||||
|
||||
Test Steps:
|
||||
1. Create and configure GNSS monitoring instance
|
||||
2. Perform host lock/unlock operations
|
||||
3. Perform system reboot
|
||||
4. Verify monitoring persists after operations
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
ptp_instance_keywords = SystemPTPInstanceKeywords(ssh_connection)
|
||||
gnss_monitoring_keywords = GnssMonitoringKeywords(ssh_connection)
|
||||
ptp_parameter_keywords = SystemPTPInstanceParameterKeywords(ssh_connection)
|
||||
host_ptp_instance_keywords = SystemHostPTPInstanceKeywords(ssh_connection)
|
||||
alarm_keywords = AlarmListKeywords(ssh_connection)
|
||||
file_keywords = FileKeywords(ssh_connection)
|
||||
|
||||
def cleanup_monitoring_instance():
|
||||
"""Clean up GNSS monitoring instance."""
|
||||
get_logger().log_teardown_step("Cleaning up GNSS monitoring instance")
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_remove_with_error("controller-0", "test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "satellite_count=300")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "signal_quality_db=600")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'devices="/dev/ttyACM0"')
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'cmdline_opts="-D 7"')
|
||||
ptp_instance_keywords.system_ptp_instance_delete_with_error("test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_inactive()
|
||||
|
||||
request.addfinalizer(cleanup_monitoring_instance)
|
||||
|
||||
get_logger().log_setup_step("Creating monitoring instance")
|
||||
gnss_monitoring_keywords.create_monitoring_instance("test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "satellite_count=300")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "signal_quality_db=600")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'devices="/dev/ttyACM0"')
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_assign("controller-0", "test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
|
||||
get_logger().log_setup_step("Verifying GNSS monitor configuration file")
|
||||
gnss_monitoring_keywords.verify_monitoring_configuration_file(300, 600, "/dev/ttyACM0")
|
||||
|
||||
get_logger().log_test_case_step("Verifying PTY devices created")
|
||||
gnss_monitoring_keywords.verify_pty_device_exists("/dev/ttyACM0", True)
|
||||
|
||||
get_logger().log_setup_step("Testing GNSS data through PTY")
|
||||
gnss_monitoring_keywords.verify_gnss_pty_data("/dev/ttyACM0")
|
||||
|
||||
get_logger().log_setup_step("Checking current satellite count and signal quality for /dev/ttyACM0")
|
||||
get_gnss_monitoring_data = gnss_monitoring_keywords.get_gnss_monitoring_data("/dev/ttyACM0")
|
||||
get_satellite_count = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_satellite_count()
|
||||
get_signal_quality_max = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_signal_quality_max()
|
||||
get_logger().log_info(f"Current GNSS satellite count for /dev/ttyACM0: {get_satellite_count}")
|
||||
get_logger().log_info(f"Current GNSS signal quality for /dev/ttyACM0: {get_signal_quality_max}")
|
||||
|
||||
get_logger().log_setup_step("Checking for expected alarms")
|
||||
expected_alarms = []
|
||||
get_logger().log_info(f"satellite count {get_satellite_count} < 300, expecting satellite alarm")
|
||||
satellite_alarm = AlarmListObject()
|
||||
satellite_alarm.set_alarm_id("100.119")
|
||||
satellite_alarm.set_reason_text(r"controller-0 GNSS satellite count below threshold state: satellite count [\d]+\s+\(expected: >= 300\)")
|
||||
satellite_alarm.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-satellite-count")
|
||||
expected_alarms.append(satellite_alarm)
|
||||
|
||||
get_logger().log_info(f"ttyACM0 signal quality {get_signal_quality_max} < 600, expecting signal quality alarm")
|
||||
signal_quality_alarm = AlarmListObject()
|
||||
signal_quality_alarm.set_alarm_id("100.119")
|
||||
signal_quality_alarm.set_reason_text(r"controller-0 GNSS signal quality db below threshold state: signal_quality_db [\d\.]+\s+\(expected: >= [\d\.]+\)")
|
||||
signal_quality_alarm.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-signal-quality-db")
|
||||
expected_alarms.append(signal_quality_alarm)
|
||||
|
||||
# Wait for expected alarms to appear
|
||||
alarm_keywords.set_timeout_in_seconds(180)
|
||||
alarm_keywords.wait_for_alarms_to_appear(expected_alarms)
|
||||
get_logger().log_info("All expected alarms appeared successfully")
|
||||
|
||||
get_logger().log_test_case_step("Lock and unlock host")
|
||||
lock_keywords = SystemHostLockKeywords(ssh_connection)
|
||||
lock_success = lock_keywords.lock_host("controller-0")
|
||||
validate_equals(lock_success, True, "Controller should lock successfully")
|
||||
|
||||
unlock_success = lock_keywords.unlock_host("controller-0")
|
||||
validate_equals(unlock_success, True, "Controller should unlock successfully")
|
||||
|
||||
get_logger().log_test_case_step("Verifying monitoring instance persists after lock and unlock")
|
||||
get_host_ptp_instance_for_name = host_ptp_instance_keywords.get_system_host_ptp_instance_list("controller-0").get_host_ptp_instance_for_name("test-monitor")
|
||||
validate_equals(get_host_ptp_instance_for_name.get_name(), "test-monitor", "Monitoring instance should persist after lock and unlock")
|
||||
|
||||
get_logger().log_test_case_step("Verifying GNSS monitor configuration file after lock and unlock")
|
||||
config_exists = file_keywords.file_exists("/etc/linuxptp/ptpinstance/gnss-monitor-ptp.conf")
|
||||
validate_equals(config_exists, True, "Configuration file should exist")
|
||||
gnss_monitoring_keywords.verify_monitoring_configuration_file(300, 600, "/dev/ttyACM0")
|
||||
|
||||
get_logger().log_test_case_step("Checking system services after lock and unlock")
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
|
||||
get_logger().log_test_case_step("Verifying PTY devices created")
|
||||
gnss_monitoring_keywords.verify_pty_device_exists("/dev/ttyACM0", True)
|
||||
|
||||
get_logger().log_test_case_step("Testing GNSS data through PTY after lock and unlock")
|
||||
gnss_monitoring_keywords.verify_gnss_pty_data("/dev/ttyACM0")
|
||||
|
||||
get_logger().log_test_case_step("Checking current satellite count and signal quality for /dev/ttyACM0 after lock and unlock")
|
||||
get_gnss_monitoring_data = gnss_monitoring_keywords.get_gnss_monitoring_data("/dev/ttyACM0")
|
||||
get_satellite_count = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_satellite_count()
|
||||
get_signal_quality_max = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_signal_quality_max()
|
||||
get_logger().log_info(f"Current GNSS satellite count for /dev/ttyACM0 : {get_satellite_count}")
|
||||
get_logger().log_info(f"Current GNSS signal quality for /dev/ttyACM0 : {get_signal_quality_max}")
|
||||
|
||||
get_logger().log_test_case_step("Checking for expected alarms after lock and unlock")
|
||||
alarm_keywords.wait_for_alarms_to_appear(expected_alarms)
|
||||
get_logger().log_info("All expected alarms appeared successfully")
|
||||
|
||||
# Validate that only expected alarms are present
|
||||
all_alarms = alarm_keywords.alarm_list()
|
||||
gnss_alarms = [alarm for alarm in all_alarms if "100.119" in alarm.get_alarm_id()]
|
||||
validate_equals(len(gnss_alarms), len(expected_alarms), "Number of GNSS alarms should match expected count")
|
||||
|
||||
get_logger().log_test_case_step("Reboot host")
|
||||
# force reboot the active controller
|
||||
# get the prev uptime of the host so we can be sure it re-started
|
||||
pre_uptime_of_host = SystemHostListKeywords(ssh_connection).get_uptime("controller-0")
|
||||
ssh_connection.send_as_sudo("sudo reboot -f")
|
||||
reboot_success = SystemHostRebootKeywords(ssh_connection).wait_for_force_reboot("controller-0", pre_uptime_of_host)
|
||||
validate_equals(reboot_success, True, "Controller should reboot successfully")
|
||||
|
||||
get_logger().log_test_case_step("Verifying monitoring instance persists after reboot")
|
||||
get_host_ptp_instance_for_name = host_ptp_instance_keywords.get_system_host_ptp_instance_list("controller-0").get_host_ptp_instance_for_name("test-monitor")
|
||||
validate_equals(get_host_ptp_instance_for_name.get_name(), "test-monitor", "Monitoring instance should persist after reboot")
|
||||
|
||||
get_logger().log_test_case_step("Verifying GNSS monitor configuration file after reboot")
|
||||
gnss_monitoring_keywords.verify_monitoring_configuration_file(300, 600, "/dev/ttyACM0")
|
||||
|
||||
get_logger().log_test_case_step("Checking system services after reboot")
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
|
||||
get_logger().log_test_case_step("Verifying PTY devices created")
|
||||
gnss_monitoring_keywords.verify_pty_device_exists("/dev/ttyACM0", True)
|
||||
|
||||
get_logger().log_test_case_step("Testing GNSS data through PTY after reboot")
|
||||
gnss_monitoring_keywords.verify_gnss_pty_data("/dev/ttyACM0")
|
||||
|
||||
get_logger().log_test_case_step("Checking current satellite count and signal quality for /dev/ttyACM0 after reboot")
|
||||
get_gnss_monitoring_data = gnss_monitoring_keywords.get_gnss_monitoring_data("/dev/ttyACM0")
|
||||
get_satellite_count = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_satellite_count()
|
||||
get_signal_quality_max = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_signal_quality_max()
|
||||
get_logger().log_info(f"Current GNSS satellite count for /dev/ttyACM0 : {get_satellite_count}")
|
||||
get_logger().log_info(f"Current GNSS signal quality for /dev/ttyACM0 : {get_signal_quality_max}")
|
||||
|
||||
get_logger().log_test_case_step("Checking for expected alarms after reboot")
|
||||
# Wait for expected alarms to appear
|
||||
alarm_keywords.set_timeout_in_seconds(180)
|
||||
alarm_keywords.wait_for_alarms_to_appear(expected_alarms)
|
||||
get_logger().log_info("All expected alarms appeared successfully")
|
||||
|
||||
# Validate that only expected alarms are present
|
||||
all_alarms = alarm_keywords.alarm_list()
|
||||
gnss_alarms = [alarm for alarm in all_alarms if "100.119" in alarm.get_alarm_id()]
|
||||
validate_equals(len(gnss_alarms), len(expected_alarms), "Number of GNSS alarms should match expected count")
|
||||
|
||||
|
||||
@mark.p0
|
||||
@mark.lab_has_gnr_d
|
||||
def test_gnss_monitoring_instance_removal(request):
|
||||
"""
|
||||
GNSS Monitoring Instance Removal
|
||||
|
||||
Verify complete cleanup when removing GNSS monitoring instance.
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
ptp_parameter_keywords = SystemPTPInstanceParameterKeywords(ssh_connection)
|
||||
gnss_monitoring_keywords = GnssMonitoringKeywords(ssh_connection)
|
||||
ptp_instance_keywords = SystemPTPInstanceKeywords(ssh_connection)
|
||||
host_ptp_instance_keywords = SystemHostPTPInstanceKeywords(ssh_connection)
|
||||
alarm_keywords = AlarmListKeywords(ssh_connection)
|
||||
|
||||
get_logger().log_setup_step("Creating monitoring instance")
|
||||
gnss_monitoring_keywords.create_monitoring_instance("test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'devices="/dev/ttyACM0"')
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_assign("controller-0", "test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0"])
|
||||
|
||||
gnss_monitoring_keywords.verify_pty_device_exists("/dev/ttyACM0", True)
|
||||
|
||||
get_logger().log_test_case_step("Removing instance from host")
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_remove("controller-0", "test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_inactive()
|
||||
|
||||
gnss_monitoring_keywords.verify_pty_device_exists("/dev/ttyACM0", False)
|
||||
|
||||
get_logger().log_test_case_step("Waiting for alarm to clear")
|
||||
alarm_keywords.set_timeout_in_seconds(180)
|
||||
ptp_alarm = AlarmListObject()
|
||||
ptp_alarm.set_alarm_id("100.119")
|
||||
alarm_keywords.wait_for_alarms_cleared([ptp_alarm])
|
||||
|
||||
get_logger().log_test_case_step("Cleaning up GNSS monitoring instance")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'devices="/dev/ttyACM0"')
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'cmdline_opts="-D 7"')
|
||||
ptp_instance_keywords.system_ptp_instance_delete_with_error("test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_inactive()
|
||||
|
||||
error_message = ptp_instance_keywords.get_system_ptp_instance_show_with_error("test-monitor")
|
||||
validate_str_contains(error_message, "PTP instance not found: test-monitor", "Error message for non-existent instance")
|
||||
|
||||
get_logger().log_test_case_step("Waiting for alarm to clear")
|
||||
alarm_keywords.set_timeout_in_seconds(180)
|
||||
alarm_keywords.wait_for_alarms_cleared([ptp_alarm])
|
||||
|
||||
get_logger().log_test_case_step("Verify PTY devices removed")
|
||||
gnss_monitoring_keywords.verify_pty_device_exists("/dev/ttyACM0", False)
|
||||
get_logger().log_info("PTY devices cleaned up")
|
||||
|
||||
get_logger().log_test_case_step("Verify configuration file removed")
|
||||
config_file_check = ssh_connection.send("ls /etc/linuxptp/ptpinstance/gnss-monitor-ptp.conf 2>/dev/null || echo 'not found'")
|
||||
config_file_check_str = "\n".join(config_file_check) if isinstance(config_file_check, list) else config_file_check
|
||||
validate_str_contains(config_file_check_str, "not found", "Check: /etc/linuxptp/ptpinstance/gnss-monitor-ptp.conf does not exist")
|
||||
get_logger().log_info("Configuration files removed")
|
||||
|
||||
get_logger().log_test_case_step("Verify ts2phc configuration reverted for nmea_serialport")
|
||||
gnss_monitoring_keywords.verify_ts2phc_config_serialport("ts1", "/dev/ttyACM0")
|
||||
|
||||
|
||||
@mark.p1
|
||||
@mark.lab_has_gnr_d
|
||||
def test_gnss_monitoring_single_instance_per_host(request):
|
||||
"""
|
||||
Verify that only one PTP instance is allowed per host and appropriate error handling when attempting to assign multiple instances
|
||||
|
||||
Test steps:
|
||||
1) Ensure existing GNSS monitor instance is assigned
|
||||
2) Create a second PTP instance
|
||||
3) Attempt to assign second instance to same host - should fail
|
||||
4) Confirm only original instance remains active
|
||||
5) Clean up second instance
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
ptp_instance_keywords = SystemPTPInstanceKeywords(ssh_connection)
|
||||
ptp_parameter_keywords = SystemPTPInstanceParameterKeywords(ssh_connection)
|
||||
host_ptp_instance_keywords = SystemHostPTPInstanceKeywords(ssh_connection)
|
||||
gnss_monitoring_keywords = GnssMonitoringKeywords(ssh_connection)
|
||||
|
||||
def cleanup_monitoring_instances():
|
||||
"""Clean up GNSS monitoring instances."""
|
||||
get_logger().log_test_case_step("Cleaning up second instance")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor-2", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor-2", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor-2", 'devices="/dev/ttyACM0 /dev/gnssx"')
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor-2", 'cmdline_opts="-D 7"')
|
||||
ptp_instance_keywords.system_ptp_instance_delete_with_error("test-monitor-2")
|
||||
|
||||
get_logger().log_teardown_step("Cleaning up GNSS monitoring instances")
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_remove_with_error("controller-0", "test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'devices="/dev/ttyACM0 /dev/gnssx"')
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'cmdline_opts="-D 7"')
|
||||
ptp_instance_keywords.system_ptp_instance_delete_with_error("test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_inactive()
|
||||
|
||||
request.addfinalizer(cleanup_monitoring_instances)
|
||||
|
||||
get_logger().log_test_case_step("Creating first GNSS monitoring instance")
|
||||
gnss_monitoring_keywords.create_monitoring_instance("test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'devices="/dev/ttyACM0 /dev/gnssx"')
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'cmdline_opts="-D 7"')
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_assign("controller-0", "test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0", "/dev/gnssx"])
|
||||
|
||||
get_logger().log_test_case_step("Verifying first instance assigned successfully")
|
||||
get_host_ptp_instance_for_name = host_ptp_instance_keywords.get_system_host_ptp_instance_list("controller-0").get_host_ptp_instance_for_name("test-monitor")
|
||||
validate_equals(get_host_ptp_instance_for_name.get_name(), "test-monitor", "First instance should be assigned")
|
||||
|
||||
get_logger().log_test_case_step("Creating second PTP instance")
|
||||
gnss_monitoring_keywords.create_monitoring_instance("test-monitor-2")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor-2", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor-2", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor-2", 'devices="/dev/ttyACM0 /dev/gnssx"')
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor-2", 'cmdline_opts="-D 7"')
|
||||
|
||||
get_logger().log_test_case_step("Attempting to assign second instance to same host - should fail")
|
||||
error_message = host_ptp_instance_keywords.system_host_ptp_instance_assign_with_error("controller-0", "test-monitor-2")
|
||||
validate_str_contains(error_message, "gnss-monitor ptp instance already exists on host", "Should get error about existing gnss-monitor instance")
|
||||
|
||||
get_logger().log_test_case_step("Confirming only original instance remains active")
|
||||
gnss_monitoring_instance = ptp_instance_keywords.get_system_ptp_instance_show("test-monitor")
|
||||
validate_equals(gnss_monitoring_instance.system_ptp_instance_object.get_name(), "test-monitor", "Original instance should remain")
|
||||
|
||||
|
||||
@mark.p0
|
||||
@mark.lab_has_gnr_d
|
||||
def test_gnss_monitoring_threshold_alarm_verification(request):
|
||||
"""
|
||||
Verify satellite count and signal quality thresholds trigger appropriate alarms when breached
|
||||
|
||||
Test Steps:
|
||||
1) Check current GNSS device metrics
|
||||
2) Set thresholds above current values
|
||||
3) Apply updated configuration
|
||||
4) Verify updated configuration file
|
||||
5) Check for threshold alarms
|
||||
6) Verify only valid device PTY exists
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
ptp_instance_keywords = SystemPTPInstanceKeywords(ssh_connection)
|
||||
ptp_parameter_keywords = SystemPTPInstanceParameterKeywords(ssh_connection)
|
||||
host_ptp_instance_keywords = SystemHostPTPInstanceKeywords(ssh_connection)
|
||||
gnss_monitoring_keywords = GnssMonitoringKeywords(ssh_connection)
|
||||
alarm_keywords = AlarmListKeywords(ssh_connection)
|
||||
|
||||
get_logger().log_setup_step("Creating GNSS monitor")
|
||||
gnss_monitoring_keywords.create_monitoring_instance("test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'devices="/dev/ttyACM0 /dev/gnssx"')
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", 'cmdline_opts="-D 7"')
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_assign("controller-0", "test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0", "/dev/gnssx"])
|
||||
|
||||
get_logger().log_setup_step("Checking current satellite count and signal quality for /dev/ttyACM0")
|
||||
get_gnss_monitoring_data = gnss_monitoring_keywords.get_gnss_monitoring_data("/dev/ttyACM0")
|
||||
get_satellite_count_ttyACM0 = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_satellite_count()
|
||||
get_signal_quality_max_ttyACM0 = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/ttyACM0").get_signal_quality_max()
|
||||
get_logger().log_info(f"Current GNSS satellite count for /dev/ttyACM0: {get_satellite_count_ttyACM0}")
|
||||
get_logger().log_info(f"Current GNSS signal quality for /dev/ttyACM0: {get_signal_quality_max_ttyACM0}")
|
||||
|
||||
get_logger().log_setup_step("Checking current satellite count and signal quality for /dev/gnssx")
|
||||
get_gnss_monitoring_data = gnss_monitoring_keywords.get_gnss_monitoring_data("/dev/gnssx")
|
||||
get_satellite_count_gnssx = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/gnssx").get_satellite_count()
|
||||
get_signal_quality_max_gnssx = get_gnss_monitoring_data.get_monitoring_data_for_device("/dev/gnssx").get_signal_quality_max()
|
||||
get_logger().log_info(f"Current GNSS satellite count for /dev/gnssx: {get_satellite_count_gnssx}")
|
||||
get_logger().log_info(f"Current GNSS signal quality for /dev/gnssx: {get_signal_quality_max_gnssx}")
|
||||
|
||||
# Set thresholds higher than both devices' current values
|
||||
satellite_count = max(get_satellite_count_gnssx + 30, get_satellite_count_ttyACM0 + 30)
|
||||
signal_quality_max = max(int(get_signal_quality_max_gnssx) + 50, int(get_signal_quality_max_ttyACM0) + 50)
|
||||
get_logger().log_info(f"Setting satellite_count threshold to: {satellite_count}")
|
||||
get_logger().log_info(f"Setting signal_quality_max threshold to: {signal_quality_max}")
|
||||
|
||||
def cleanup_monitoring_instance():
|
||||
"""Clean up GNSS monitoring instance."""
|
||||
get_logger().log_teardown_step("Cleaning up GNSS monitoring instance")
|
||||
host_ptp_instance_keywords.system_host_ptp_instance_remove_with_error("controller-0", "test-monitor")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", f"satellite_count={satellite_count}")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", f"signal_quality_db={signal_quality_max}")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'devices="/dev/ttyACM0 /dev/gnssx"')
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete_with_error("test-monitor", 'cmdline_opts="-D 7"')
|
||||
ptp_instance_keywords.system_ptp_instance_delete_with_error("test-monitor")
|
||||
ptp_instance_keywords.system_ptp_instance_apply()
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_inactive()
|
||||
|
||||
request.addfinalizer(cleanup_monitoring_instance)
|
||||
|
||||
get_logger().log_test_case_step("Set thresholds above current values")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete("test-monitor", "satellite_count=8")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_delete("test-monitor", "signal_quality_db=30")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", f"satellite_count={satellite_count}")
|
||||
ptp_parameter_keywords.system_ptp_instance_parameter_add("test-monitor", f"signal_quality_db={signal_quality_max}")
|
||||
system_ptp_instance_apply_output = ptp_instance_keywords.system_ptp_instance_apply()
|
||||
validate_equals(system_ptp_instance_apply_output, "Applying the PTP Instance configuration", "apply PTP instance configuration")
|
||||
gnss_monitoring_keywords.wait_for_monitoring_services_active(["/dev/ttyACM0", "/dev/gnssx"])
|
||||
|
||||
get_logger().log_test_case_step("Verify updated configuration file")
|
||||
gnss_monitoring_keywords.wait_for_monitoring_configuration_file(satellite_count, signal_quality_max, "/dev/ttyACM0 /dev/gnssx")
|
||||
|
||||
get_logger().log_test_case_step("Verifying alarm conditions")
|
||||
signal_loss_alarm = AlarmListObject()
|
||||
signal_loss_alarm.set_alarm_id("100.119")
|
||||
signal_loss_alarm.set_reason_text("controller-0 GNSS signal loss state: signal lock False \(expected: True\)")
|
||||
signal_loss_alarm.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/gnssx.ptp=GNSS-signal-loss")
|
||||
|
||||
satellite_alarm_gnssx = AlarmListObject()
|
||||
satellite_alarm_gnssx.set_alarm_id("100.119")
|
||||
satellite_alarm_gnssx.set_reason_text(r"controller-0 GNSS satellite count below threshold state: satellite count [\d]+\s+\(expected: >= [\d]+\)")
|
||||
satellite_alarm_gnssx.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/gnssx.ptp=GNSS-satellite-count")
|
||||
|
||||
signal_quality_alarm_gnssx = AlarmListObject()
|
||||
signal_quality_alarm_gnssx.set_alarm_id("100.119")
|
||||
signal_quality_alarm_gnssx.set_reason_text(r"controller-0 GNSS signal quality db below threshold state: signal_quality_db [\d\.]+\s+\(expected: >= [\d\.]+\)")
|
||||
signal_quality_alarm_gnssx.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/gnssx.ptp=GNSS-signal-quality-db")
|
||||
|
||||
satellite_alarm_ttyACM0 = AlarmListObject()
|
||||
satellite_alarm_ttyACM0.set_alarm_id("100.119")
|
||||
satellite_alarm_ttyACM0.set_reason_text(r"controller-0 GNSS satellite count below threshold state: satellite count [\d]+\s+\(expected: >= [\d]+\)")
|
||||
satellite_alarm_ttyACM0.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-satellite-count")
|
||||
|
||||
signal_quality_alarm_ttyACM0 = AlarmListObject()
|
||||
signal_quality_alarm_ttyACM0.set_alarm_id("100.119")
|
||||
signal_quality_alarm_ttyACM0.set_reason_text(r"controller-0 GNSS signal quality db below threshold state: signal_quality_db [\d\.]+\s+\(expected: >= [\d\.]+\)")
|
||||
signal_quality_alarm_ttyACM0.set_entity_id("host=controller-0.gnss-monitor=gnss-monitor-ptp.device_path=/dev/ttyACM0.ptp=GNSS-signal-quality-db")
|
||||
|
||||
alarm_keywords.set_timeout_in_seconds(180)
|
||||
alarm_keywords.wait_for_alarms_to_appear([signal_loss_alarm, satellite_alarm_gnssx, signal_quality_alarm_gnssx, satellite_alarm_ttyACM0, signal_quality_alarm_ttyACM0])
|
||||
get_logger().log_info("All expected alarms appeared successfully")
|
||||
|
||||
get_logger().log_test_case_step("Verify only valid device PTY exists")
|
||||
gnss_monitoring_keywords.verify_device_exists("/dev/ttyACM0.pty")
|
||||
gnss_monitoring_keywords.verify_device_exists("/dev/gnssx.pty")
|
||||
|
||||
get_logger().log_test_case_step("Verify GNSS data through PTY")
|
||||
gnss_monitoring_keywords.verify_gnss_pty_data("/dev/ttyACM0")
|
||||
@@ -39,6 +39,7 @@ markers=
|
||||
lab_rook_ceph: mark tests that require rook-ceph application applied
|
||||
lab_is_aio: mark labs without worker nodes
|
||||
lab_dell_storage: mark tests that require dell-storage application applied
|
||||
lab_has_gnr_d: mark tests that use specific lab with Granite Rapids-D GNSS
|
||||
#TODO: add 'lab_has_bmc_ipmi', 'lab_has_bmc_redfish', 'lab_has_bmc_dynamic', and 'lab_bmc_sensor'
|
||||
|
||||
|
||||
|
||||
65
unit_tests/parser/ptp/gnss_monitor_conf_parser_test.py
Normal file
65
unit_tests/parser/ptp/gnss_monitor_conf_parser_test.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""Unit tests for GnssMonitorConfParser."""
|
||||
|
||||
from keywords.ptp.cat.gnss_monitor_conf_parser import GnssMonitorConfParser
|
||||
|
||||
|
||||
def test_parse_gnss_monitor_config():
|
||||
"""Test parsing of GNSS monitor configuration output."""
|
||||
sample_output = ["[global]\n", "##\n", "## Default Data Set\n", "##\n", "devices /dev/ttyACM0 /dev/gnssx\n", "satellite_count 8\n", "signal_quality_db 30\n"]
|
||||
|
||||
parser = GnssMonitorConfParser(sample_output)
|
||||
values_dict = parser.get_output_values_dict()
|
||||
|
||||
assert values_dict["devices"] == "/dev/ttyACM0 /dev/gnssx"
|
||||
assert values_dict["satellite_count"] == "8"
|
||||
assert values_dict["signal_quality_db"] == "30"
|
||||
|
||||
|
||||
def test_parse_minimal_config():
|
||||
"""Test parsing minimal configuration."""
|
||||
minimal_output = ["[global]\n", "devices /dev/ttyACM0\n", "satellite_count 15\n", "signal_quality_db 40\n"]
|
||||
|
||||
parser = GnssMonitorConfParser(minimal_output)
|
||||
values_dict = parser.get_output_values_dict()
|
||||
|
||||
assert values_dict["devices"] == "/dev/ttyACM0"
|
||||
assert values_dict["satellite_count"] == "15"
|
||||
assert values_dict["signal_quality_db"] == "40"
|
||||
|
||||
|
||||
def test_parse_config_with_prompts():
|
||||
"""Test parsing configuration with command prompts and passwords."""
|
||||
output_with_prompts = ["~$ cat /etc/linuxptp/ptpinstance/gnss-monitor-ptp.conf\n", "[global]\n", "Password: \n", "devices /dev/ttyACM0\n", "satellite_count 10\n", "signal_quality_db 25\n"]
|
||||
|
||||
parser = GnssMonitorConfParser(output_with_prompts)
|
||||
values_dict = parser.get_output_values_dict()
|
||||
|
||||
# Should ignore prompts and passwords
|
||||
assert "~$" not in str(values_dict)
|
||||
assert "Password:" not in str(values_dict)
|
||||
|
||||
assert values_dict["devices"] == "/dev/ttyACM0"
|
||||
assert values_dict["satellite_count"] == "10"
|
||||
assert values_dict["signal_quality_db"] == "25"
|
||||
|
||||
|
||||
def test_parse_empty_config():
|
||||
"""Test parsing empty configuration."""
|
||||
empty_output = ["[global]\n", "##\n", "## Default Data Set\n", "##\n"]
|
||||
|
||||
parser = GnssMonitorConfParser(empty_output)
|
||||
values_dict = parser.get_output_values_dict()
|
||||
|
||||
assert len(values_dict) == 0
|
||||
|
||||
|
||||
def test_parse_config_with_spaces_in_values():
|
||||
"""Test parsing configuration with spaces in device values."""
|
||||
output_with_spaces = ["[global]\n", "devices /dev/ttyACM0 /dev/gnssx /dev/ttyUSB0\n", "satellite_count 12\n", "signal_quality_db 35\n"]
|
||||
|
||||
parser = GnssMonitorConfParser(output_with_spaces)
|
||||
values_dict = parser.get_output_values_dict()
|
||||
|
||||
assert values_dict["devices"] == "/dev/ttyACM0 /dev/gnssx /dev/ttyUSB0"
|
||||
assert values_dict["satellite_count"] == "12"
|
||||
assert values_dict["signal_quality_db"] == "35"
|
||||
Reference in New Issue
Block a user