Skip to content

Commit 0d467f1

Browse files
authored
Merge pull request #588 from xcp-ng/dnt/fix-test-checkpoint
Fix test_checkpoint on Windows
2 parents 32915b9 + f323578 commit 0d467f1

2 files changed

Lines changed: 30 additions & 11 deletions

File tree

lib/vm.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,8 @@ def get_residence_host(self) -> Host:
412412
return self.host.pool.get_host_by_uuid(host_uuid)
413413

414414
def start_background_process(self, cmd: str) -> str:
415+
if self.is_windows:
416+
logging.warning('start_background_process is not reliable on Windows')
415417
script = "/tmp/bg_process.sh"
416418
pidfile = "/tmp/bg_process.pid"
417419
with tempfile.NamedTemporaryFile('w') as f:
@@ -443,8 +445,19 @@ def start_background_process(self, cmd: str) -> str:
443445
self.ssh(f'rm -f {pidfile}')
444446
return str(pid)
445447

446-
def pid_exists(self, pid: str) -> bool:
447-
return self.ssh_with_result(f'kill -s 0 {pid}').returncode == 0
448+
def pid_exists(self, pid: str, winpid: bool = False) -> bool:
449+
if self.is_windows and winpid:
450+
return strtobool(
451+
self.execute_powershell_script(f"$null -ne (Get-Process -Id {pid} -ErrorAction SilentlyContinue)")
452+
)
453+
else:
454+
return self.ssh_with_result(f'kill -s 0 {pid}').returncode == 0
455+
456+
def kill_pid(self, pid: str, winpid: bool = False) -> None:
457+
if self.is_windows and winpid:
458+
self.execute_powershell_script(f"Stop-Process -Id {pid} -Force -ErrorAction SilentlyContinue")
459+
else:
460+
self.ssh(f'kill {pid}')
448461

449462
@overload
450463
def execute_script(self, script_contents: str, *, simple_output: Literal[True] = True) -> str:
@@ -818,17 +831,19 @@ def run_powershell_command(self, program: str, args: str) -> int:
818831
f"Write-Output (Start-Process -Wait -PassThru {program} -ArgumentList '{args}').ExitCode")
819832
return int(output)
820833

821-
def start_background_powershell(self, cmd: str) -> None:
834+
def start_background_powershell(self, cmd: str) -> str:
822835
"""
823-
Run command under powershell in the background.
836+
Run command under powershell in the background. Return the PID as string.
824837
825838
Backslash-safe.
826839
"""
827840
assert self.is_windows
828841
encoded_command = commands.encode_powershell_command(cmd)
829-
self.ssh(
830-
"powershell.exe -noprofile -noninteractive Invoke-WmiMethod -Class Win32_Process -Name Create "
842+
return self.ssh(
843+
"powershell.exe -noprofile -noninteractive -command \\("
844+
"Invoke-WmiMethod -Class Win32_Process -Name Create "
831845
f"-ArgumentList \\'powershell.exe -noprofile -noninteractive -encodedcommand {encoded_command}\\'"
846+
"\\).ProcessId"
832847
)
833848

834849
def is_windows_pv_device_installed(self) -> bool:

tests/misc/test_vm_basic_operations.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@ def test_snapshot(self, running_vm: VM) -> None:
2323
vm = running_vm
2424
vm.test_snapshot_on_running_vm()
2525

26-
# When using a windows VM the background ssh process is never terminated
26+
# When running the tests on Windows, the background ssh process is never terminated
2727
# This results in a ResourceWarning
2828
@pytest.mark.filterwarnings("ignore::ResourceWarning")
2929
def test_checkpoint(self, running_vm: VM) -> None:
3030
vm = running_vm
3131
logging.info("Start a 'sleep' process on VM through SSH")
32-
pid = vm.start_background_process('sleep 10000')
32+
if vm.is_windows:
33+
pid = vm.start_background_powershell('Start-Sleep -Seconds 10000')
34+
else:
35+
pid = vm.start_background_process('sleep 10000')
36+
logging.info(f"Background task PID: {pid}")
3337
snapshot = vm.checkpoint()
3438
filepath = '/tmp/%s' % snapshot.uuid
3539
vm.ssh_touch_file(filepath)
@@ -39,8 +43,8 @@ def test_checkpoint(self, running_vm: VM) -> None:
3943
logging.info("Check file does not exist anymore")
4044
vm.ssh(f'test ! -f {filepath}')
4145
logging.info("Check 'sleep' process is still running")
42-
assert vm.pid_exists(pid)
46+
assert vm.pid_exists(pid, winpid=True)
4347
logging.info("Kill background process")
44-
vm.ssh(f'kill {pid}')
45-
wait_for_not(lambda: vm.pid_exists(pid), "Wait for process %s not running anymore" % pid)
48+
vm.kill_pid(pid, winpid=True)
49+
wait_for_not(lambda: vm.pid_exists(pid, winpid=True), "Wait for process %s not running anymore" % pid)
4650
snapshot.destroy(verify=True)

0 commit comments

Comments
 (0)