Checking if a process still exists

Last edited on

Synopsis

It may be required to know when a process has exited, for example to ensure that following actions, steps and test cases do not run into an error when trying to start the same (still running) process/application again.

Python

# -*- coding: utf-8 -*-

# See
#  https://doc.qt.io/squish/squish-api.html#rgs-remotesystem
from remotesystem import RemoteSystem

import names


def main():
    ctx = startApplication("addressbook")

    #  https://doc.qt.io/squish/squish-api.html#application-context
    proc_guard = ProcessGuard(ctx)

    # Initiate AUT shutdown, here we
    # use ApplicationContext.detach(), as the test execution will end
    # if there are no hooked contexts:
    # See
    #  https://doc.qt.io/squish/squish-api.html#applicationcontext-detach-function
    ctx.detach()

    # Wait for process to have exited:
    proc_guard.wait_for_exit()


import sys
class ProcessGuard:
    def __init__(self,context,remote_os=None,platform=None):
        # Copy the properties from the context in variables, as the context object can become invalid

        self.current_pid = context.pid
        self.remote_os = remote_os
        if platform is None:
            # Squish Application Context has a property to get OS since Squish 6.6.0
            self.current_platform = getattr(context,'osName',None)
        else:
            self.current_platform = platform


    def wait_for_exit(self,timeout=60 * 1000):
        waitFor(self.process_exists, timeout)


    def process_exists(self):
        if self.remote_os is None:
            self.remote_os = RemoteSystem()

        possible_cmd = {
                'Windows' : [["wmic", "PROCESS", "where", "ProcessId={}".format(self.current_pid), "GET", "ProcessId"], (1,'ProcessId')],
                'Unix' : [["ps", "--pid", "{}".format(self.current_pid)], (0,'0')]
            }

        self.current_platform = self.determine_current_platform()

        try:
            cmd, (position,value) = possible_cmd[self.current_platform]
            result = str(self.remote_os.execute(cmd)[position])
            if result.startswith(value):
                test.log("Process still exists: PID: {}".format(self.current_pid))
                return False
            else:
                test.log('Process terminated')
                return True
        except KeyError:
            # Return to not wait for the timeout in waitFor
            test.fail('Unknown Platform "{}"'.format(self.current_platform))
            return True


    def determine_current_platform(self):
        '''
            Only works if squishrunner is on the same machine as the AUT
        '''
        if self.current_platform in ['Linux','Darwin']:
            return 'Unix'
        elif self.current_platform is None:
            if sys.platform == 'win32':
                self.current_platform = 'Windows'
            if sys.platform == 'darwin' or sys.platform.startswith('linux'):
                self.current_platform = 'Unix'
        return self.current_platform
test.py