Updated gnss power off and power on test cases
Change-Id: I9eec723890d1b4705a4d0b37157ccfb4fdcecd16 Signed-off-by: Guntaka Umashankar Reddy <umashankarguntaka.reddy@windriver.com>
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
from framework.validation.validation import validate_equals_with_retry
|
||||
from typing import Union
|
||||
|
||||
from framework.validation.validation import validate_equals_with_retry, validate_list_contains_with_retry
|
||||
from keywords.ptp.pmc.pmc_keywords import PMCKeywords
|
||||
|
||||
|
||||
@@ -52,13 +54,13 @@ class PTPReadinessKeywords:
|
||||
|
||||
validate_equals_with_retry(lambda: check_port_state_in_port_data_set(name), expected_port_states, "port state in port data set", 120, 30)
|
||||
|
||||
def wait_for_clock_class_appear_in_grandmaster_settings_np(self, name: str, expected_clock_class: int) -> None:
|
||||
def wait_for_clock_class_appear_in_grandmaster_settings_np(self, name: str, expected_clock_class: Union[int, list]) -> None:
|
||||
"""
|
||||
Waits until the clock class observed in the grandmaster settings np match the expected clock class, or times out.
|
||||
|
||||
Args:
|
||||
name (str): Name of the PTP instance.
|
||||
expected_clock_class (int): expected clock class to wait for.
|
||||
expected_clock_class (Union[int, list]): expected clock class to wait for.
|
||||
|
||||
Raises:
|
||||
Exception: If expected clock class do not appear within the timeout.
|
||||
@@ -84,15 +86,16 @@ class PTPReadinessKeywords:
|
||||
|
||||
return observed_clock_class
|
||||
|
||||
validate_equals_with_retry(lambda: get_clock_class_in_grandmaster_settings_np(name), expected_clock_class, "clock class in grandmaster settings np", 120, 30)
|
||||
exp_clock_class = expected_clock_class if isinstance(expected_clock_class, list) else [expected_clock_class]
|
||||
validate_list_contains_with_retry(lambda: get_clock_class_in_grandmaster_settings_np(name), exp_clock_class, "clock class in grandmaster settings np", 120, 30)
|
||||
|
||||
def wait_for_gm_clock_class_appear_in_parent_data_set(self, name: str, expected_gm_clock_class: int) -> None:
|
||||
def wait_for_gm_clock_class_appear_in_parent_data_set(self, name: str, expected_gm_clock_class: Union[int, list]) -> None:
|
||||
"""
|
||||
Waits until the gm clock class observed in the parent data set match the expected clock class, or times out.
|
||||
|
||||
Args:
|
||||
name (str): Name of the PTP instance.
|
||||
expected_gm_clock_class (int): expected gm clock class to wait for.
|
||||
expected_gm_clock_class (Union[int, list]): expected gm clock class to wait for.
|
||||
|
||||
Raises:
|
||||
Exception: If expected gm clock class do not appear within the timeout.
|
||||
@@ -118,4 +121,5 @@ class PTPReadinessKeywords:
|
||||
|
||||
return observed_gm_clock_class
|
||||
|
||||
validate_equals_with_retry(lambda: get_gm_clock_class_in_parent_data_set(name), expected_gm_clock_class, "gm clock class in parent data set", 120, 30)
|
||||
exp_gm_clock_class = expected_gm_clock_class if isinstance(expected_gm_clock_class, list) else [expected_gm_clock_class]
|
||||
validate_list_contains_with_retry(lambda: get_gm_clock_class_in_parent_data_set(name), exp_gm_clock_class, "gm clock class in parent data set", 120, 30)
|
||||
|
@@ -7,7 +7,6 @@ from keywords.base_keyword import BaseKeyword
|
||||
from keywords.cloud_platform.fault_management.alarms.alarm_list_keywords import AlarmListKeywords
|
||||
from keywords.cloud_platform.ssh.lab_connection_keywords import LabConnectionKeywords
|
||||
from keywords.cloud_platform.system.host.system_host_list_keywords import SystemHostListKeywords
|
||||
from keywords.linux.systemctl.systemctl_status_keywords import SystemCTLStatusKeywords
|
||||
from keywords.ptp.cat.cat_clock_conf_keywords import CatClockConfKeywords
|
||||
from keywords.ptp.cat.cat_ptp_cgu_keywords import CatPtpCguKeywords
|
||||
from keywords.ptp.cat.cat_ptp_config_keywords import CatPtpConfigKeywords
|
||||
@@ -504,7 +503,7 @@ class PTPVerifyConfigKeywords(BaseKeyword):
|
||||
ptp4l_expected_obj = self.ptp_setup.get_ptp4l_expected_by_name(name)
|
||||
expected_parent_data_set_obj = ptp4l_expected_obj.get_parent_data_set_for_hostname(hostname)
|
||||
|
||||
validate_equals(parent_data_set_obj.get_gm_clock_class(), expected_parent_data_set_obj.get_gm_clock_class(), "gm.ClockClass value within GET PARENT_DATA_SET")
|
||||
validate_list_contains(parent_data_set_obj.get_gm_clock_class(), expected_parent_data_set_obj.get_gm_clock_class(), "gm.ClockClass value within GET PARENT_DATA_SET")
|
||||
validate_equals(parent_data_set_obj.get_gm_clock_accuracy(), expected_parent_data_set_obj.get_gm_clock_accuracy(), "gm.ClockAccuracy value within GET PARENT_DATA_SET")
|
||||
validate_equals(parent_data_set_obj.get_gm_offset_scaled_log_variance(), expected_parent_data_set_obj.get_gm_offset_scaled_log_variance(), "gm.OffsetScaledLogVariance value within GET PARENT_DATA_SET")
|
||||
|
||||
@@ -626,7 +625,7 @@ class PTPVerifyConfigKeywords(BaseKeyword):
|
||||
expected_time_source = expected_grandmaster_settings_obj.get_time_source()
|
||||
expected_current_utc_offset_valid = expected_grandmaster_settings_obj.get_current_utc_offset_valid()
|
||||
|
||||
validate_equals(observed_clock_class, expected_clock_class, "clockClass value within GET GRANDMASTER_SETTINGS_NP")
|
||||
validate_list_contains(observed_clock_class, expected_clock_class, "clockClass value within GET GRANDMASTER_SETTINGS_NP")
|
||||
validate_equals(observed_clock_accuracy, expected_clock_accuracy, "clockAccuracy value within GET GRANDMASTER_SETTINGS_NP")
|
||||
validate_equals(observed_offset_scaled_log_variance, expected_offset_scaled_log_variance, "offsetScaledLogVariance value within GET GRANDMASTER_SETTINGS_NP")
|
||||
validate_equals(observed_current_utc_offset_valid, expected_current_utc_offset_valid, "currentUtcOffsetValid value within GET GRANDMASTER_SETTINGS_NP")
|
||||
|
@@ -112,12 +112,16 @@ class GnssKeywords(BaseKeyword):
|
||||
raise Exception(f"GPIO switch port not configured for {hostname} {nic}")
|
||||
|
||||
# Export GPIO pin if not already exported
|
||||
export_cmd = f"if [ ! -d /sys/class/gpio/gpio{gpio_switch_port} ]; then echo {gpio_switch_port} > /sys/class/gpio/export; fi"
|
||||
export_cmd = f"if [ ! -d /sys/class/gpio/gpio{gpio_switch_port} ]; then echo {gpio_switch_port} > /sys/class/gpio/export; sleep 0.5; fi"
|
||||
gnss_ssh_connection.send(export_cmd)
|
||||
# sleep needed even with retry loop
|
||||
time.sleep(1)
|
||||
|
||||
# Set direction to output
|
||||
direction_cmd = f"echo out > /sys/class/gpio/gpio{gpio_switch_port}/direction"
|
||||
gnss_ssh_connection.send(direction_cmd)
|
||||
# sleep needed even with retry loop
|
||||
time.sleep(1)
|
||||
|
||||
# Set GPIO value to 1 (power on GNSS)
|
||||
value_cmd = f"echo 1 > /sys/class/gpio/gpio{gpio_switch_port}/value"
|
||||
@@ -147,12 +151,16 @@ class GnssKeywords(BaseKeyword):
|
||||
raise Exception(f"GPIO switch port not configured for {hostname} {nic}")
|
||||
|
||||
# Export GPIO pin if not already exported
|
||||
export_cmd = f"if [ ! -d /sys/class/gpio/gpio{gpio_switch_port} ]; then echo {gpio_switch_port} > /sys/class/gpio/export; fi"
|
||||
export_cmd = f"if [ ! -d /sys/class/gpio/gpio{gpio_switch_port} ]; then echo {gpio_switch_port} > /sys/class/gpio/export; sleep 0.5; fi"
|
||||
gnss_ssh_connection.send(export_cmd)
|
||||
# sleep needed even with retry loop
|
||||
time.sleep(1)
|
||||
|
||||
# Set direction to output
|
||||
direction_cmd = f"echo out > /sys/class/gpio/gpio{gpio_switch_port}/direction"
|
||||
gnss_ssh_connection.send(direction_cmd)
|
||||
# sleep needed even with retry loop
|
||||
time.sleep(1)
|
||||
|
||||
# Set GPIO value to 0 (power off GNSS)
|
||||
value_cmd = f"echo 0 > /sys/class/gpio/gpio{gpio_switch_port}/value"
|
||||
|
@@ -15,7 +15,8 @@ class ParentDataSet:
|
||||
"""
|
||||
if "gm_clock_class" not in expected_dict:
|
||||
raise Exception("Every expected dict should have a gm_clock_class.")
|
||||
self.gm_clock_class = expected_dict["gm_clock_class"]
|
||||
gm_clock_class = expected_dict["gm_clock_class"]
|
||||
self.gm_clock_class = gm_clock_class if isinstance(gm_clock_class, list) else [gm_clock_class]
|
||||
|
||||
if "gm_clock_accuracy" not in expected_dict:
|
||||
raise Exception("Every expected dict should have a gm_clock_accuracy.")
|
||||
@@ -25,12 +26,12 @@ class ParentDataSet:
|
||||
raise Exception("Every expected dict should have a gm_offset_scaled_log_variance.")
|
||||
self.gm_offset_scaled_log_variance = expected_dict["gm_offset_scaled_log_variance"]
|
||||
|
||||
def get_gm_clock_class(self) -> int:
|
||||
def get_gm_clock_class(self) -> list:
|
||||
"""
|
||||
Gets the gm clock class.
|
||||
|
||||
Returns:
|
||||
int: The gm clock class.
|
||||
list: The gm clock class.
|
||||
"""
|
||||
return self.gm_clock_class
|
||||
|
||||
|
@@ -153,58 +153,6 @@ Prerequisites
|
||||
3. Confirm all nodes are up and running
|
||||
4. PTP services should be configured but not necessarily synchronized
|
||||
|
||||
Test Execution
|
||||
------------
|
||||
|
||||
To run all PTP tests:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m pytest starlingx/testcases/cloud_platform/regression/ptp/test_ptp.py -v
|
||||
|
||||
To run a specific test:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m pytest starlingx/testcases/cloud_platform/regression/ptp/test_ptp.py::test_ptp_operation_gnss_disable -v
|
||||
|
||||
Test Cases
|
||||
=========
|
||||
|
||||
test_ptp_operation_gnss_disable
|
||||
-----------------------------
|
||||
|
||||
**Purpose**: Verify PTP behavior when GNSS signal is lost and then restored.
|
||||
|
||||
**Steps**:
|
||||
1. Turn off GNSS for Controller-0 NIC1 using GPIO control
|
||||
2. Verify alarms are triggered (100.119)
|
||||
3. Verify clock class degradation (248 for holdover mode)
|
||||
4. Verify PMC configuration with GNSS off
|
||||
5. Turn GNSS back on
|
||||
6. Verify alarms clear
|
||||
7. Verify clock class restoration (6 for normal operation)
|
||||
8. Verify PMC configuration after restoration
|
||||
|
||||
**Expected Results**:
|
||||
- When GNSS is off, system should enter holdover mode with appropriate alarms
|
||||
- When GNSS is restored, system should return to normal operation with alarms cleared
|
||||
|
||||
test_ptp_operation_phc_ctl_time_change
|
||||
------------------------------------
|
||||
|
||||
**Purpose**: Verify PTP behavior when hardware clocks are manually adjusted.
|
||||
|
||||
**Steps**:
|
||||
1. Start phc_ctl loop on controller-0 NIC1 to introduce time drift
|
||||
2. Verify out-of-tolerance alarms are triggered
|
||||
3. Stop the adjustment and verify alarms clear
|
||||
4. Repeat the process for controller-1 NIC2
|
||||
|
||||
**Expected Results**:
|
||||
- Manual clock adjustments should trigger out-of-tolerance alarms
|
||||
- When adjustments stop, system should recover and alarms should clear
|
||||
|
||||
Common Alarms
|
||||
============
|
||||
|
||||
@@ -293,7 +241,7 @@ Common Issues and Solutions
|
||||
- Check for proper delay mechanism configuration
|
||||
|
||||
Diagnostic Commands and Interpretation
|
||||
--------------------------------
|
||||
================================
|
||||
|
||||
Below are essential commands for diagnosing PTP issues, along with explanations of what to look for in the output:
|
||||
|
||||
@@ -350,17 +298,68 @@ Below are essential commands for diagnosing PTP issues, along with explanations
|
||||
|
||||
**Understanding Clock Class Values:**
|
||||
|
||||
- **6**: Synchronized to primary reference (GNSS) - Optimal
|
||||
- **7**: Synchronized to primary reference but holdover capable - Good
|
||||
- **13-14**: Synchronized to application-specific source - Acceptable
|
||||
- **52**: Degraded reference but synchronized - Warning
|
||||
- **6**: Synchronized to primary reference (GNSS) - Highest accuracy
|
||||
- **7**: Synchronized to primary reference but in holdover - Starting to drift
|
||||
- **13-14**: Synchronized to application-specific source - Alternative reference
|
||||
- **52**: Degraded reference but synchronized - Reduced accuracy
|
||||
- **165**: Clock in holdover mode after losing synchronization - Drifting
|
||||
- **187**: In holdover but within specifications - Warning
|
||||
- **193**: In holdover, out of specifications - Problem
|
||||
- **248**: Default/Holdover/Uncalibrated - Problem
|
||||
- **255**: Slave-only clock - Normal for slave devices
|
||||
- **248**: Default/uncalibrated clock - Worst quality, complete loss
|
||||
- **255**: Slave-only clock - Receives time, never provides it
|
||||
|
||||
**Clock Accuracy Values:**
|
||||
- **0x20**: "±25 nanoseconds - Highest accuracy with GNSS lock",
|
||||
- **0x21**: "±100 nanoseconds - Very high accuracy",
|
||||
- **0x22**: "±250 nanoseconds - High accuracy",
|
||||
- **0xFE**: "Unknown - Accuracy cannot be determined (typically in holdover)",
|
||||
- **0xFF**: "Reserved/Invalid - Not used for synchronization"
|
||||
|
||||
**Port States:**
|
||||
- **MASTER**: "Port provides timing to downstream devices",
|
||||
- **SLAVE**: "Port receives timing from an upstream master",
|
||||
- **PASSIVE**: "Port is not currently used for synchronization",
|
||||
- **LISTENING**: "Port is monitoring the network but not synchronized",
|
||||
- **FAULTY**: "Port has detected a fault condition",
|
||||
- **DISABLED**: "Port is administratively disabled",
|
||||
- **UNCALIBRATED**: "Port is in the process of calibrating",
|
||||
- **PRE_MASTER**: "Port is transitioning to MASTER state"
|
||||
}
|
||||
|
||||
** Flag Values:**
|
||||
- **time_traceable_1**: "Time is traceable to a primary reference (GNSS/UTC)",
|
||||
- **time_traceable_0**: "Time is not traceable to a primary reference",
|
||||
- **frequency_traceable_1**: "Frequency is traceable to a primary reference",
|
||||
- **frequency_traceable_0**: "Frequency is not traceable to a primary reference",
|
||||
- **current_utc_offset_valid_1**: "The UTC offset is valid and can be trusted",
|
||||
- **current_utc_offset_valid_0**: "The UTC offset is not valid and cannot be trusted"
|
||||
|
||||
## Clock Accuracy Values
|
||||
|
||||
| Accuracy Value | Description | Meaning in Tests |
|
||||
|----------------|-------------|------------------|
|
||||
| 0x20 | ±25 nanoseconds | Highest accuracy, typically with GNSS lock |
|
||||
| 0x21 | ±100 nanoseconds | Very high accuracy |
|
||||
| 0x22 | ±250 nanoseconds | High accuracy |
|
||||
| 0xFE | Unknown | Accuracy cannot be determined (typically in holdover) |
|
||||
| 0xFF | Reserved/Invalid | Not used for synchronization |
|
||||
|
||||
## Port States
|
||||
|
||||
| Port State | Description | Test Implications |
|
||||
|------------|-------------|-------------------|
|
||||
| MASTER | Port provides timing to downstream devices | Device is acting as time source |
|
||||
| SLAVE | Port receives timing from an upstream master | Device is synchronizing to another clock |
|
||||
| PASSIVE | Port is not currently used for synchronization | Monitoring only, not active in timing path |
|
||||
| LISTENING | Port is monitoring the network but not synchronized | Initial state or recovering from error |
|
||||
| FAULTY | Port has detected a fault condition | Problem with timing or physical connection |
|
||||
| DISABLED | Port is administratively disabled | Not participating in PTP |
|
||||
| UNCALIBRATED | Port is in the process of calibrating | Transitional state during initialization |
|
||||
| PRE_MASTER | Port is transitioning to MASTER state | Temporary state before becoming MASTER |
|
||||
|
||||
|
||||
References and Learning Resources
|
||||
===========================
|
||||
================================
|
||||
|
||||
Standards and Specifications
|
||||
--------------------------
|
||||
|
@@ -500,6 +500,22 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
|
||||
Preconditions:
|
||||
- System is set up with valid PTP configuration as defined in ptp_configuration_expectation_compute.json5.
|
||||
|
||||
Notes:
|
||||
When analyzing test results, pay attention to:
|
||||
1. **Clock Class Transitions**:
|
||||
- 6 → 7: Brief GNSS signal loss, entering holdover
|
||||
- 6 → 248: Complete GNSS signal loss, uncalibrated
|
||||
- 248 → 6: GNSS signal recovery
|
||||
|
||||
2. **Port State Changes**:
|
||||
- MASTER → SLAVE: Loss of reference or better clock available
|
||||
- SLAVE → MASTER: Becoming best available clock
|
||||
- Any state → FAULTY: Hardware or connectivity issue
|
||||
|
||||
3. **Flag Value Changes**:
|
||||
- time_traceable 1 → 0: Loss of traceable time reference
|
||||
- frequency_traceable 1 → 0: Loss of traceable frequency reference
|
||||
"""
|
||||
lab_connect_keywords = LabConnectionKeywords()
|
||||
ssh_connection = lab_connect_keywords.get_active_controller_ssh()
|
||||
@@ -510,45 +526,66 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
|
||||
selected_instances = [("ptp1", "controller-0", []), ("ptp1", "controller-1", []), ("ptp3", "controller-0", []), ("ptp4", "controller-1", [])]
|
||||
|
||||
# controller-0 with GNSS disabled demotes itself (clockClass: 248) and becomes a SLAVE.
|
||||
# controller-1 (still in degraded state but better than 248) becomes MASTER.
|
||||
# Synchronization continues from controller-1 to controller-0.
|
||||
# External clients (e.g., Proxmox) continue receiving PTP sync via remaining MASTER ports.
|
||||
# Clock quality degradation is tracked via clock_class, accuracy, and variance.
|
||||
# Flag Values:
|
||||
# time_traceable=1: Time is traceable to primary reference (GNSS/UTC)
|
||||
# time_traceable=0: Time is not traceable to primary reference
|
||||
# frequency_traceable=1: Frequency is traceable to primary reference
|
||||
# frequency_traceable=0: Frequency is not traceable to primary reference
|
||||
# current_utc_offset_valid=0: UTC offset cannot be trusted without GNSS
|
||||
#
|
||||
# When GNSS signal is lost:
|
||||
# - Controller-0 changes from clock class 6 to 7 (brief loss) or 248 (complete loss)
|
||||
# - Port roles may reverse with the best available clock becoming MASTER
|
||||
# - External clients continue receiving time from both controllers
|
||||
#
|
||||
# Role Changes During GNSS Signal Loss
|
||||
# When GNSS signal is lost, the following changes occur in the PTP network:
|
||||
|
||||
# 1. Controller-0 with GNSS:
|
||||
# - Clock class changes from 6 (GNSS-synchronized) to 248 (uncalibrated)
|
||||
# - Port state changes from MASTER to SLAVE
|
||||
# - time_traceable and frequency_traceable flags change from 1 to 0
|
||||
|
||||
# 2. Controller-1 without direct GNSS:
|
||||
# - Takes over as best available time source with clock class 165
|
||||
# - Port state changes from SLAVE to MASTER
|
||||
# - Becomes the new reference for Controller-0
|
||||
|
||||
# 3. External Clients:
|
||||
# - Continue receiving time from both controllers
|
||||
# - Service availability is maintained despite degraded accuracy
|
||||
|
||||
# This role reversal ensures that the best available clock is always used as the reference,
|
||||
# maintaining time synchronization even when the primary reference is lost.
|
||||
ctrl0_nic1_gnss_disable_exp_dict = """{
|
||||
"ptp4l": [
|
||||
{
|
||||
"name": "ptp1",
|
||||
"controller-0": {
|
||||
"parent_data_set": {
|
||||
"gm_clock_class": 165, // GM is in holdover or degraded mode due to GNSS loss
|
||||
"gm_clock_class": 7, // GM is in holdover or degraded mode due to GNSS loss
|
||||
"gm_clock_accuracy": "0xfe", // Accuracy unknown due to GNSS signal loss
|
||||
"gm_offset_scaled_log_variance": "0xffff" // Clock stability unknown
|
||||
},
|
||||
"time_properties_data_set": {
|
||||
"current_utc_offset": 37, // Standard UTC offset (can be static)
|
||||
"current_utc_offset_valid": 0, // UTC offset is not currently valid
|
||||
"time_traceable": 0, // Time is not traceable to a valid source
|
||||
"frequency_traceable": 0 // Frequency is not traceable to a valid reference
|
||||
"time_traceable": 1, // Time is not traceable to a valid source
|
||||
"frequency_traceable": 1 // Frequency is not traceable to a valid reference
|
||||
},
|
||||
"grandmaster_settings": {
|
||||
"clock_class": 248, // Indicates GNSS signal is lost (free-running or degraded)
|
||||
"clock_class": 7, // Indicates GNSS signal is lost (free-running or degraded)
|
||||
"clock_accuracy": "0xfe", // Accuracy is unknown
|
||||
"offset_scaled_log_variance": "0xffff", // Clock variance is unknown
|
||||
"time_traceable": 0, // Time not traceable
|
||||
"frequency_traceable": 0, // Frequency not traceable
|
||||
"time_traceable": 1, // Time not traceable
|
||||
"frequency_traceable": 1, // Frequency not traceable
|
||||
"time_source": "0xa0", // Time source originally GNSS (0xA0)
|
||||
"current_utc_offset_valid": 0 // UTC offset invalid due to signal loss
|
||||
},
|
||||
"port_data_set": [
|
||||
{
|
||||
"interface": "{{ controller_0.nic1.nic_connection.interface }}",
|
||||
"port_state": "SLAVE", // Now syncing from controller-1, no longer acting as GM
|
||||
"parent_port_identity" : {
|
||||
"name": "ptp1", // Source PTP instance (controller-1)
|
||||
"hostname":"controller-1", // Controller now acting as GM
|
||||
"interface": "{{ controller_1.nic1.nic_connection.interface }}" // Source interface on controller-1
|
||||
},
|
||||
"port_state": "MASTER",
|
||||
},
|
||||
{
|
||||
"interface": "{{ controller_0.nic1.conn_to_proxmox }}",
|
||||
@@ -558,18 +595,18 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
},
|
||||
"controller-1": {
|
||||
"parent_data_set": {
|
||||
"gm_clock_class": 165, // Controller-1 is GM but in holdover/degraded state
|
||||
"gm_clock_class": 7,
|
||||
"gm_clock_accuracy": "0xfe", // Unknown accuracy
|
||||
"gm_offset_scaled_log_variance": "0xffff" // Unknown clock variance
|
||||
},
|
||||
"time_properties_data_set": {
|
||||
"current_utc_offset": 37,
|
||||
"current_utc_offset_valid": 0,
|
||||
"time_traceable": 0,
|
||||
"frequency_traceable": 0
|
||||
"time_traceable": 1,
|
||||
"frequency_traceable": 1
|
||||
},
|
||||
"grandmaster_settings": {
|
||||
"clock_class": 165, // Controller-1 is acting as the best available GM
|
||||
"clock_class": [165,248],
|
||||
"clock_accuracy": "0xfe",
|
||||
"offset_scaled_log_variance": "0xffff",
|
||||
"time_traceable": 0,
|
||||
@@ -580,7 +617,12 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
"port_data_set": [
|
||||
{
|
||||
"interface": "{{ controller_1.nic1.nic_connection.interface }}",
|
||||
"port_state": "MASTER" // Now acting as the Grandmaster
|
||||
"port_state": "SLAVE",
|
||||
"parent_port_identity" : {
|
||||
"name": "ptp1",
|
||||
"hostname":"controller-0",
|
||||
"interface": "{{ controller_0.nic1.nic_connection.interface }}" // ctrl-0 NIC1 is Master and ctrl-1 NIC1 is slave
|
||||
},
|
||||
},
|
||||
{
|
||||
"interface": "{{ controller_1.nic1.conn_to_proxmox }}",
|
||||
@@ -593,34 +635,29 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
"name": "ptp3",
|
||||
"controller-0": {
|
||||
"parent_data_set": {
|
||||
"gm_clock_class": 165, // Degraded GM status
|
||||
"gm_clock_class": 7, // Lost GNSS, degraded state
|
||||
"gm_clock_accuracy": "0xfe",
|
||||
"gm_offset_scaled_log_variance": "0xffff"
|
||||
},
|
||||
"time_properties_data_set": {
|
||||
"current_utc_offset": 37,
|
||||
"current_utc_offset_valid": 0,
|
||||
"time_traceable": 0,
|
||||
"frequency_traceable": 0
|
||||
"time_traceable": 1,
|
||||
"frequency_traceable": 1
|
||||
},
|
||||
"grandmaster_settings": {
|
||||
"clock_class": 248, // Lost GNSS, degraded state
|
||||
"clock_class": 7, // Lost GNSS, degraded state
|
||||
"clock_accuracy": "0xfe",
|
||||
"offset_scaled_log_variance": "0xffff",
|
||||
"time_traceable": 0,
|
||||
"frequency_traceable": 0,
|
||||
"time_traceable": 1,
|
||||
"frequency_traceable": 1,
|
||||
"time_source": "0xa0",
|
||||
"current_utc_offset_valid": 0
|
||||
},
|
||||
"port_data_set": [
|
||||
{
|
||||
"interface": "{{ controller_0.nic2.nic_connection.interface }}",
|
||||
"port_state": "SLAVE", // Now following ptp4 on controller-1 NIC2
|
||||
"parent_port_identity" : {
|
||||
"name": "ptp4",
|
||||
"hostname":"controller-1",
|
||||
"interface": "{{ controller_1.nic2.nic_connection.interface }}"
|
||||
},
|
||||
"port_state": "MASTER",
|
||||
},
|
||||
{
|
||||
"interface": "{{ controller_0.nic2.conn_to_proxmox }}",
|
||||
@@ -633,18 +670,18 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
"name": "ptp4",
|
||||
"controller-1": {
|
||||
"parent_data_set": {
|
||||
"gm_clock_class": 165,
|
||||
"gm_clock_class": 7,
|
||||
"gm_clock_accuracy": "0xfe",
|
||||
"gm_offset_scaled_log_variance": "0xffff"
|
||||
},
|
||||
"time_properties_data_set": {
|
||||
"current_utc_offset": 37,
|
||||
"current_utc_offset_valid": 0,
|
||||
"time_traceable": 0,
|
||||
"frequency_traceable": 0
|
||||
"time_traceable": 1,
|
||||
"frequency_traceable": 1
|
||||
},
|
||||
"grandmaster_settings": {
|
||||
"clock_class": 165,
|
||||
"clock_class": [165,248],
|
||||
"clock_accuracy": "0xfe",
|
||||
"offset_scaled_log_variance": "0xffff",
|
||||
"time_traceable": 0,
|
||||
@@ -655,7 +692,12 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
"port_data_set": [
|
||||
{
|
||||
"interface": "{{ controller_1.nic2.nic_connection.interface }}",
|
||||
"port_state": "MASTER" // Acting as GM for NIC2
|
||||
"port_state": "SLAVE", // Acting as GM for NIC2
|
||||
"parent_port_identity" : {
|
||||
"name": "ptp3",
|
||||
"hostname":"controller-0",
|
||||
"interface": "{{ controller_0.nic2.nic_connection.interface }}" // ctrl-0 NIC2 is Master and ctrl-1 NIC2 is slave
|
||||
},
|
||||
},
|
||||
{
|
||||
"interface": "{{ controller_1.nic2.conn_to_proxmox }}",
|
||||
@@ -679,13 +721,8 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
|
||||
ptp1_not_locked_alarm_obj = AlarmListObject()
|
||||
ptp1_not_locked_alarm_obj.set_alarm_id("100.119")
|
||||
ptp1_not_locked_alarm_obj.set_reason_text("controller-1 is not locked to remote PTP Grand Master")
|
||||
ptp1_not_locked_alarm_obj.set_entity_id("host=controller-1.instance=ptp1.ptp=no-lock")
|
||||
|
||||
ptp4_not_locked_alarm_obj = AlarmListObject()
|
||||
ptp4_not_locked_alarm_obj.set_alarm_id("100.119")
|
||||
ptp4_not_locked_alarm_obj.set_reason_text("controller-1 is not locked to remote PTP Grand Master")
|
||||
ptp4_not_locked_alarm_obj.set_entity_id("host=controller-1.instance=ptp4.ptp=no-lock")
|
||||
ptp1_not_locked_alarm_obj.set_reason_text("controller-0 is not locked to remote PTP Grand Master")
|
||||
ptp1_not_locked_alarm_obj.set_entity_id("host=controller-0.instance=ptp1.ptp=no-lock")
|
||||
|
||||
pps_signal_loss_alarm_obj = AlarmListObject()
|
||||
pps_signal_loss_alarm_obj.set_alarm_id("100.119")
|
||||
@@ -697,15 +734,15 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
gnss_signal_loss_alarm_obj.set_reason_text("controller-0 GNSS signal loss state: holdover")
|
||||
gnss_signal_loss_alarm_obj.set_entity_id(f"host=controller-0.interface={interface}.ptp=GNSS-signal-loss")
|
||||
|
||||
AlarmListKeywords(ssh_connection).wait_for_alarms_to_appear([ptp1_not_locked_alarm_obj, ptp4_not_locked_alarm_obj, pps_signal_loss_alarm_obj, gnss_signal_loss_alarm_obj])
|
||||
AlarmListKeywords(ssh_connection).wait_for_alarms_to_appear([ptp1_not_locked_alarm_obj, pps_signal_loss_alarm_obj, gnss_signal_loss_alarm_obj])
|
||||
|
||||
get_logger().log_info("Verifying clock class degradation after GNSS is off.")
|
||||
# The clock is in "Holdover" or "Degraded" mode
|
||||
ptp_readiness_keywords = PTPReadinessKeywords(LabConnectionKeywords().get_ssh_for_hostname("controller-0"))
|
||||
ptp_readiness_keywords.wait_for_clock_class_appear_in_grandmaster_settings_np("ptp1", 248)
|
||||
ptp_readiness_keywords.wait_for_clock_class_appear_in_grandmaster_settings_np("ptp3", 248)
|
||||
ptp_readiness_keywords.wait_for_clock_class_appear_in_grandmaster_settings_np("ptp1", 7)
|
||||
ptp_readiness_keywords.wait_for_clock_class_appear_in_grandmaster_settings_np("ptp3", 7)
|
||||
# GNSS loss
|
||||
ptp_readiness_keywords.wait_for_gm_clock_class_appear_in_parent_data_set("ptp1", 165)
|
||||
ptp_readiness_keywords.wait_for_gm_clock_class_appear_in_parent_data_set("ptp1", 7)
|
||||
|
||||
get_logger().log_info("Verifying PMC configuration after GNSS is off.")
|
||||
ptp_verify_config_keywords = PTPVerifyConfigKeywords(ssh_connection, ctrl0_nic1_gnss_disable_exp_ptp_setup)
|
||||
@@ -715,7 +752,7 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
gnss_keywords.gnss_power_on("controller-0", "nic1")
|
||||
|
||||
get_logger().log_info("Waiting for alarm 100.119 to clear after GNSS is back on.")
|
||||
AlarmListKeywords(ssh_connection).wait_for_alarms_cleared([ptp1_not_locked_alarm_obj, ptp4_not_locked_alarm_obj, pps_signal_loss_alarm_obj, gnss_signal_loss_alarm_obj])
|
||||
AlarmListKeywords(ssh_connection).wait_for_alarms_cleared([ptp1_not_locked_alarm_obj, pps_signal_loss_alarm_obj, gnss_signal_loss_alarm_obj])
|
||||
|
||||
get_logger().log_info("Verifying clock class restoration after GNSS is on.")
|
||||
ptp_readiness_keywords.wait_for_clock_class_appear_in_grandmaster_settings_np("ptp1", 6)
|
||||
@@ -723,8 +760,7 @@ def test_ptp_operation_gnss_off_and_on():
|
||||
ptp_readiness_keywords.wait_for_gm_clock_class_appear_in_parent_data_set("ptp1", 6)
|
||||
|
||||
get_logger().log_info("Verifying PMC configuration after GNSS is restored.")
|
||||
ctrl0_nic1_gnss_enable_exp_dict_overrides = {"ptp4l": [{"name": "ptp4", "controller-1": {"grandmaster_settings": {"clock_class": 165}}}]}
|
||||
ctrl0_nic1_gnss_enable_exp_ptp_setup = ptp_setup_keywords.filter_and_render_ptp_config(ptp_setup_template_path, selected_instances, expected_dict_overrides=ctrl0_nic1_gnss_enable_exp_dict_overrides)
|
||||
ctrl0_nic1_gnss_enable_exp_ptp_setup = ptp_setup_keywords.generate_ptp_setup_from_template(ptp_setup_template_path)
|
||||
ptp_verify_config_keywords = PTPVerifyConfigKeywords(ssh_connection, ctrl0_nic1_gnss_enable_exp_ptp_setup)
|
||||
ptp_verify_config_keywords.verify_ptp_pmc_values()
|
||||
|
||||
|
Reference in New Issue
Block a user