PTPSetup and associated reader
Change-Id: I2a878c41cdc552a387623f06c2890b25f4403a75 Signed-off-by: croy <Christian.Roy@windriver.com>
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
// Can be assigned to any interface of the NIC connected to GNSS and with any NIC on the same host.
|
||||
// By default, we use the first port.
|
||||
base_port: "enp81s0f0",
|
||||
conn_to_ctr1_nic1: "enp81s0f1",
|
||||
conn_to_ctrl1_nic1: "enp81s0f1",
|
||||
|
||||
// Optional Spirent config.
|
||||
conn_to_spirent: "",
|
||||
@@ -33,7 +33,7 @@
|
||||
// Can be assigned to any interface of the NIC connected to GNSS and with any NIC on the same host.
|
||||
// By default, we use the first port.
|
||||
base_port: "",
|
||||
conn_to_ctr1_nic2: "",
|
||||
conn_to_ctrl1_nic2: "",
|
||||
|
||||
// Optional Spirent config.
|
||||
conn_to_spirent: "",
|
||||
@@ -56,7 +56,7 @@
|
||||
// Can be assigned to any interface of the NIC connected to GNSS and with any NIC on the same host.
|
||||
// By default, we use the first port.
|
||||
base_port: "",
|
||||
conn_to_ctr0_nic1: "",
|
||||
conn_to_ctrl0_nic1: "",
|
||||
|
||||
// Optional Spirent config.
|
||||
conn_to_spirent: "",
|
||||
@@ -75,8 +75,8 @@
|
||||
// This port for TS2PHC and PHC2SYS.
|
||||
// Can be assigned to any interface of the NIC connected to GNSS and with any NIC on the same host.
|
||||
// By default, we use the first port.
|
||||
base_port: "",
|
||||
conn_to_ctr0_nic2: "",
|
||||
base_port: "enp82s0f0",
|
||||
conn_to_ctrl0_nic2: "",
|
||||
|
||||
// Optional Spirent config.
|
||||
conn_to_spirent: "",
|
||||
|
@@ -1,4 +1,4 @@
|
||||
from typing import List
|
||||
from typing import Dict, List
|
||||
|
||||
import json5
|
||||
|
||||
@@ -33,6 +33,22 @@ class PTPConfig:
|
||||
"""
|
||||
return "PTPConfig"
|
||||
|
||||
def get_all_hosts_dictionary(self) -> Dict[str, Dict]:
|
||||
"""
|
||||
This function will return a dictionary view of the PTPConfig.
|
||||
|
||||
This is mostly used for substitution in JINJA templates.
|
||||
|
||||
Returns:
|
||||
Dict[str, Dict]: Dictionary representation
|
||||
|
||||
"""
|
||||
dictionary_view = {}
|
||||
for host in self.get_all_hosts():
|
||||
dictionary_view[host.get_name()] = host.get_all_nics_dictionary()
|
||||
|
||||
return dictionary_view
|
||||
|
||||
def get_all_hosts(self) -> List[PTPHost]:
|
||||
"""
|
||||
Getter for the PTP information for every host defined in the config.
|
||||
|
@@ -32,6 +32,22 @@ class PTPHost:
|
||||
"""
|
||||
return f"PTPHost - {self.name}"
|
||||
|
||||
def get_all_nics_dictionary(self) -> Dict[str, Dict]:
|
||||
"""
|
||||
This function will return a dictionary view of the PTPHost.
|
||||
|
||||
This is mostly used for substitution in JINJA templates.
|
||||
|
||||
Returns:
|
||||
Dict[str, Dict]: Dictionary representation
|
||||
|
||||
"""
|
||||
dictionary_view = {}
|
||||
for nic in self.get_all_nics():
|
||||
dictionary_view[nic.get_name()] = nic.to_dictionary()
|
||||
|
||||
return dictionary_view
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
Getter for the name of this ptp_host.
|
||||
@@ -65,6 +81,4 @@ class PTPHost:
|
||||
for nic in self.nics:
|
||||
if nic.get_name() == nic_name:
|
||||
return nic
|
||||
raise Exception(
|
||||
f"There is no PTP NIC called {nic_name} associated with the host {self.name} in the PTP config."
|
||||
)
|
||||
raise Exception(f"There is no PTP NIC called {nic_name} associated with the host {self.name} in the PTP config.")
|
||||
|
@@ -29,6 +29,8 @@ class PTPNic:
|
||||
self.conn_to_spirent = None
|
||||
self.spirent_port = None
|
||||
|
||||
self.nic_dictionary = nic_dict
|
||||
|
||||
if "gnss_switch_port" in nic_dict and nic_dict["gnss_switch_port"]:
|
||||
self.gnss_switch_port = nic_dict["gnss_switch_port"]
|
||||
|
||||
@@ -74,6 +76,18 @@ class PTPNic:
|
||||
"""
|
||||
return f"PTPNic - {self.name}"
|
||||
|
||||
def to_dictionary(self) -> Dict[str, str]:
|
||||
"""
|
||||
This function will return a dictionary view of the PTPNic.
|
||||
|
||||
This is mostly used for substitution in JINJA templates.
|
||||
|
||||
Returns:
|
||||
Dict[str, str]: Dictionary representation
|
||||
|
||||
"""
|
||||
return self.nic_dictionary
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
Gets the Name of this PTP NIC.
|
||||
|
101
keywords/ptp/setup/object/clock_setup.py
Normal file
101
keywords/ptp/setup/object/clock_setup.py
Normal file
@@ -0,0 +1,101 @@
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from keywords.ptp.setup.object.ptp_host_interface_setup import PTPHostInterfaceSetup
|
||||
|
||||
|
||||
class ClockSetup:
|
||||
"""
|
||||
Class models a clock setup
|
||||
"""
|
||||
|
||||
def __init__(self, setup_dict: Dict[str, Any], ptp_host_ifs_dict: Dict[str, PTPHostInterfaceSetup]):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
Args:
|
||||
setup_dict (Dict[str, Any]): The dictionary read from the JSON setup template file associated with this clock setup.
|
||||
ptp_host_ifs_dict (Dict[str, PTPHostInterfaceSetup]): The dictionary that maps the name of thePTPHostInterfaceSetup to its associated object.
|
||||
|
||||
"""
|
||||
if "name" not in setup_dict:
|
||||
raise Exception("Every clock entry should have a name.")
|
||||
self.name = setup_dict["name"]
|
||||
|
||||
if "instance_hostnames" not in setup_dict:
|
||||
raise Exception(f"The clock entry {self.name} must have instance_hostnames defined.")
|
||||
self.instance_hostnames = setup_dict["instance_hostnames"]
|
||||
|
||||
if "instance_parameters" not in setup_dict:
|
||||
raise Exception(f"The clock entry {self.name} must have instance_parameters defined.")
|
||||
self.instance_parameters = setup_dict["instance_parameters"]
|
||||
|
||||
if "ptp_interface_names" not in setup_dict:
|
||||
raise Exception(f"The clock entry {self.name} must have ptp_interface_names defined.")
|
||||
|
||||
ptp_interfaces = []
|
||||
for ptp_interface_name in setup_dict["ptp_interface_names"]:
|
||||
if ptp_interface_name not in ptp_host_ifs_dict:
|
||||
raise Exception(f"The ptp_host_if entry {ptp_interface_name} must be defined.")
|
||||
ptp_interfaces.append(ptp_host_ifs_dict[ptp_interface_name])
|
||||
self.ptp_interfaces = ptp_interfaces
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
String representation of this object.
|
||||
|
||||
Returns:
|
||||
str: String representation of this object.
|
||||
|
||||
"""
|
||||
return self.get_name()
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
Gets the name of this clock setup.
|
||||
|
||||
Returns:
|
||||
str: The name of this clock setup.
|
||||
"""
|
||||
return self.name
|
||||
|
||||
def get_instance_hostnames(self) -> list[str]:
|
||||
"""
|
||||
Gets the list of instance hostnames.
|
||||
|
||||
Returns:
|
||||
list[str]: The list of instance hostnames.
|
||||
"""
|
||||
return self.instance_hostnames
|
||||
|
||||
def get_instance_parameters(self) -> str:
|
||||
"""
|
||||
Gets the instance parameters as a string.
|
||||
|
||||
Returns:
|
||||
str: The instance parameters as a string
|
||||
"""
|
||||
return self.instance_parameters
|
||||
|
||||
def get_ptp_interfaces(self) -> List[PTPHostInterfaceSetup]:
|
||||
"""
|
||||
Gets the list of PTP interfaces.
|
||||
|
||||
Returns:
|
||||
List[PTPHostInterfaceSetup]: The list of PTP interfaces.
|
||||
"""
|
||||
return self.ptp_interfaces
|
||||
|
||||
def get_ptp_interface(self, ptp_host_if_name: str) -> PTPHostInterfaceSetup:
|
||||
"""
|
||||
Gets the PTP interface associated with the name ptp_host_if_name.
|
||||
|
||||
Args:
|
||||
ptp_host_if_name (str): Name of the ptp_host_if associated with this clock setup with the provided name.
|
||||
|
||||
Returns:
|
||||
PTPHostInterfaceSetup: PTPHostInterfaceSetup with the name passed in.
|
||||
"""
|
||||
for ptp_interface in self.ptp_interfaces:
|
||||
if ptp_interface.get_name() == ptp_host_if_name:
|
||||
return ptp_interface
|
||||
raise Exception(f"There is no ptp host interface with the name {ptp_host_if_name} associated with the clock setup {self.get_name()}")
|
86
keywords/ptp/setup/object/phc2sys_setup.py
Normal file
86
keywords/ptp/setup/object/phc2sys_setup.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from keywords.ptp.setup.object.ptp_host_interface_setup import PTPHostInterfaceSetup
|
||||
|
||||
|
||||
class PHC2SysSetup:
|
||||
"""
|
||||
Class models a phc2sys setup
|
||||
"""
|
||||
|
||||
def __init__(self, setup_dict: Dict[str, Any], ptp_host_ifs_dict: Dict[str, PTPHostInterfaceSetup]):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
Args:
|
||||
setup_dict (Dict[str, Any]): The dictionary read from the JSON setup template file associated with this phc2sys setup.
|
||||
ptp_host_ifs_dict (Dict[str, PTPHostInterfaceSetup]): The dictionary that maps the name of thePTPHostInterfaceSetup to its associated object.
|
||||
|
||||
"""
|
||||
if "name" not in setup_dict:
|
||||
raise Exception("Every phc2sys entry should have a name.")
|
||||
self.name = setup_dict["name"]
|
||||
|
||||
if "instance_hostnames" not in setup_dict:
|
||||
raise Exception(f"The phc2sys entry {self.name} must have instance_hostnames defined.")
|
||||
self.instance_hostnames = setup_dict["instance_hostnames"]
|
||||
|
||||
if "instance_parameters" not in setup_dict:
|
||||
raise Exception(f"The phc2sys entry {self.name} must have instance_parameters defined.")
|
||||
self.instance_parameters = setup_dict["instance_parameters"]
|
||||
|
||||
if "ptp_interface_names" not in setup_dict:
|
||||
raise Exception(f"The phc2sys entry {self.name} must have ptp_interface_names defined.")
|
||||
|
||||
ptp_interfaces = []
|
||||
for ptp_interface_name in setup_dict["ptp_interface_names"]:
|
||||
if ptp_interface_name not in ptp_host_ifs_dict:
|
||||
raise Exception(f"The ptp_host_if entry {ptp_interface_name} must be defined.")
|
||||
ptp_interfaces.append(ptp_host_ifs_dict[ptp_interface_name])
|
||||
self.ptp_interfaces = ptp_interfaces
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
String representation of this object.
|
||||
|
||||
Returns:
|
||||
str: String representation of this object.
|
||||
|
||||
"""
|
||||
return self.get_name()
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
Gets the name of this phc2sys setup.
|
||||
|
||||
Returns:
|
||||
str: The name of this phc2sys setup.
|
||||
"""
|
||||
return self.name
|
||||
|
||||
def get_instance_hostnames(self) -> list[str]:
|
||||
"""
|
||||
Gets the list of instance hostnames.
|
||||
|
||||
Returns:
|
||||
list[str]: The list of instance hostnames.
|
||||
"""
|
||||
return self.instance_hostnames
|
||||
|
||||
def get_instance_parameters(self) -> str:
|
||||
"""
|
||||
Gets the instance parameters as a string.
|
||||
|
||||
Returns:
|
||||
str: The instance parameters as a string
|
||||
"""
|
||||
return self.instance_parameters
|
||||
|
||||
def get_ptp_interfaces(self) -> List[PTPHostInterfaceSetup]:
|
||||
"""
|
||||
Gets the list of PTP interfaces.
|
||||
|
||||
Returns:
|
||||
List[PTPHostInterfaceSetup]: The list of PTP interfaces.
|
||||
"""
|
||||
return self.ptp_interfaces
|
86
keywords/ptp/setup/object/ptp4l_setup.py
Normal file
86
keywords/ptp/setup/object/ptp4l_setup.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from keywords.ptp.setup.object.ptp_host_interface_setup import PTPHostInterfaceSetup
|
||||
|
||||
|
||||
class PTP4LSetup:
|
||||
"""
|
||||
Class models a ptp4l setup
|
||||
"""
|
||||
|
||||
def __init__(self, setup_dict: Dict[str, Any], ptp_host_ifs_dict: Dict[str, PTPHostInterfaceSetup]):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
Args:
|
||||
setup_dict (Dict[str, Any]): The dictionary read from the JSON setup template file associated with this ptp4l setup.
|
||||
ptp_host_ifs_dict (Dict[str, PTPHostInterfaceSetup]): The dictionary that maps the name of thePTPHostInterfaceSetup to its associated object.
|
||||
|
||||
"""
|
||||
if "name" not in setup_dict:
|
||||
raise Exception("Every PTP4L entry should have a name.")
|
||||
self.name = setup_dict["name"]
|
||||
|
||||
if "instance_hostnames" not in setup_dict:
|
||||
raise Exception(f"The ptp4l entry {self.name} must have instance_hostnames defined.")
|
||||
self.instance_hostnames = setup_dict["instance_hostnames"]
|
||||
|
||||
if "instance_parameters" not in setup_dict:
|
||||
raise Exception(f"The ptp4l entry {self.name} must have instance_parameters defined.")
|
||||
self.instance_parameters = setup_dict["instance_parameters"]
|
||||
|
||||
if "ptp_interface_names" not in setup_dict:
|
||||
raise Exception(f"The ptp4l entry {self.name} must have ptp_interface_names defined.")
|
||||
|
||||
ptp_interfaces = []
|
||||
for ptp_interface_name in setup_dict["ptp_interface_names"]:
|
||||
if ptp_interface_name not in ptp_host_ifs_dict:
|
||||
raise Exception(f"The ptp_host_if entry {ptp_interface_name} must be defined.")
|
||||
ptp_interfaces.append(ptp_host_ifs_dict[ptp_interface_name])
|
||||
self.ptp_interfaces = ptp_interfaces
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
String representation of this object.
|
||||
|
||||
Returns:
|
||||
str: String representation of this object.
|
||||
|
||||
"""
|
||||
return self.get_name()
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
Gets the name of this ptp4l setup.
|
||||
|
||||
Returns:
|
||||
str: The name of this ptp4l setup.
|
||||
"""
|
||||
return self.name
|
||||
|
||||
def get_instance_hostnames(self) -> list[str]:
|
||||
"""
|
||||
Gets the list of instance hostnames.
|
||||
|
||||
Returns:
|
||||
list[str]: The list of instance hostnames.
|
||||
"""
|
||||
return self.instance_hostnames
|
||||
|
||||
def get_instance_parameters(self) -> str:
|
||||
"""
|
||||
Gets the instance parameters as a string.
|
||||
|
||||
Returns:
|
||||
str: The instance parameters as a string
|
||||
"""
|
||||
return self.instance_parameters
|
||||
|
||||
def get_ptp_interfaces(self) -> List[PTPHostInterfaceSetup]:
|
||||
"""
|
||||
Gets the list of PTP interfaces.
|
||||
|
||||
Returns:
|
||||
List[PTPHostInterfaceSetup]: The list of PTP interfaces.
|
||||
"""
|
||||
return self.ptp_interfaces
|
77
keywords/ptp/setup/object/ptp_host_interface_setup.py
Normal file
77
keywords/ptp/setup/object/ptp_host_interface_setup.py
Normal file
@@ -0,0 +1,77 @@
|
||||
from typing import Any, Dict, List
|
||||
|
||||
|
||||
class PTPHostInterfaceSetup:
|
||||
"""
|
||||
This class models a PTP Host interface setup.
|
||||
"""
|
||||
|
||||
def __init__(self, setup_dict: Dict[str, Any]):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
Args:
|
||||
setup_dict (Dict[str, Any]): The dictionary read from the JSON setup template file associated with this ptp host interface setup.
|
||||
|
||||
"""
|
||||
if "name" not in setup_dict:
|
||||
raise Exception("Every ptp host interface entry should have a name.")
|
||||
self.name = setup_dict["name"]
|
||||
|
||||
if "ptp_interface_parameter" not in setup_dict:
|
||||
raise Exception(f"The ptp host interface entry {self.name} must have ptp_interface_parameter defined.")
|
||||
self.ptp_interface_parameter = setup_dict["ptp_interface_parameter"]
|
||||
|
||||
if "controller_0_interfaces" not in setup_dict:
|
||||
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:
|
||||
raise Exception(f"The ptp host interface entry {self.name} must have controller_1_interfaces defined.")
|
||||
self.controller_0_interfaces = setup_dict["controller_1_interfaces"]
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
String representation of this object.
|
||||
|
||||
Returns:
|
||||
str: String representation of this object.
|
||||
|
||||
"""
|
||||
return self.get_name()
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
Gets the name of this ptp host interface setup.
|
||||
|
||||
Returns:
|
||||
str: The name of this ptp host interface setup.
|
||||
"""
|
||||
return self.name
|
||||
|
||||
def get_ptp_interface_parameter(self) -> str:
|
||||
"""
|
||||
Gets the ptp_interface_parameter of this ptp host interface setup.
|
||||
|
||||
Returns:
|
||||
str: The ptp_interface_parameter of this ptp host interface setup.
|
||||
"""
|
||||
return self.ptp_interface_parameter
|
||||
|
||||
def get_controller_0_interfaces(self) -> List[str]:
|
||||
"""
|
||||
Gets the controller_0_interfaces of this ptp host interface setup.
|
||||
|
||||
Returns:
|
||||
List[str]: The controller_0_interfaces of this ptp host interface setup.
|
||||
"""
|
||||
return self.controller_0_interfaces
|
||||
|
||||
def get_controller_1_interfaces(self) -> List[str]:
|
||||
"""
|
||||
Gets the controller_1_interfaces of this ptp host interface setup.
|
||||
|
||||
Returns:
|
||||
List[str]: The controller_1_interfaces of this ptp host interface setup.
|
||||
"""
|
||||
return self.controller_1_interfaces
|
110
keywords/ptp/setup/object/ptp_setup.py
Normal file
110
keywords/ptp/setup/object/ptp_setup.py
Normal file
@@ -0,0 +1,110 @@
|
||||
from typing import Dict, List
|
||||
|
||||
from keywords.ptp.setup.object.clock_setup import ClockSetup
|
||||
from keywords.ptp.setup.object.phc2sys_setup import PHC2SysSetup
|
||||
from keywords.ptp.setup.object.ptp4l_setup import PTP4LSetup
|
||||
from keywords.ptp.setup.object.ptp_host_interface_setup import PTPHostInterfaceSetup
|
||||
from keywords.ptp.setup.object.ts2phc_setup import TS2PHCSetup
|
||||
|
||||
|
||||
class PTPSetup:
|
||||
"""
|
||||
This class represents a PTP Setup.
|
||||
"""
|
||||
|
||||
def __init__(self, setup_dict: Dict[str, Dict]):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
Args:
|
||||
setup_dict (Dict[str, Dict]): The dictionary read from the JSON config file associated with this ptp_setup.
|
||||
|
||||
"""
|
||||
self.ptp4l_setup_list: List[PTP4LSetup] = []
|
||||
self.phc2sys_setup_list: List[PHC2SysSetup] = []
|
||||
self.ts2phc_setup_list: List[TS2PHCSetup] = []
|
||||
self.clock_setup_list: List[ClockSetup] = []
|
||||
self.host_ptp_if_dict: Dict[str, PTPHostInterfaceSetup] = {} # Name -> PTPHostInterfaceSetup
|
||||
|
||||
if "ptp_instances" not in setup_dict:
|
||||
raise Exception("You must define a ptp_instances section in your ptp setup_dict")
|
||||
|
||||
if "ptp_host_ifs" not in setup_dict:
|
||||
raise Exception("You must define a ptp_host_ifs section in your ptp setup_dict")
|
||||
|
||||
ptp_host_ifs = setup_dict["ptp_host_ifs"]
|
||||
for ptp_host_if in ptp_host_ifs:
|
||||
ptp_host_if_object = PTPHostInterfaceSetup(ptp_host_if)
|
||||
ptp_host_if_name = ptp_host_if_object.get_name()
|
||||
self.host_ptp_if_dict[ptp_host_if_name] = ptp_host_if_object
|
||||
|
||||
ptp_instances_dict = setup_dict["ptp_instances"]
|
||||
if "ptp4l" in ptp_instances_dict:
|
||||
ptp4l_list = ptp_instances_dict["ptp4l"]
|
||||
for ptp4l_entry_dict in ptp4l_list:
|
||||
ptp4l_setup = PTP4LSetup(ptp4l_entry_dict, self.host_ptp_if_dict)
|
||||
self.ptp4l_setup_list.append(ptp4l_setup)
|
||||
|
||||
if "phc2sys" in ptp_instances_dict:
|
||||
phc2sys_list = ptp_instances_dict["phc2sys"]
|
||||
for phc2sys_entry_dict in phc2sys_list:
|
||||
phc2sys_setup = PHC2SysSetup(phc2sys_entry_dict, self.host_ptp_if_dict)
|
||||
self.phc2sys_setup_list.append(phc2sys_setup)
|
||||
|
||||
if "ts2phc" in ptp_instances_dict:
|
||||
ts2phc_list = ptp_instances_dict["ts2phc"]
|
||||
for ts2phc_entry_dict in ts2phc_list:
|
||||
ts2phc_setup = TS2PHCSetup(ts2phc_entry_dict, self.host_ptp_if_dict)
|
||||
self.ts2phc_setup_list.append(ts2phc_setup)
|
||||
|
||||
if "clock" in ptp_instances_dict:
|
||||
clock_list = ptp_instances_dict["clock"]
|
||||
for clock_entry_dict in clock_list:
|
||||
clock_setup = ClockSetup(clock_entry_dict, self.host_ptp_if_dict)
|
||||
self.clock_setup_list.append(clock_setup)
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
String representation of this object.
|
||||
|
||||
Returns:
|
||||
str: String representation of this object.
|
||||
|
||||
"""
|
||||
return "PTPSetup"
|
||||
|
||||
def get_ptp4l_setup_list(self) -> List[PTP4LSetup]:
|
||||
"""
|
||||
Getter for the list of ptp4l setups.
|
||||
|
||||
Returns:
|
||||
List[PTP4LSetup]: list of ptp4l setups
|
||||
"""
|
||||
return self.ptp4l_setup_list
|
||||
|
||||
def get_phc2sys_setup_list(self) -> List[PHC2SysSetup]:
|
||||
"""
|
||||
Getter for the list of phc2sys setups.
|
||||
|
||||
Returns:
|
||||
List[PHC2SysSetup]: list of phc2sys setups
|
||||
"""
|
||||
return self.phc2sys_setup_list
|
||||
|
||||
def get_ts2phc_setup_list(self) -> List[TS2PHCSetup]:
|
||||
"""
|
||||
Getter for the list of ts2phc setups.
|
||||
|
||||
Returns:
|
||||
List[TS2PHCSetup]: list of ts2phc setups
|
||||
"""
|
||||
return self.ts2phc_setup_list
|
||||
|
||||
def get_clock_setup_list(self) -> List[ClockSetup]:
|
||||
"""
|
||||
Getter for the list of clock setups.
|
||||
|
||||
Returns:
|
||||
List[ClockSetup]: list of clock setups
|
||||
"""
|
||||
return self.clock_setup_list
|
86
keywords/ptp/setup/object/ts2phc_setup.py
Normal file
86
keywords/ptp/setup/object/ts2phc_setup.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from keywords.ptp.setup.object.ptp_host_interface_setup import PTPHostInterfaceSetup
|
||||
|
||||
|
||||
class TS2PHCSetup:
|
||||
"""
|
||||
Class models a ts2phc setup
|
||||
"""
|
||||
|
||||
def __init__(self, setup_dict: Dict[str, Any], ptp_host_ifs_dict: Dict[str, PTPHostInterfaceSetup]):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
Args:
|
||||
setup_dict (Dict[str, Any]): The dictionary read from the JSON setup template file associated with this ts2phc setup.
|
||||
ptp_host_ifs_dict (Dict[str, PTPHostInterfaceSetup]): The dictionary that maps the name of thePTPHostInterfaceSetup to its associated object.
|
||||
|
||||
"""
|
||||
if "name" not in setup_dict:
|
||||
raise Exception("Every ts2phc entry should have a name.")
|
||||
self.name = setup_dict["name"]
|
||||
|
||||
if "instance_hostnames" not in setup_dict:
|
||||
raise Exception(f"The ts2phc entry {self.name} must have instance_hostnames defined.")
|
||||
self.instance_hostnames = setup_dict["instance_hostnames"]
|
||||
|
||||
if "instance_parameters" not in setup_dict:
|
||||
raise Exception(f"The ts2phc entry {self.name} must have instance_parameters defined.")
|
||||
self.instance_parameters = setup_dict["instance_parameters"]
|
||||
|
||||
if "ptp_interface_names" not in setup_dict:
|
||||
raise Exception(f"The ts2phc entry {self.name} must have ptp_interface_names defined.")
|
||||
|
||||
ptp_interfaces = []
|
||||
for ptp_interface_name in setup_dict["ptp_interface_names"]:
|
||||
if ptp_interface_name not in ptp_host_ifs_dict:
|
||||
raise Exception(f"The ptp_host_if entry {ptp_interface_name} must be defined.")
|
||||
ptp_interfaces.append(ptp_host_ifs_dict[ptp_interface_name])
|
||||
self.ptp_interfaces = ptp_interfaces
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
String representation of this object.
|
||||
|
||||
Returns:
|
||||
str: String representation of this object.
|
||||
|
||||
"""
|
||||
return self.get_name()
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""
|
||||
Gets the name of this ts2phc setup.
|
||||
|
||||
Returns:
|
||||
str: The name of this ts2phc setup.
|
||||
"""
|
||||
return self.name
|
||||
|
||||
def get_instance_hostnames(self) -> list[str]:
|
||||
"""
|
||||
Gets the list of instance hostnames.
|
||||
|
||||
Returns:
|
||||
list[str]: The list of instance hostnames.
|
||||
"""
|
||||
return self.instance_hostnames
|
||||
|
||||
def get_instance_parameters(self) -> str:
|
||||
"""
|
||||
Gets the instance parameters as a string.
|
||||
|
||||
Returns:
|
||||
str: The instance parameters as a string
|
||||
"""
|
||||
return self.instance_parameters
|
||||
|
||||
def get_ptp_interfaces(self) -> List[PTPHostInterfaceSetup]:
|
||||
"""
|
||||
Gets the list of PTP interfaces.
|
||||
|
||||
Returns:
|
||||
List[PTPHostInterfaceSetup]: The list of PTP interfaces.
|
||||
"""
|
||||
return self.ptp_interfaces
|
40
keywords/ptp/setup/ptp_setup_reader.py
Normal file
40
keywords/ptp/setup/ptp_setup_reader.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import json5
|
||||
from jinja2 import Template
|
||||
|
||||
from config.configuration_manager import ConfigurationManager
|
||||
from keywords.base_keyword import BaseKeyword
|
||||
from keywords.ptp.setup.object.ptp_setup import PTPSetup
|
||||
|
||||
|
||||
class PTPSetupKeywords(BaseKeyword):
|
||||
"""
|
||||
This class is responsible for reading ptp_setup files and matching them with the ptp config.
|
||||
"""
|
||||
|
||||
def generate_ptp_setup_from_template(self, template_file_location: str) -> PTPSetup:
|
||||
"""
|
||||
This function will read the template_file specified and will replace values based on the ptp_config.
|
||||
|
||||
Args:
|
||||
template_file_location (str): Path in the repo to the Template JSON5 file. e.g. 'resources/ptp/setup/ptp_setup_template.json5'
|
||||
|
||||
Returns:
|
||||
PTPSetup: An object representing the setup.
|
||||
|
||||
"""
|
||||
# Load the Template JSON5 file.
|
||||
with open(template_file_location, "r") as template_file:
|
||||
json5_template = template_file.read()
|
||||
|
||||
# Build a replacement dictionary from the PTP Config
|
||||
ptp_config = ConfigurationManager.get_ptp_config()
|
||||
replacement_dictionary = ptp_config.get_all_hosts_dictionary()
|
||||
|
||||
# Render the JSON5 file by replacing the tokens.
|
||||
template = Template(json5_template)
|
||||
rendered_json_string = template.render(replacement_dictionary)
|
||||
json_data = json5.loads(rendered_json_string)
|
||||
|
||||
# Turn the JSON Data into a ptp_setup object.
|
||||
ptp_setup = PTPSetup(json_data)
|
||||
return ptp_setup
|
225
resources/ptp/setup/ptp_setup_template.json5
Normal file
225
resources/ptp/setup/ptp_setup_template.json5
Normal file
@@ -0,0 +1,225 @@
|
||||
{
|
||||
ptp_instances: {
|
||||
|
||||
ptp4l: [
|
||||
|
||||
{
|
||||
name: "ptp1",
|
||||
instance_hostnames : ["controller_1", "controller_0"] ,
|
||||
instance_parameters: "tx_timestamp_timeout=700 domainNumber=24 dataset_comparison=G.8275.x priority2=100 boundary_clock_jbod=1",
|
||||
ptp_interface_names: [
|
||||
"ptp1if1",
|
||||
"ptp1if2",
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
name: "ptp2",
|
||||
instance_hostnames : [],
|
||||
instance_parameters: "dataset_comparison=G.8275.x domainNumber=24 tx_timestamp_timeout=700 boundary_clock_jbod=1 priority2=110",
|
||||
ptp_interface_names: [
|
||||
"ptp2if1",
|
||||
"ptp2if2"
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "ptp3",
|
||||
instance_hostnames : ["controller_0"],
|
||||
instance_parameters: "dataset_comparison=G.8275.x domainNumber=24 tx_timestamp_timeout=700 boundary_clock_jbod=1 priority2=100",
|
||||
ptp_interface_names: [
|
||||
"ptp3if1",
|
||||
"ptp3if2"
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "ptp4",
|
||||
instance_hostnames : ["controller_1"],
|
||||
instance_parameters: "priority2=110 dataset_comparison=G.8275.x domainNumber=24 tx_timestamp_timeout=700 boundary_clock_jbod=1",
|
||||
ptp_interface_names: [
|
||||
"ptp4if1",
|
||||
"ptp4if2"
|
||||
],
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
phc2sys : [
|
||||
|
||||
{
|
||||
name: "phc1",
|
||||
instance_hostnames : ["controller_1", "controller_0"],
|
||||
instance_parameters: "cmdline_opts=-s {{controller_0.nic1.conn_to_sprint}} -O -37 -m", // lab_topology_synce3.json5 : values is enp81s0f2
|
||||
ptp_interface_names: [
|
||||
"phc1if1",
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "phc2",
|
||||
instance_hostnames : [],
|
||||
instance_parameters: "uds_address=/var/run/ptp4l-ptp2 domainNumber=24",
|
||||
ptp_interface_names: [
|
||||
"phc2if1",
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "phc3",
|
||||
instance_hostnames : [],
|
||||
instance_parameters: "uds_address=/var/run/ptp4l-ptp3 domainNumber=24",
|
||||
ptp_interface_names: [
|
||||
"phc3if1",
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "phc4",
|
||||
instance_hostnames : [],
|
||||
instance_parameters: "uds_address=/var/run/ptp4l-ptp4 domainNumber=24",
|
||||
ptp_interface_names: [
|
||||
"phc4if1",
|
||||
],
|
||||
},
|
||||
|
||||
],
|
||||
|
||||
ts2phc : [
|
||||
|
||||
{
|
||||
name: "ts1",
|
||||
instance_hostnames : ["controller_0"],
|
||||
instance_parameters: "ts2phc.nmea_serialport=/dev/gnss0",
|
||||
ptp_interface_names: [
|
||||
"ts1if1",
|
||||
],
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
clock : [
|
||||
|
||||
{
|
||||
name: "clock1",
|
||||
instance_hostnames : ["controller_0"],
|
||||
instance_parameters: "",
|
||||
ptp_interface_names: [
|
||||
"clock1if1",
|
||||
"clock1if2",
|
||||
],
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
},
|
||||
|
||||
ptp_host_ifs: [
|
||||
|
||||
{
|
||||
name: "ptp1if1",
|
||||
controller_0_interfaces: ["{{ controller_0.nic1.conn_to_ctrl1_nic1 }}"],
|
||||
controller_1_interfaces: ["{{ controller_1.nic1.conn_to_ctrl0_nic1 }}"],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "ptp1if2",
|
||||
controller_0_interfaces: ["{{ controller_0.nic1.conn_to_spirent }}"],
|
||||
controller_1_interfaces: ["{{ controller_1.nic1.conn_to_spirent }}"],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "ptp2if1",
|
||||
controller_0_interfaces: [],
|
||||
controller_1_interfaces: [],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "ptp2if2",
|
||||
controller_0_interfaces: [],
|
||||
controller_1_interfaces: [],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "ptp3if1",
|
||||
controller_0_interfaces: ["{{ controller_0.nic2.conn_to_ctrl1_nic2 }}"],
|
||||
controller_1_interfaces: [],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "ptp3if2",
|
||||
controller_0_interfaces: ["{{ controller_0.nic2.conn_to_spirent }}"],
|
||||
controller_1_interfaces: [],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "ptp4if1",
|
||||
controller_0_interfaces: [],
|
||||
controller_1_interfaces: ["{{ controller_0.nic2.conn_to_ctrl1_nic2 }}"],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "ptp4if2",
|
||||
controller_0_interfaces: [],
|
||||
controller_1_interfaces: ["{{ controller_1.nic2.conn_to_spirent }}"],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "phc1if1",
|
||||
controller_0_interfaces: [],
|
||||
controller_1_interfaces: [],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "phc2if1",
|
||||
controller_0_interfaces: [],
|
||||
controller_1_interfaces: [],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "phc3if1",
|
||||
controller_0_interfaces: [],
|
||||
controller_1_interfaces: [],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "phc4if1",
|
||||
controller_0_interfaces: [],
|
||||
controller_1_interfaces: ["{{ controller_1.nic1.base_port }}", "{{ controller_1.nic2.base_port }}"],
|
||||
ptp_interface_parameter :"",
|
||||
},
|
||||
|
||||
{
|
||||
name: "ts1if1",
|
||||
controller_0_interfaces: ["{{ controller_0.nic1.conn_to_spirent }}", "{{ controller_0.nic2.base_port }}"],
|
||||
controller_1_interfaces: [],
|
||||
ptp_interface_parameter : "",
|
||||
},
|
||||
|
||||
{
|
||||
name: "clock1if1",
|
||||
controller_0_interfaces: ["{{ controller_0.nic1.conn_to_spirent }}"],
|
||||
controller_1_interfaces: [],
|
||||
ptp_interface_parameter : "{{ controller_0.nic1.sma1_to_nic2 }}",
|
||||
},
|
||||
|
||||
{
|
||||
name: "clock1if2",
|
||||
controller_0_interfaces: ["{{ controller_0.nic2.base_port }}"],
|
||||
controller_1_interfaces: [],
|
||||
ptp_interface_parameter : "{{ controller_0.nic2.sma1_to_nic1 }}",
|
||||
},
|
||||
],
|
||||
|
||||
}
|
@@ -1,4 +1,6 @@
|
||||
from config.configuration_file_locations_manager import ConfigurationFileLocationsManager
|
||||
from config.configuration_file_locations_manager import (
|
||||
ConfigurationFileLocationsManager,
|
||||
)
|
||||
from config.configuration_manager import ConfigurationManagerClass
|
||||
|
||||
|
||||
@@ -20,3 +22,4 @@ def test_default_ptp_config():
|
||||
|
||||
first_nic = config_for_controller_0.get_nic("nic1")
|
||||
assert first_nic.get_sma1_to_nic2() == "output"
|
||||
assert first_nic.get_conn_to_ctrl1_nic1() == "enp81s0f1"
|
||||
|
32
unit_tests/keyword/ptp/ptp_setup_reader_test.py
Normal file
32
unit_tests/keyword/ptp/ptp_setup_reader_test.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from config.configuration_file_locations_manager import (
|
||||
ConfigurationFileLocationsManager,
|
||||
)
|
||||
from config.configuration_manager import ConfigurationManager
|
||||
from framework.resources.resource_finder import get_stx_resource_path
|
||||
from keywords.ptp.setup.ptp_setup_reader import PTPSetupKeywords
|
||||
|
||||
|
||||
def test_generate_ptp_setup_from_template():
|
||||
"""
|
||||
Tests that the generation of a PTPSetup from a Config and Template works as expected.
|
||||
|
||||
"""
|
||||
config_file_locations = ConfigurationFileLocationsManager()
|
||||
ConfigurationManager.load_configs(config_file_locations)
|
||||
|
||||
ptp_setup_template_path = get_stx_resource_path("resources/ptp/setup/ptp_setup_template.json5")
|
||||
ptp_setup_keywords = PTPSetupKeywords()
|
||||
ptp_setup = ptp_setup_keywords.generate_ptp_setup_from_template(ptp_setup_template_path)
|
||||
|
||||
ptp4l_setup_list = ptp_setup.get_ptp4l_setup_list()
|
||||
assert len(ptp4l_setup_list) == 4
|
||||
phc2sys_setup_list = ptp_setup.get_phc2sys_setup_list()
|
||||
assert len(phc2sys_setup_list) == 4
|
||||
ts2phc_setup_list = ptp_setup.get_ts2phc_setup_list()
|
||||
assert len(ts2phc_setup_list) == 1
|
||||
|
||||
clock_setup_list = ptp_setup.get_clock_setup_list()
|
||||
assert len(clock_setup_list) == 1
|
||||
clock1 = clock_setup_list[0]
|
||||
clock1_interfaces = clock1.get_ptp_interfaces()
|
||||
assert len(clock1_interfaces) == 2
|
Reference in New Issue
Block a user