def start(self):
        '''Start the test process
        '''
        if self._process:
            raise Exception("there is already a running process")

        for listener in self._listeners:
            listener.reset()

        here = os.path.abspath(os.path.dirname(__file__))
        socket_listener = os.path.join(here,
                                       "socket_listener.py:%s" % self._port)

        full_args = [
            "--listener", socket_listener, "--log", "NONE", "--report", "NONE"
        ] + self._args
        cmd = shlex.split(self._runner) + full_args
        logging.debug("command: " + " ".join(cmd))

        self._process = Process(cmd, cwd=self._cwd)
        self._listen("start_job", cmd)
        if self._poll_job_id is not None:
            self._parent.after_cancel(self._poll_job_id)
            self._poll_job_id = None
        self.poll(100)
Exemplo n.º 2
0
    def start(self):
        '''Start the test process
        '''
        if self._process:
            raise Exception("there is already a running process")

        for listener in self._listeners:
            listener.reset()

        here = os.path.abspath(os.path.dirname(__file__))
        socket_listener = os.path.join(here, "socket_listener.py:%s" % self._port)

        full_args = ["--listener", socket_listener, "--log", "NONE", 
                     "--report", "NONE"] + self._args
        cmd = shlex.split(self._runner) + full_args
        logging.debug("command: " + " ".join(cmd))

        self._process = Process(cmd, cwd=self._cwd)
        self._listen("start_job", cmd)
        if self._poll_job_id is not None:
            self._parent.after_cancel(self._poll_job_id)
            self._poll_job_id = None
        self.poll(100)
class RobotController(object):
    '''A class for controlling the execution of a robot test
    
    This class does *not* run the test; that is done in a separate
    process. What this class does is monitor the output, and acts
    as a listener (listening to the running test via a socket). 

    Special GUI listeners may be associated with this controller.
    Each message that comes back from the running robot test is
    forwarded to each of these GUI listeners. 

    These listeners must provide a "listen" method which accepts an
    id, an event name (one of the supported robot listener messages
    such as 'start_suite', 'start_test', etc), and then zero or more
    additional arguments.

    '''
    def __init__(self, parent, runner="python -m robot.runner"):
        self._parent = parent
        self._listener = RemoteRobotListener(parent, self._listen)
        self._port = self._listener.port
        self._poll_job_id = None
        self._process = None
        self._listeners = []
        self._args = []
        self._cwd = os.getcwd()
        self._runner = runner

        # every event gets an id, a simple incrementing integer. The plan
        # is that each display (console, log, etc) will be able to jump
        # to the related item in some other display using this id (ie:
        # from the message window you can jump to the details window or
        # visa versa) (this isn't implemented yet...)
        #
        # (of course, most events have timestamps that could serve
        # the same purpose... need to think harder about this some day)
        self._id = 0

    def __del__(self):
        try:
            if self._poll_job_id is not None:
                self.after_cancel(self._poll_job_id)
        except:
            pass

    def configure(self, args=None, listeners=None, runner=None, cwd=None):
        '''Configure the runner
        args - the arguments to pass to the runner
        listeners - a list of listeners (actually, MVC views)
        runner - the command to start a test run
        '''
        if args is not None: self._args = args
        if listeners is not None: self._listeners = listeners
        if runner is not None: self._runner = runner
        if cwd is not None: self._cwd = cwd

    def start(self):
        '''Start the test process
        '''
        if self._process:
            raise Exception("there is already a running process")

        for listener in self._listeners:
            listener.reset()

        here = os.path.abspath(os.path.dirname(__file__))
        socket_listener = os.path.join(here,
                                       "socket_listener.py:%s" % self._port)

        full_args = [
            "--listener", socket_listener, "--log", "NONE", "--report", "NONE"
        ] + self._args
        cmd = shlex.split(self._runner) + full_args
        logging.debug("command: " + " ".join(cmd))

        self._process = Process(cmd, cwd=self._cwd)
        self._listen("start_job", cmd)
        if self._poll_job_id is not None:
            self._parent.after_cancel(self._poll_job_id)
            self._poll_job_id = None
        self.poll(100)

    def poll(self, delay):
        '''Poll the running process for data on stdout and stderr'''
        if self._process:
            (stdout, stderr) = self._process.read()

            if stdout: self._listen("stdout", stdout)
            if stderr: self._listen("stderr", stderr)

            if self._process.exit_code() is not None:
                # It's dead, Jim.
                self._listen("stop_job", self._process.exit_code())
                del self._process
                self._process = None

            self._poll_job_id = self._parent.after(delay, self.poll, delay)

    def _listen(self, name, *args):
        '''Forward messages to each registered listener'''
        self._id += 1
        for listener in self._listeners:
            listener.listen(self._id, name, args)

    def stop(self):
        if self._process:
            self._process.terminate()
