Best Python code snippet using lisa_python
timesync.py
Source:timesync.py
...17from lisa.operating_system import CpuArchitecture, Redhat18from lisa.tools import Cat, Chrony, Dmesg, Hwclock, Lscpu, Ntp, Ntpstat, Service19from lisa.tools.lscpu import CpuType20from lisa.util.shell import wait_tcp_port_ready21def _wait_file_changed(22 node: Node,23 path: str,24 expected_value: Optional[Union[str, List[str]]],25) -> bool:26 timeout = 6027 timout_timer = create_timer()28 while timout_timer.elapsed(False) < timeout:29 cat = node.tools[Cat]30 result = cat.run(path, force_run=True)31 if isinstance(expected_value, list):32 if result.stdout in expected_value:33 return True34 else:35 if result.stdout == expected_value:36 return True37 sleep(0.5)38 return False39@TestSuiteMetadata(40 area="time",41 category="functional",42 description="""43 This test suite is related with time sync.44 """,45)46class TimeSync(TestSuite):47 ptp_registered_msg = "PTP clock support registered"48 hyperv_ptp_udev_rule = "ptp_hyperv"49 chrony_path = [50 "/etc/chrony.conf",51 "/etc/chrony/chrony.conf",52 "/etc/chrony.d/azure.conf",53 ]54 current_clocksource = (55 "/sys/devices/system/clocksource/clocksource0/current_clocksource"56 )57 available_clocksource = (58 "/sys/devices/system/clocksource/clocksource0/available_clocksource"59 )60 unbind_clocksource = (61 "/sys/devices/system/clocksource/clocksource0/unbind_clocksource"62 )63 current_clockevent = "/sys/devices/system/clockevents/clockevent0/current_device"64 unbind_clockevent = "/sys/devices/system/clockevents/clockevent0/unbind_device"65 @TestCaseMetadata(66 description="""67 https://docs.microsoft.com/en-us/azure/virtual-machines/linux/time-sync#check-for-ptp-clock-source # noqa: E50168 This test is to check -69 1. PTP time source is available on Azure guests (newer versions of Linux).70 2. PTP device name is hyperv.71 3. When accelerated network is enabled, multiple PTP devices will72 be available, the names of ptp are changeable, create the symlink73 /dev/ptp_hyperv to whichever /dev/ptp entry corresponds to the Azure host.74 4. Chrony should be configured to use the symlink /dev/ptp_hyperv75 instead of /dev/ptp0 or /dev/ptp1.76 """,77 priority=2,78 )79 def timesync_validate_ptp(self, node: Node) -> None:80 # 1. PTP time source is available on Azure guests (newer versions of Linux).81 dmesg = node.tools[Dmesg]82 assert_that(dmesg.get_output()).contains(self.ptp_registered_msg)83 # 2. PTP device name is hyperv.84 cat = node.tools[Cat]85 clock_name_result = cat.run("/sys/class/ptp/ptp0/clock_name")86 assert_that(clock_name_result.stdout).described_as(87 f"ptp clock name should be 'hyperv', meaning the Azure host, "88 f"but it is {clock_name_result.stdout}, more info please refer "89 f"https://docs.microsoft.com/en-us/azure/virtual-machines/linux/time-sync#check-for-ptp-clock-source" # noqa: E50190 ).is_equal_to("hyperv")91 # 3. When accelerated network is enabled, multiple PTP devices will92 # be available, the names of ptp are changeable, create the symlink93 # /dev/ptp_hyperv to whichever /dev/ptp entry corresponds to the Azure host.94 assert_that(node.shell.exists(PurePosixPath("/dev/ptp_hyperv"))).described_as(95 "/dev/ptp_hyperv doesn't exist, make sure there is a udev rule to create "96 "symlink /dev/ptp_hyperv to /dev/ptp entry corresponds to the Azure host. "97 "More info please refer "98 "https://docs.microsoft.com/en-us/azure/virtual-machines/linux/time-sync#check-for-ptp-clock-source" # noqa: E50199 ).is_true()100 # 4. Chrony should be configured to use the symlink /dev/ptp_hyperv101 # instead of /dev/ptp0 or /dev/ptp1.102 for chrony_config in self.chrony_path:103 if node.shell.exists(PurePosixPath(chrony_config)):104 chrony_results = cat.run(f"{chrony_config}")105 assert_that(chrony_results.stdout).described_as(106 "Chrony config file should use the symlink /dev/ptp_hyperv."107 ).contains(self.hyperv_ptp_udev_rule)108 @TestCaseMetadata(109 description="""110 This test is to check -111 1. Check clock source name is one of hyperv_clocksource_tsc_page,112 lis_hv_clocksource_tsc_page, hyperv_clocksource, tsc,113 arch_sys_counter(arm64).114 (thereâs a new feature in the AH2021 host that allows Linux guests so use115 the plain "tsc" instead of the "hyperv_clocksource_tsc_page",116 which produces a modest performance benefit when reading the clock.)117 2. Check CPU flag contains constant_tsc from /proc/cpuinfo.118 3. Check clocksource name shown up in dmesg.119 4. Unbind current clock source if there are 2+ clock sources, check current120 clock source can be switched to a different one.121 """,122 priority=2,123 )124 def timesync_check_unbind_clocksource(self, node: Node, log: Logger) -> None:125 unbind = node.shell.exists(PurePosixPath(self.unbind_clocksource))126 try:127 # 1. Check clock source name is one of hyperv_clocksource_tsc_page,128 # lis_hv_clocksource_tsc_page, hyperv_clocksource.129 clocksource_map = {130 CpuArchitecture.X64: [131 "hyperv_clocksource_tsc_page",132 "lis_hyperv_clocksource_tsc_page",133 "hyperv_clocksource",134 "tsc",135 ],136 CpuArchitecture.ARM64: [137 "arch_sys_counter",138 ],139 }140 lscpu = node.tools[Lscpu]141 arch = lscpu.get_architecture()142 clocksource = clocksource_map.get(CpuArchitecture(arch), None)143 if not clocksource:144 raise UnsupportedCpuArchitectureException(arch)145 cat = node.tools[Cat]146 clock_source_result = cat.run(self.current_clocksource)147 assert_that([clock_source_result.stdout]).described_as(148 f"Expected clocksource name is one of {clocksource},"149 f" but actual it is {clock_source_result.stdout}."150 ).is_subset_of(clocksource)151 # 2. Check CPU flag contains constant_tsc from /proc/cpuinfo.152 if CpuArchitecture.X64 == arch:153 cpu_info_result = cat.run("/proc/cpuinfo")154 if CpuType.Intel == lscpu.get_cpu_type():155 expected_tsc_str = " constant_tsc "156 elif CpuType.AMD == lscpu.get_cpu_type():157 expected_tsc_str = " tsc "158 shown_up_times = cpu_info_result.stdout.count(expected_tsc_str)159 assert_that(shown_up_times).described_as(160 f"Expected {expected_tsc_str} shown up times in cpu flags is"161 " equal to cpu count."162 ).is_equal_to(lscpu.get_core_count())163 # 3. Check clocksource name shown up in dmesg.164 dmesg = node.tools[Dmesg]165 assert_that(dmesg.get_output()).described_as(166 f"Expected clocksource {clock_source_result.stdout} shown up in dmesg."167 ).contains(f"clocksource {clock_source_result.stdout}")168 # 4. Unbind current clock source if there are 2+ clock sources,169 # check current clock source can be switched to a different one.170 if unbind:171 available_clocksources = cat.run(self.available_clocksource)172 available_clocksources_array = available_clocksources.stdout.split(" ")173 # We can not unbind clock source if there is only one existed.174 if len(available_clocksources_array) > 1:175 available_clocksources_array.remove(clock_source_result.stdout)176 cmd_result = node.execute(177 f"echo {clock_source_result.stdout} >"178 f" {self.unbind_clocksource}",179 sudo=True,180 shell=True,181 )182 cmd_result.assert_exit_code()183 clock_source_result_expected = _wait_file_changed(184 node, self.current_clocksource, available_clocksources_array185 )186 assert_that(clock_source_result_expected).described_as(187 f"After unbind {clock_source_result.stdout}, current clock"188 f" source doesn't switch properly."189 ).is_true()190 finally:191 # after unbind, need reboot vm to bring the previous time clock source back192 if unbind:193 node.reboot()194 remote_node = cast(RemoteNode, node)195 is_ready, _ = wait_tcp_port_ready(196 remote_node.public_address,197 remote_node.public_port,198 log=log,199 timeout=300,200 )201 if not is_ready:202 raise LisaException("vm is inaccessible after reboot.")203 @TestCaseMetadata(204 description="""205 This test is to check -206 1. Current clock event name is 'Hyper-V clockevent' for x86,207 'arch_sys_timer' for arm64.208 2. 'Hyper-V clockevent' or 'arch_sys_timer' and 'hrtimer_interrupt'209 show up times in /proc/timer_list should equal to cpu count.210 3. when cpu count is 1 and cpu type is Intel type, unbind current time211 clock event, check current time clock event switch to 'lapic'.212 """,213 priority=2,214 )215 def timesync_check_unbind_clockevent(self, node: Node) -> None:216 if node.shell.exists(PurePosixPath(self.current_clockevent)):217 # 1. Current clock event name is 'Hyper-V clockevent'.218 clockevent_map = {219 CpuArchitecture.X64: "Hyper-V clockevent",220 CpuArchitecture.ARM64: "arch_sys_timer",221 }222 lscpu = node.tools[Lscpu]223 arch = lscpu.get_architecture()224 clock_event_name = clockevent_map.get(CpuArchitecture(arch), None)225 if not clock_event_name:226 raise UnsupportedCpuArchitectureException(arch)227 cat = node.tools[Cat]228 clock_event_result = cat.run(self.current_clockevent)229 assert_that(clock_event_result.stdout).described_as(230 f"Expected clockevent name is {clock_event_name}, "231 f"but actual it is {clock_event_result.stdout}."232 ).is_equal_to(clock_event_name)233 # 2. 'Hyper-V clockevent' and 'hrtimer_interrupt' show up times in234 # /proc/timer_list should equal to cpu count.235 event_handler_name = "hrtimer_interrupt"236 timer_list_result = cat.run("/proc/timer_list", sudo=True)237 lscpu = node.tools[Lscpu]238 core_count = lscpu.get_core_count()239 event_handler_times = timer_list_result.stdout.count(240 f"{event_handler_name}"241 )242 assert_that(event_handler_times).described_as(243 f"Expected {event_handler_name} shown up {core_count} times in output "244 f"of /proc/timer_list, but actual it shows up "245 f"{event_handler_times} times."246 ).is_equal_to(core_count)247 clock_event_times = timer_list_result.stdout.count(f"{clock_event_name}")248 assert_that(clock_event_times).described_as(249 f"Expected {clock_event_name} shown up {core_count} times in output "250 f"of /proc/timer_list, but actual it shows up "251 f"{clock_event_times} times."252 ).is_equal_to(core_count)253 # 3. when cpu count is 1 and cpu type is Intel type, unbind current time254 # clock event, check current time clock event switch to 'lapic'.255 if CpuType.Intel == lscpu.get_cpu_type() and 1 == core_count:256 cmd_result = node.execute(257 f"echo {clock_event_name} > {self.unbind_clockevent}",258 sudo=True,259 shell=True,260 )261 cmd_result.assert_exit_code()262 clock_event_result_expected = _wait_file_changed(263 node, self.current_clockevent, "lapic"264 )265 assert_that(clock_event_result_expected).described_as(266 f"After unbind {clock_event_name}, current clock event should "267 f"equal to [lapic]."268 ).is_true()269 @TestCaseMetadata(270 description="""271 This test is to check, ntp works properly.272 1. Stop systemd-timesyncd if this service exists.273 2. Set rtc clock to system time.274 3. Restart Ntp service.275 4. Check and set server setting in config file.276 5. Restart Ntp service to reload with new config....
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!