Exemple #1
0
class CommandHost(local_host.LocalHost):
    """A CommandHost runs an executable through a command.

    The 'command' parameter specifies the command to use, while
    'command_args' contains a set of arguments to be passed to the
    command."""

    command = TextField(description="Name of the command"
                        " used to run the executable.")
    command_args = SetField(
        TextField(description="Set of arguments"
                  " passed to the command."))

    def Run(self,
            path,
            arguments,
            environment=None,
            timeout=-1,
            relative=False):

        if (relative
                or (not os.path.isabs(path) and
                    (path.find(os.path.sep) != -1 or
                     (os.path.altsep and path.find(os.path.altsep) != -1)))):
            path = os.path.join(os.curdir, path)
        arguments = self.command_args + [path] + arguments
        return local_host.LocalHost.Run(self, self.command, arguments,
                                        environment, timeout)
Exemple #2
0
class RemoteHost(ssh_host.SSHHost):

    # The wrapper script name to be used to invoke
    # remote programs
    wrapper = TextField()
    wrapper_args = SetField(TextField())

    def Run(self,
            path,
            arguments,
            environment=None,
            timeout=-1,
            relative=False):

        if self.wrapper:
            path = os.path.join(os.curdir, os.path.basename(path))
            arguments = [path] + arguments[:]
            path = self.wrapper
            if self.wrapper_args:
                arguments = self.wrapper_args + arguments[:]
        return super(RemoteHost, self).Run(path, arguments, environment,
                                           timeout, relative)

    def DeleteFile(self, remote_file):

        if self.default_dir:
            remote_file = os.path.join(self.default_dir, remote_file)
        super(RemoteHost, self).Run('rm', [remote_file])
Exemple #3
0
class RSHHost(SSHHost):
    """An 'RSHHost' is an 'SSHHost' that uses 'rsh' instead of 'ssh'.

    The reason that 'RSHHost' is a separate class is that (a) that
    makes it easier for users to construct an 'SSHHost', and (b) 'rsh'
    does not return the exit code of the remote program, so 'Run'
    requires adjustment."""

    # Override the default values.
    ssh_program = TextField(
        default_value = "rsh",
        description = """The path to the remote shell program."""
        )
    scp_program = TextField(
        default_value = "rcp",
        description = """The path to the remote copy program."""
        )

    def Run(self, path, arguments, environment = None, timeout = -1):

        status, output = \
                super(RSHHost, self).Run(path, arguments,
                                         environment, timeout)
        # The exit status of 'rsh' is not the exit status of the
        # remote program.  The exit status of the remote program is
        # unavailable. 
        return (None, output)
Exemple #4
0
class ExplicitSuite(qm.test.suite.Suite):
    """An 'ExplicitSuite' stores all of the test and suite ids explicitly."""

    arguments = [
        SetField(
            TextField(
                name="test_ids",
                title="Test Names",
                description="""The the tests contained in this suite.""")),
        SetField(
            TextField(
                name="suite_ids",
                title="Suite Names",
                description="""The the suites contained in this suite.""")),
        BooleanField(name="is_implicit",
                     title="Implicit?",
                     description="""\
                     True if this test is implicitly generated by QMTest.""",
                     default_value="false"),
    ]

    def IsImplicit(self):

        return self.is_implicit == "true"

    def GetTestIds(self):

        return self.test_ids

    def GetSuiteIds(self):

        return self.suite_ids
Exemple #5
0
class PreviousTestRun(ExpectationDatabase):
    """A 'PreviousTestRun' uses test results as expectations.

    A 'PreviousTestRun' uses a ResultsFile such as generated by
    'qmtest run' to determine the expected outcome for the current
    test run."""

    file_name = TextField(description="The name of the results file.")
    results_file = PythonField("The results file.")


    def __init__(self, **args):

        super(PreviousTestRun, self).__init__(**args)
        if not self.results_file:
            self.results_file = open(self.file_name, "rb")
        results = load_results(self.results_file, self.test_database)
        self._results = {}
        for r in results:
            # Keep test results only.
            if r.GetKind() == Result.TEST:
                self._results[r.GetId()] = r

        
    def Lookup(self, test_id):

        return self._results.get(test_id) or Result(Result.TEST, test_id)