Exemplo n.º 4
0
class RobotController(object):
    '''A class for controlling the execution of a robot test
    
    This class does *not* run the test; that is done in a separate
    process. What this class does is monitor the output, and acts
    as a listener (listening to the running test via a socket). 

    Special GUI listeners may be associated with this controller.
    Each message that comes back from the running robot test is
    forwarded to each of these GUI listeners. 

    These listeners must provide a "listen" method which accepts an
    id, an event name (one of the supported robot listener messages
    such as 'start_suite', 'start_test', etc), and then zero or more
    additional arguments.

    '''
    def __init__(self, parent, runner="python -m robot.runner"):
        self._parent = parent
        self._listener = RemoteRobotListener(parent, self._listen)
        self._port = self._listener.port
        self._poll_job_id = None
        self._process = None
        self._listeners = []
        self._args = []
        self._cwd = os.getcwd()
        self._runner = runner

        # every event gets an id, a simple incrementing integer. The plan
        # is that each display (console, log, etc) will be able to jump
        # to the related item in some other display using this id (ie:
        # from the message window you can jump to the details window or
        # visa versa) (this isn't implemented yet...)
        #
        # (of course, most events have timestamps that could serve
        # the same purpose... need to think harder about this some day)
        self._id = 0

    def __del__(self):
        try:
            if self._poll_job_id is not None:
                self.after_cancel(self._poll_job_id)
        except:
            pass

    def configure(self, args=None, listeners=None, runner=None, cwd=None):
        '''Configure the runner
        args - the arguments to pass to the runner
        listeners - a list of listeners (actually, MVC views)
        runner - the command to start a test run
        '''
        if args is not None: self._args = args
        if listeners is not None: self._listeners = listeners
        if runner is not None: self._runner = runner
        if cwd is not None: self._cwd = cwd

    def start(self):
        '''Start the test process
        '''
        if self._process:
            raise Exception("there is already a running process")

        for listener in self._listeners:
            listener.reset()

        here = os.path.abspath(os.path.dirname(__file__))
        socket_listener = os.path.join(here, "socket_listener.py:%s" % self._port)

        full_args = ["--listener", socket_listener, "--log", "NONE", 
                     "--report", "NONE"] + self._args
        cmd = shlex.split(self._runner) + full_args
        logging.debug("command: " + " ".join(cmd))

        self._process = Process(cmd, cwd=self._cwd)
        self._listen("start_job", cmd)
        if self._poll_job_id is not None:
            self._parent.after_cancel(self._poll_job_id)
            self._poll_job_id = None
        self.poll(100)

    def poll(self, delay):
        '''Poll the running process for data on stdout and stderr'''
        if self._process:
            (stdout, stderr) = self._process.read()

            if stdout: self._listen("stdout", stdout)
            if stderr: self._listen("stderr", stderr)

            if self._process.exit_code() is not None:
                # It's dead, Jim.
                self._listen("stop_job", self._process.exit_code())
                del self._process
                self._process = None

            self._poll_job_id = self._parent.after(delay, self.poll, delay)

    def _listen(self, name, *args):
        '''Forward messages to each registered listener'''
        self._id += 1
        for listener in self._listeners:
            listener.listen(self._id, name, args)

    def stop(self):
        if self._process:
            self._process.terminate()