diff --git a/lisa/microsoft/testsuites/performance/common.py b/lisa/microsoft/testsuites/performance/common.py index ac8d38e793..533fbbbfc6 100644 --- a/lisa/microsoft/testsuites/performance/common.py +++ b/lisa/microsoft/testsuites/performance/common.py @@ -340,10 +340,16 @@ def perf_ntttcp( # noqa: C901 else: connections = NTTTCP_TCP_CONCURRENCY - client_ntttcp, server_ntttcp = run_in_parallel( - [lambda: client.tools[Ntttcp], lambda: server.tools[Ntttcp]] # type: ignore - ) + # Initialize variables before try block + client_lagscope = None + server_lagscope = None + client_ntttcp = None + server_ntttcp = None + try: + client_ntttcp, server_ntttcp = run_in_parallel( + [lambda: client.tools[Ntttcp], lambda: server.tools[Ntttcp]] # type: ignore + ) client_lagscope, server_lagscope = run_in_parallel( [ lambda: client.tools[Lagscope], # type: ignore @@ -609,6 +615,9 @@ def perf_ntttcp( # noqa: C901 ) notifier.notify(ntttcp_message) perf_ntttcp_message_list.append(ntttcp_message) + except Exception as ex: + client.log.info(f"Exception during ntttcp performance test: {ex}") + raise finally: error_msg = "" throw_error = False @@ -619,11 +628,13 @@ def perf_ntttcp( # noqa: C901 if throw_error: error_msg += "probably due to VM stuck on reboot stage." raise LisaException(error_msg) - for ntttcp in [client_ntttcp, server_ntttcp]: - ntttcp.restore_system(udp_mode) - for lagscope in [client_lagscope, server_lagscope]: - lagscope.kill() - lagscope.restore_busy_poll() + if client_ntttcp and server_ntttcp: + for ntttcp in [client_ntttcp, server_ntttcp]: + ntttcp.restore_system(udp_mode) + if client_lagscope and server_lagscope: + for lagscope in [client_lagscope, server_lagscope]: + lagscope.kill() + lagscope.restore_busy_poll() return perf_ntttcp_message_list @@ -778,6 +789,6 @@ def check_sriov_count(node: RemoteNode, sriov_count: int) -> None: node_nic_info.reload() assert_that(len(node_nic_info.get_lower_nics())).described_as( - f"VF count inside VM is {len(node_nic_info.get_lower_nics())}," + f"VF count inside VM is {len(node_nic_info.get_lower_nics())}, " f"actual sriov nic count is {sriov_count}" ).is_equal_to(sriov_count) diff --git a/lisa/operating_system.py b/lisa/operating_system.py index 61dd86b650..d0d64994a2 100644 --- a/lisa/operating_system.py +++ b/lisa/operating_system.py @@ -1904,7 +1904,7 @@ def _package_exists(self, package: str) -> bool: return False def _is_package_in_repo(self, package: str) -> bool: - command = f"yum --showduplicates list {package}" + command = f"yum --showduplicates -y list {package}" result = self._node.execute(command, sudo=True, shell=True) return 0 == result.exit_code diff --git a/lisa/sut_orchestrator/azure/tools.py b/lisa/sut_orchestrator/azure/tools.py index e48e871ec1..ac9e88f7a2 100644 --- a/lisa/sut_orchestrator/azure/tools.py +++ b/lisa/sut_orchestrator/azure/tools.py @@ -103,14 +103,38 @@ def upgrade_from_source(self, source_version: str = "") -> None: for package in list(["python-setuptools", "python3-setuptools"]): if self.node.os.is_package_in_repo(package): # type: ignore self.node.os.install_packages(package) # type: ignore - self.node.execute( - f"{python_cmd} setup.py install --force", + + # Downgrading setuptools is required because: + # 1. Old WALinuxAgent versions have compatibility issues with pip's build + # isolation (missing 'distro' module, deprecated platform APIs) + # 2. The legacy 'setup.py install' works but requires compatible setuptools + downgrade_result = self.node.execute( + f"{python_cmd} -m pip install 'setuptools<71' --force-reinstall", sudo=True, - cwd=self.node.working_path.joinpath("WALinuxAgent"), - expected_exit_code=0, - expected_exit_code_failure_message="Failed to install waagent", ) + if downgrade_result.exit_code != 0: + self._log.debug( + "Failed to downgrade setuptools, trying pip install instead" + ) + # Fallback: try pip install with --no-build-isolation to avoid + # downloading latest setuptools in isolated environment + self.node.execute( + f"{python_cmd} -m pip install --no-build-isolation .", + sudo=True, + cwd=self.node.working_path.joinpath("WALinuxAgent"), + expected_exit_code=0, + expected_exit_code_failure_message="Failed to install waagent", + ) + else: + self.node.execute( + f"{python_cmd} setup.py install --force", + sudo=True, + cwd=self.node.working_path.joinpath("WALinuxAgent"), + expected_exit_code=0, + expected_exit_code_failure_message="Failed to install waagent", + ) + def restart(self) -> None: service = self.node.tools[Service] if isinstance(self.node.os, Debian): @@ -220,7 +244,7 @@ def _get_waagent_conf_path(self) -> str: # Try to use waagent code to detect result = self.node.execute( - f'{python_cmd} -c "from azurelinuxagent.common.osutil import get_osutil;' + f'{python_cmd} -c "from azurelinuxagent.common.osutil import get_osutil; ' 'print(get_osutil().agent_conf_file_path)"', sudo=use_sudo, ) @@ -250,7 +274,7 @@ def get_distro_version(self) -> str: # Try to use waagent code to detect result = self.node.execute( - f'{python_cmd} -c "from azurelinuxagent.common.version import get_distro;' + f'{python_cmd} -c "from azurelinuxagent.common.version import get_distro; ' "print('-'.join(get_distro()[0:3]))\"", sudo=use_sudo, ) @@ -259,7 +283,7 @@ def get_distro_version(self) -> str: else: # try to compat with old waagent versions result = self.node.execute( - f'{python_cmd} -c "import platform;' + f'{python_cmd} -c "import platform; ' "print('-'.join(platform.linux_distribution(0)))\"", sudo=use_sudo, ) diff --git a/lisa/tools/lagscope.py b/lisa/tools/lagscope.py index 28f4e781b8..ef995d68cf 100644 --- a/lisa/tools/lagscope.py +++ b/lisa/tools/lagscope.py @@ -402,6 +402,37 @@ def _install(self) -> bool: git = self.node.tools[Git] git.clone(self.repo, tool_path, ref=self.branch) code_path = tool_path.joinpath("lagscope") + + src_path = code_path.joinpath("src") + + # Get the installed CMake version dynamically + cmake_version_result = self.node.execute( + "cmake --version | head -n1 | grep -oP '\\d+\\.\\d+'", + shell=True, + ) + + if cmake_version_result.exit_code == 0 and cmake_version_result.stdout.strip(): + cmake_version = cmake_version_result.stdout.strip() + self._log.debug(f"Detected CMake version: {cmake_version}") + else: + # Fallback to a safe minimum version if detection fails + cmake_version = "3.5" + self._log.debug( + f"Could not detect CMake version, using fallback: {cmake_version}" + ) + + # Update CMakeLists.txt with the detected version + self.node.execute( + f"sed -i 's/cmake_minimum_required(VERSION [0-9.]\\+)/" + f"cmake_minimum_required(VERSION {cmake_version})/' " + f"{src_path}/CMakeLists.txt", + cwd=code_path, + sudo=True, + shell=True, + expected_exit_code=0, + expected_exit_code_failure_message="fail to update src/CMakeLists.txt", + ) + self.node.execute( "./do-cmake.sh build", cwd=code_path,