@@ -176,13 +176,23 @@ def wait_for_vm_running_and_ssh_up(self):
176176 self .wait_for_os_booted ()
177177 wait_for (self .is_ssh_up , "Wait for SSH up" )
178178
179- def ssh_touch_file (self , filepath ):
179+ def touch_file (self , filepath ):
180+ """
181+ Make sure that a file exists. Do not change file contents.
182+
183+ On Windows, it uses PowerShell path format and may not update timestamps.
184+ """
180185 logging .info ("Create file on VM (%s)" % filepath )
181- self .ssh (['touch' , filepath ])
182- if not self .is_windows :
186+ if self .is_windows :
187+ self .execute_powershell_script (f'New-Item -ErrorAction SilentlyContinue -Type File -Path { filepath } ' )
188+ else :
189+ self .ssh (['touch' , filepath ])
183190 self .ssh (['sync' , filepath ])
184191 logging .info ("Check file created" )
185- self .ssh (['test -f ' + filepath ])
192+ if self .is_windows :
193+ assert self .file_exists (filepath )
194+ else :
195+ self .ssh (['test -f ' + filepath ])
186196
187197 def suspend (self , verify = False ):
188198 logging .info ("Suspend VM" )
@@ -403,7 +413,18 @@ def start_background_process(self, cmd: str) -> str:
403413 return pid
404414
405415 def pid_exists (self , pid ):
406- return self .ssh_with_result (['kill' , '-s' , '0' , pid ]).returncode == 0
416+ if self .is_windows :
417+ return strtobool (
418+ self .execute_powershell_script (f'$null -ne (Get-Process -Id { pid } -ErrorAction SilentlyContinue)' )
419+ )
420+ else :
421+ return self .ssh_with_result (['kill' , '-s' , '0' , pid ]).returncode == 0
422+
423+ def kill_process (self , pid ):
424+ if self .is_windows :
425+ self .execute_powershell_script (f'Get-Process -Id { pid } | Stop-Process' )
426+ else :
427+ self .ssh (['kill ' + pid ])
407428
408429 def execute_script (self , script_contents , simple_output = True ):
409430 with tempfile .NamedTemporaryFile ('w' ) as f :
@@ -443,9 +464,16 @@ def tools_version(self):
443464 return "{major}.{minor}.{micro}-{build}" .format (** version_dict )
444465
445466 def file_exists (self , filepath , regular_file = True ):
446- """Returns True if the file exists, otherwise returns False."""
447- option = '-f' if regular_file else '-e'
448- return self .ssh_with_result (['test' , option , filepath ]).returncode == 0
467+ """
468+ Returns True if the file exists, otherwise returns False.
469+
470+ regular_file does not apply to Windows.
471+ """
472+ if self .is_windows :
473+ return strtobool (self .execute_powershell_script (f'Test-Path { filepath } ' ))
474+ else :
475+ option = '-f' if regular_file else '-e'
476+ return self .ssh_with_result (['test' , option , filepath ]).returncode == 0
449477
450478 def detect_package_manager (self ):
451479 """ Heuristic to determine the package manager on a unix distro. """
@@ -472,13 +500,16 @@ def test_snapshot_on_running_vm(self):
472500 self .wait_for_vm_running_and_ssh_up ()
473501 snapshot = self .snapshot ()
474502 try :
475- filepath = '/tmp/%s' % snapshot .uuid
476- self .ssh_touch_file (filepath )
503+ if self .is_windows :
504+ filepath = fr'$Env:Temp\{ snapshot .uuid } '
505+ else :
506+ filepath = '/tmp/%s' % snapshot .uuid
507+ self .touch_file (filepath )
477508 snapshot .revert ()
478509 self .start ()
479510 self .wait_for_vm_running_and_ssh_up ()
480511 logging .info ("Check file does not exist anymore" )
481- self .ssh ([ 'test ! -f ' + filepath ] )
512+ assert not self .file_exists ( filepath )
482513 finally :
483514 snapshot .destroy (verify = True )
484515
@@ -769,15 +800,16 @@ def run_powershell_command(self, program: str, args: str):
769800
770801 def start_background_powershell (self , cmd : str ):
771802 """
772- Run command under powershell in the background.
803+ Run command under powershell in the background. Return the resulting PID.
773804
774805 Backslash-safe.
775806 """
776807 assert self .is_windows
777808 encoded_command = commands .encode_powershell_command (cmd )
778- self .ssh (
809+ return self .ssh (
779810 "powershell.exe -noprofile -noninteractive Invoke-WmiMethod -Class Win32_Process -Name Create "
780- f"-ArgumentList \\ 'powershell.exe -noprofile -noninteractive -encodedcommand { encoded_command } \\ '"
811+ f"-ArgumentList \\ 'powershell.exe -noprofile -noninteractive -encodedcommand { encoded_command } \\ ' \\ |"
812+ "Select-Object -Expand ProcessId"
781813 )
782814
783815 def is_windows_pv_device_installed (self ):
0 commit comments