class FileResultReader(ResultReader):
    """A 'FileResultReader' gets its input from a file.

    A 'FileResultReader' is an abstract base class for other result
    reader classes that read results from a single file.  The file
    from which results should be read can be specified using either
    the 'filename' argument or the 'file' argument.  The latter is for
    use by QMTest internally."""
    class InvalidFile(QMException):
        """An 'InvalidFile' exception indicates an incorrect file format.

        If the constructor for a 'FileResultStream' detects an invalid
        file, it must raise an instance of this exception."""

        pass

    arguments = [
        TextField(name="filename",
                  title="File Name",
                  description="""The name of the file.

            All results will be read from the file indicated.  If no
            filename is specified, or the filename specified is "-",
            the standard input will be used.""",
                  verbatim="true",
                  default_value=""),
        PythonField(name="file"),
    ]

    _is_binary_file = 0
    """If true, results are stored in a binary format.

    This flag can be overridden by derived classes."""

    def __init__(self, arguments=None, **args):
        """Construct a new 'FileResultReader'.

        'arguments' -- As for 'ResultReader'.

        If the file provided is not in the input format expected by this
        result reader, the derived class '__init__' function must raise
        an 'InvalidStream' exception."""

        super(FileResultReader, self).__init__(arguments, **args)

        if not self.file:
            if self.filename and self.filename != "-":
                if self._is_binary_file:
                    mode = "rb"
                else:
                    mode = "r"
                self.file = open(self.filename, mode, 0)
            else:
                self.file = sys.stdin
Exemple #7
0
class Simulator(LocalHost):
    """A 'Simulator' is a semi-hosted simulation environment.

    The local file system is shared with the simulated machine.  A
    simulator is used to execute programs."""

    simulator = TextField(
        description = """The simulation program."""
        )

    # Any arguments that must be provided to the simulator.
    simulator_args = SetField(
        TextField(description = """Arguments to the simulation program."""))
    
    def Run(self, path, arguments, environment = None, timeout = -1):

        arguments = self.simulator_args + [path] + arguments
        return super(Simulator, self.Run(self.simulator,
                                         arguments,
                                         environment,
                                         timeout))
Exemple #8
0
class RemoteHost(ssh_host.SSHHost):

    # The wrapper script name to be used to invoke
    # remote programs
    wrapper = TextField()

    def Run(self,
            path,
            arguments,
            environment=None,
            timeout=-1,
            relative=False):

        if self.wrapper:
            arguments = [path] + arguments[:]
            path = self.wrapper
        return super(RemoteHost, self).Run(path, arguments, environment,
                                           timeout, relative)
Exemple #9
0
class XMLExpectationDatabase(ExpectationDatabase):
    """An 'XMLExpectationDatabase' reads expectations from
    an XML file."""

    file_name = TextField()

    def __init__(self, **args):

        super(XMLExpectationDatabase, self).__init__(**args)
        self._expectations = []
        document = load_xml(open(self.file_name))
        root = document.documentElement
        for e in root.getElementsByTagName('expectation'):
            test_id = e.getAttribute('test_id')
            outcome = {
                'pass': Result.PASS,
                'fail': Result.FAIL,
            }[e.getAttribute('outcome')]
            filters = {}
            for a in e.getElementsByTagName('annotation'):
                filters[a.getAttribute('name')] = a.getAttribute('value')
            description = e.getElementsByTagName('description')
            if description: description = get_dom_text(description[0])
            self._expectations.append((test_id, outcome, filters, description))

    def Lookup(self, test_id):

        outcome, description = Result.PASS, ''
        for rule_id, rule_outcome, rule_annotations, rule_description in self._expectations:
            if re.match(rule_id, test_id):
                match = True
                for a in rule_annotations.iteritems():
                    if (a[0] not in self.testrun_parameters or
                            not re.match(a[1], self.testrun_parameters[a[0]])):
                        match = False
                if match:
                    outcome = rule_outcome
                    description = rule_description
        return Result(Result.TEST,
                      test_id,
                      outcome,
                      annotations={'description': description})
Exemple #10
0
class SSHHost(Host):
    """An 'SSHHost' is accessible via 'ssh' or a similar program."""

    # If not empty, the name of the remote host. 
    host_name = TextField()
    # The path to "ssh".
    ssh_program = TextField(
        default_value = "ssh",
        description = """The path to the remote shell program."""
        )
    # Any arguments that must be provided to "ssh". 
    ssh_args = SetField(
        TextField(description =
                  """The arguments to the remote shell program."""))
    # The path to "scp".
    scp_program = TextField(
        default_value = "scp",
        description = """The path to the remote copy program."""
        )
    # Any arguments that must be provided to "scp".
    scp_args = SetField(
        TextField(description =
                  """The arguments to the remote copy program."""))
    # The default directory on the remote system.
    default_dir = TextField(
        description = """The default directory on the remote system."""
        )

    nfs_dir = TextField(
        description = """The default directory, as seen from the local host.
    
        If not empty, 'nfs_dir' is a directory on the local machine
        that is equivalent to the default directory on the remote
        machine.  In that case, files will be copied to and from this
        directory on the local machine, rather than by using
        'scp'."""
        )

    user_name = TextField(
        description = """The user name on the remote host.

        If not empty, the user name that should be used when
        connecting to the remote host."""
        )
    
    def Run(self, path, arguments, environment = None, timeout = -1,
            relative = False):

        default_dir = self.default_dir
        if not default_dir:
            default_dir = os.curdir
        if (relative
            or (not os.path.isabs(path)
                and (path.find(os.path.sep) != -1
                     or (os.path.altsep
                         and path.find(os.path.altsep) != -1)))):
            path = os.path.join(default_dir, path)
        path, arguments = self._FormSSHCommandLine(path, arguments,
                                                   environment)
        return super(SSHHost, self).Run(path, arguments, None, timeout)


    def UploadFile(self, local_file, remote_file = None):

        if remote_file is None:
            remote_file = os.path.basename(local_file)
        if self.nfs_dir:
            remote_file = os.path.join(self.nfs_dir, remote_file)
            super(SSHHost, self).UploadFile(local_file, remote_file)
        else:    
            if self.default_dir:
                remote_file = os.path.join(self.default_dir, remote_file)
            command = self._FormSCPCommandLine(True, local_file,
                                               remote_file)
            executable = self.Executable()
            status = executable.Run(command)
            if ((sys.platform != "win32"
                 and (not os.WIFEXITED(status)
                      or os.WEXITSTATUS(status) != 0))
                or (sys.platform == "win32" and status != 0)):
                raise qm.common.QMException("could not upload file")
        

    def DownloadFile(self, remote_file, local_file = None):

        if local_file is None:
            local_file = os.path.basename(remote_file)
        if self.nfs_dir:
            remote_file = os.path.join(self.nfs_dir, remote_file)
            super(SSHHost, self).DownloadFile(remote_file, local_file)
        else:
            if self.default_dir:
                remote_file = os.path.join(self.default_dir, remote_file)
            command = self._FormSCPCommandLine(False, local_file,
                                               remote_file)
            executable = self.Executable()
            executable.Run(command)


    def DeleteFile(self, remote_file):

        if self.default_dir:
            remote_file = os.path.join(self.default_dir, remote_file)
        return self.Run("rm", [remote_file])

        
    def _FormSSHCommandLine(self, path, arguments, environment = None):
        """Form the 'ssh' command line.

        'path' -- The remote command, in the same format expected by
        'Run'. 
        
        'arguments' -- The arguments to the remote command.

        'environment' -- As for 'Run'.

        returns -- A pair '(path, arguments)' describing the command
        to run on the local machine that will execute the remote
        command."""

        command = self.ssh_args + [self.host_name]
        if self.user_name:
            command += ["-l", self.user_name]
        if environment is not None:
            command.append("env")
            for (k, v) in environment.iteritems():
                command.append("%s=%s" % (k, v))
        command.append(path)
        command += arguments

        return self.ssh_program, command


    def _FormSCPCommandLine(self, upload, local_file, remote_file):
        """Form the 'scp' command line.

        'upload' -- True iff the 'local_file' should be copied to the
        remote host.

        'local_file' -- The path to the local file.

        'remote_file' -- The path to the remote file.

        returns -- The list of arguments for a command to run on the
        local machine that will perform the file copy."""

        if self.default_dir:
            remote_file = os.path.join(self.default_dir, remote_file)
        remote_file = self.host_name + ":" + remote_file
        if self.user_name:
            remote_file = self.user_name + "@" + remote_file
        command = [self.scp_program] + self.scp_args
        if upload:
            command += [local_file, remote_file]
        else:
            command += [remote_file, local_file]

        return command