示例#1
0
 def _gotEnvironment(self, resdict):
     info("Got environment %r", resdict)
     self._environment = resdict
     self.emit("start")
     self._starttime = int(time.time())
     self._storage.startNewTestRun(self, self._clientid)
     self._runNextBatch()
 def next(self):
     if not self._initialized:
         self._initialize()
     if not self.globalidx < self.combinations:
         raise StopIteration
     # return the next dict of arguments
     # contains a copy of all static arguments
     # plus the next combination of generators
     res = self.statics.copy()
     if self.generators:
         info("we have generators")
         # extend with current generator values
         for key in self.genlist:
             info("key")
             gen, idx = self.generators[key][:2]
             # split generator name
             keys = key.split(",")
             if len(keys) > 1:
                 if isinstance(gen[idx],list):
                   gens = gen[idx]
                 else:
                   gens = gen[idx].split(",")
                 for i in range(len(keys)):
                     res[keys[i]] = gens[i]
             else:
                 res[keys[0]] = gen[idx]
         # update values
         self._updateGeneratorsPosition()
     # update global idx
     self.globalidx += 1
     return res
    def tearDownVmethod(self):
        info("uuid:%s", self.uuid)
        # FIXME : tear down the other process gracefully
        #    by first sending it the termination remote signal
        #    and then checking it's killed
        try:
            self.callRemoteTearDown()
        finally:
            if self._testrun:
                if self._newremotetestsid:
                    self._testrun.disconnect(self._newremotetestsid)
                    self._newremotetestsid = 0
                if self._testrunremovedtestsigid:
                    self._testrun.disconnect(self._testrunremovedtestsigid)
                    self._testrunremovedtestsigid = 0
            if self._processpollid:
                gobject.source_remove(self._processpollid)
                self._processpollid = 0
            if self._process:
                # double check it hasn't actually exited
                # give the test up to one second to exit
                if self._returncode is None:
                    self._returncode = utils.kill_process (self._process)
                self._process = None
                if self._redir_tty_thread is not None:
                    self._redir_tty_thread.exit()
                    self._redir_tty_thread = None
            if not self._returncode is None:
                info("Process returned %d", self._returncode)
                self.extraInfo("subprocess-return-code", self._returncode)

            self.validateChecklistItem("subprocess-exited-normally", self._returncode == 0)
示例#4
0
 def test(self):
     info("uuid:%s proxy:%r", self.uuid, self._isproxy)
     if self._isproxy:
         self.callRemoteTest()
     else:
         # really do the test
         raise Exception("I shouldn't be called ! I am the remote test !")
示例#5
0
    def remoteTearDown(self):
        """
        Remote-side tearDown() method.

        Subclasses wishing to clean up their tests or collect information to
        send at the end, should implement this in their subclass and chain up
        to the parent remoteTearDown() at the *beginning of their
        implementation.

        If the parent method returns False, return False straight-away
        """
        if self._remote_tearing_down:
            return False
        self._remote_tearing_down = True
        info("%s remoteTimeoutId:%r", self.uuid, self._remotetimeoutid)

        if self.rusage_start:
            usage = resource.getrusage(resource.RUSAGE_SELF)
            rusage_end = (time.time(), usage.ru_utime, usage.ru_stime)
            rusage_diffs = [end - start for start, end in zip(self.rusage_start, rusage_end)]
            real_time, user_time, system_time = rusage_diffs
            if real_time:
                cpu_load = float(user_time + system_time) / real_time * 100.0
                self.extraInfo("cpu-load", cpu_load)

        # remote the timeout
        if self._remotetimeoutid:
            gobject.source_remove(self._remotetimeoutid)
            self._remotetimedout = False
            self._remotetimeoutid = 0
        self.validateStep("no-timeout", not self._remotetimedout)
        return True
    def validateChecklistItem(self, checkitem, validated=True, description = None):
        """
        Validate a checklist item in the checklist.
        checkitem is one of the keys of __test_checklist__
        validated is a boolean indicating whether that item should be
           validated or not.

        Called by the test itself
        """
        info("checklist item %s for item %r : %r" % (checkitem, self, validated))
        # check for valid checkitem
        if not checkitem in self._possiblechecklist:
            return
        # check to see if we don't already have it
        if checkitem in dict(self._checklist):
            return
        self._checklist.append((checkitem, bool(validated)))

        if not validated:
            if self.isExpectedFailure(checkitem, self._extrainfo):
                self._expected_failures[checkitem] = True
            if description and description != "":
                explanation = description
            else:
                explanation = self.processFailure(checkitem, self._extrainfo)
            if explanation is not None:
                self._error_explanations[checkitem] = explanation

        self.emit("check", checkitem, validated)
示例#7
0
 def stop(self):
     info("uuid:%s proxy:%r", self.uuid, self._isproxy)
     if self._isproxy:
         Test.stop(self)
     else:
         self.tearDown()
         self.remoteStopSignal()
    def _start(self, glob):
        desc = self.arguments.get("desc")
        basename = self.arguments.get("outputfile-basename")
        category = self.arguments.get("category")

        files = []
        paths = {}
        if desc:
            info("No path set, trying to use stdout and stding specific files")
            if not 'stderr' in desc and not 'stdout' in desc:
                warning("Neither of stdout-path, stderr-path and path specified"
                        "Can not use the monitor")
                return False

            if 'stderr' in desc:
                stderr_file, stderr_path = self._getTempFiles(basename, "stderr", glob, category)

                self.test.setStderr(stderr_file)
                files.append(stderr_file)
                paths["stderr-file"] = stderr_path

            if 'stdout' in desc:
                stdout_file, stdout_path = self._getTempFiles(basename, "stdout", glob, category)

                self.test.setStdout(stdout_file)
                files.append(stdout_file)
                paths["stdout-file"] = stdout_path
        else:
            _file, path = self._getTempFiles(basename, "stdoutanderr", glob, category)

            self.test.setStdOutAndErr(path)
            files.append(_file)
            paths["stdout-and-stderr-file"] = path

        return files, paths
示例#9
0
    def _runNextBatch(self):
        """ Runs the next test batch """
        if len(self._tests) == 0:
            # if nothing left, stop
            info("No more tests batch to run, we're done")
            self._stoptime = int(time.time())
            self._storage.endTestRun(self)
            self._running = False
            self.emit("done")
            return False

        info("Getting next test batch")
        # pop out the next batch
        test, args, monitors = self._tests.pop(0)
        self._currenttest = test
        self._currentmonitors = monitors
        self._currentarguments = args

        info("Current test : %r" % test)
        info("Current monitors : %r" % monitors)
        info("Current arguments : %r" % args)

        # and run the first one of that batch
        self._runNext()
        return False
    def _stopMonitors(self):
        for monitorinstance in self._monitorinstances:
            if not monitorinstance.stop():
                info("Could not stop monitor %s", monitorinstance)
                continue

            ofiles =  monitorinstance.getIterationOutputFiles(self._iteration)
            if ofiles:
                self.iteration_outputfiles.update(ofiles)
示例#11
0
 def _singleTestDone(self, test):
     info("Done with test %r , success rate %02f%%",
          test, test.getSuccessPercentage())
     self.emit("single-test-done", test)
     # FIXME : Improvement : disconnect all signals from that test
     if test in self._runninginstances:
         self._runninginstances.remove(test)
     self._storage.newTestFinished(self, test)
     self._runNext()
    def _removedRemoteTest(self, testrun, uuid):
        if not uuid == self.uuid:
            return

        info("%s our remote counterpart has left", self.uuid)
        # abort if the test hasn't actually finished
        self._remoteinstance = None
        if not self._stopping:
            self.stop()
示例#13
0
    def remoteTest(self):
        """
        Remote-side test() method.

        Subclasses should implement this method and chain up to the parent
        remoteTest() method at the *beginning* of their implementation.
        """
        info("%s", self.uuid)
        # add a timeout
        self._remotetimeoutid = gobject.timeout_add(self._timeout * 1000, self._remoteTestTimeoutCb)
示例#14
0
 def _generate(self):
     res = []
     for path in self.paths:
         fullpath = os.path.abspath(path)
         if os.path.isfile(fullpath) and self._is_valid_file(fullpath):
             res.append(fullpath)
         else:
             res.extend(self._get_files(fullpath))
     info("Returning %d files" % len(res))
     return res
 def probe_test(self, filename):
     if not "insanity-test-" in filename:
         return False
     info ('Running %s, which might be a test', filename)
     try:
         process = subprocess.Popen([filename, '--insanity-metadata'],
             stdin = None, stdout = subprocess.PIPE, stderr = subprocess.PIPE,
             universal_newlines=True)
     except Exception,e:
         info('Exception running process (%s), not a test', e)
         return False
def kill_private_dbus():
    """
    Kill the private dbus daemon used by the client
    """
    global private_bus_pid, private_bus, private_bus_address
    if private_bus_pid:
        info("Killing private dbus daemon [pid:%d]" % int(private_bus_pid))
        os.kill(int(private_bus_pid), signal.SIGKILL)
        private_bus = None
        private_bus_address = None
        private_bus_pid = None
示例#17
0
 def _dbusNameOwnerChangedSignal(self, name, oldowner, newowner):
     # we only care about connections named net.gstreamer.Insanity.Test.xxx
     info("name:%s , oldowner:%s, newowner:%s" % (name, oldowner, newowner))
     if not name.startswith("net.gstreamer.Insanity.Test.Test"):
         return
     # extract uuid
     uuid = name.rsplit('.Test', 1)[-1]
     if newowner == "":
         self.emit("removed-remote-test", uuid)
     elif oldowner == "":
         self.emit("new-remote-test", uuid)
    def validateChecklistItem(self, checkitem):
        """
        Validate a checklist item in the checklist.
        checkitem is one of the keys of __test_checklist__

        Called by the test itself
        """
        info("checklist item %s for item %r" % (checkitem, self))
        if not checkitem in self._checklist:
            return
        self._checklist[checkitem] = True
    def extraInfo(self, key, value):
        """
        Give extra information obtained while running the tests.

        If key was already given, the new value will override the value
        previously given for the same key.

        Called by the test itself
        """
        info("uuid:%s, key:%s, value:%r", self.uuid, key, value)
        self._extrainfo[key] = value
        self.emit("extra-info", key, value)
示例#20
0
    def remoteSetUp(self):
        """
        Remote-side setUp() method.

        Subclasses should implement this method and chain up to the parent
        remoteSetUp() method at the *end* of their implementation.
        """
        info("%s", self.uuid)

        usage = resource.getrusage(resource.RUSAGE_SELF)
        self.rusage_start = (time.time(), usage.ru_utime, usage.ru_stime)

        # if not overriden, we just emit the "ready" signal
        self.remoteReadySignal()
    def _voidRemoteStopCallBackHandler(self):
        info("%s", self.uuid)

        self.validateChecklistItem("subprocess-exited-normally")
        self._prepareArguments()
        Test.stop(self)

        self.ping()
        # Check if we have new arguments and
        # have to run another time
        if self.args:
            self.start()
        else:
            self.tearDown()
示例#22
0
 def tearDown(self):
     info("uuid:%s proxy:%r", self.uuid, self._isproxy)
     if self._isproxy:
         # FIXME : tear down the other process gracefully
         #    by first sending it the termination remote signal
         #    and then checking it's killed
         try:
             self.callRemoteStop()
         finally:
             if self._testrun:
                 if self._newremotetestsid:
                     self._testrun.disconnect(self._newremotetestsid)
                     self._newremotetestsid = 0
                 if self._testrunremovedtestsigid:
                     self._testrun.disconnect(self._testrunremovedtestsigid)
                     self._testrunremovedtestsigid = 0
             if self._processpollid:
                 gobject.source_remove(self._processpollid)
                 self._processpollid = 0
             if self._process:
                 # double check it hasn't actually exited
                 # give the test up to one second to exit
                 tries = 10
                 while self._returncode is None and not tries == 0:
                     time.sleep(0.1)
                     self._returncode = self._process.poll()
                     tries -= 1
                 if self._returncode is None:
                     info("Process isn't done yet, terminating it")
                     os.kill(self._process.pid, signal.SIGTERM)
                     time.sleep(1)
                     self._returncode = self._process.poll()
                 if self._returncode is None:
                     info("Process did not terminate, killing it")
                     os.kill(self._process.pid, signal.SIGKILL)
                     time.sleep(1)
                     self._returncode = self._process.poll()
                 if self._returncode is None:
                     # Probably turned into zombie process, something is
                     # really broken...
                     info("Process did not exit after SIGKILL")
                 self._process = None
             if not self._returncode is None:
                 info("Process returned %d", self._returncode)
                 self.validateStep("subprocess-exited-normally", self._returncode == 0)
                 self.extraInfo("subprocess-return-code", self._returncode)
     else:
         self.remoteTearDown()
     Test.tearDown(self)
    def setUp(self):
        info("uuid:%s", self.uuid)
        if Test.setUp(self) == False:
            return False

        # get the remote launcher
        pargs = self._preargs
        pargs.extend(self.get_remote_launcher_args())
        shell = isinstance (pargs, basestring)

        cwd = self._testrun.getWorkingDirectory()

        self._environ["PRIVATE_DBUS_ADDRESS"] = self._bus_address
        info("Setting PRIVATE_DBUS_ADDRESS : %r" % self._bus_address)
        info("bus:%r" % self._bus)

        self._prepareArguments()

        if False: # useful to allow some time to run dbus-monitor on the private bus
            print("Setting PRIVATE_DBUS_ADDRESS : %r" % self._bus_address)
            time.sleep(5)

        # spawn the other process
        info("opening %r" % pargs)
        info("cwd %s" % cwd)
        try:
            self._subprocessspawntime = time.time()
            self._process = subprocess.Popen(pargs,
                                             stdin = self._stdin,
                                             stdout = subprocess.PIPE,
                                             stderr = subprocess.PIPE,
                                             env=self._environ,
                                             shell = shell,
                                             cwd=cwd)

            self._ensureOutRedirection()
            self._pid = self._process.pid
        except:
            exception("Error starting the subprocess command ! %r", pargs)
            self.validateChecklistItem("dbus-process-spawned", False)
            return False
        debug("Subprocess created successfully [pid:%d]", self._pid)

        self.validateChecklistItem("dbus-process-spawned")
        # add a poller for the proces
        self._processpollid = gobject.timeout_add(500, self._pollSubProcess)
        # Don't forget to set a timeout for waiting for the connection
        return True
示例#24
0
 def __init__(self, paths=[], recursive=True,
              matching=[], reject=[], *args,
              **kwargs):
     """
     paths : list of paths and/or files
     recursive : go down in subdirectories
     matching : will only return files matching the given masks
     reject : will not return files matching the given masks
     """
     Generator.__init__(self, paths=paths, recursive=recursive,
                        matching=matching, reject=reject,
                        *args, **kwargs)
     self.paths = paths
     self.recursive = recursive
     self.matching = matching
     self.reject = reject
     info("paths:%r, recursive:%r, matching:%r, reject:%r" % (paths, recursive, matching, reject))
示例#25
0
    def _newRemoteTest(self, testrun, uuid):
        if not uuid == self.uuid:
            return

        info("%s our remote counterpart has started", self.uuid)
        self.validateStep("dbus-process-connected")
        self._subprocessconnecttime = time.time()
        delay = self._subprocessconnecttime - self._subprocessspawntime
        self.extraInfo("subprocess-spawn-time", delay)
        # we need to give the remote process the following information:
        # * filename where the Test class is located (self.get_file())
        # * class name (self.__class__.__name__)
        # * the arguments (self.arguments) + proxy=True
        rname = "net.gstreamer.Insanity.Test.Test%s" % self.uuid
        rpath = "/net/gstreamer/Insanity/Test/RemotePythonRunner%s" % self.uuid
        # get the proxy object to our counterpart
        remoteobj = self._bus.get_object(rname, rpath)
        debug("Got remote runner object %r" % remoteobj)
        # call createTestInstance()
        remoterunner = dbus.Interface(remoteobj, "net.gstreamer.Insanity.RemotePythonRunner")
        debug("Got remote iface %r" % remoterunner)
        args = self.arguments.copy()
        args["bus_address"] = self._bus_address
        args["timeout"] = self._timeout
        if self._outputfiles:
            args["outputfiles"] = self.getOutputFiles()
        debug(
            "Creating remote instance with arguments %s %s %s %r",
            self.get_file(),
            self.__module__,
            self.__class__.__name__,
            args,
        )
        try:
            remoterunner.createTestInstance(
                self.get_file(),
                self.__module__,
                self.__class__.__name__,
                args,
                reply_handler=self._createTestInstanceCallBack,
                error_handler=self._voidRemoteErrBackHandler,
            )
        except:
            exception("Exception raised when creating remote instance !")
            self.validateStep("remote-instanced-created", False)
            self.stop()
示例#26
0
    def validateStep(self, checkitem, validated=True):
        """
        Validate a step in the checklist.
        checkitem is one of the keys of __test_checklist__
        validated is a boolean indicating whether that step should be
           validated or not.

        Called by the test itself
        """
        info("step %s for item %r : %r" % (checkitem, self, validated))
        # check for valid checkitem
        if not checkitem in self._possiblechecklist:
            return
        # check to see if we don't already have it
        if checkitem in dict(self._checklist):
            return
        self._checklist.append((checkitem, bool(validated)))
        # self._checklist[checkitem] = True
        self.emit("check", checkitem, validated)
示例#27
0
    def addTest(self, test, arguments, monitors=None):
        """
        Adds test with the given arguments (or generator) and monitors
        to the list of tests to be run

        monitors are a list of tuples containing:
        * the monitor class
        * (optional) the arguments to use on that monitor
        """
        if not isinstance(test, type) and not issubclass(test, Test):
            raise TypeError("Given test is not a Test object !")
        # arguments NEED to be an Arguments object or a dictionnary
        if isinstance(arguments, dict):
            # convert dictionnary to Arguments
            info("Creating Arguments for %r" % arguments)
            arguments = Arguments(**arguments)
        elif not isinstance(arguments, Arguments):
            raise TypeError("Test arguments need to be of type Arguments or dict")
        self._tests.append((test, arguments, monitors))
示例#28
0
 def __init__(self, singlerun=False, storage=None, *args, **kwargs):
     dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
     info("starting")
     self._ml = gobject.MainLoop()
     self._bus = dbustools.get_private_session_bus()
     self._busname = dbus.service.BusName("net.gstreamer.TesterClient", self._bus)
     # dbus.service.Object.__init__(self, dbustools.get_private_session_bus(), "/here")
     dbus.service.Object.__init__(self, self._bus, "/here")
     self._testruns = []
     self._storage = None
     self._clientid = None
     if storage:
         self.setStorage(storage)
     # _current is the current TestRun being executed
     self._current = None
     # _running is True if the mainloop is running
     self._running = False
     # If _singlerun == True, the client will quit after
     # all testruns are done
     self._singlerun = singlerun
示例#29
0
    def setUp(self):
        info("uuid:%s proxy:%r", self.uuid, self._isproxy)
        if Test.setUp(self) == False:
            return False

        if self._isproxy:
            # get the remote launcher
            pargs = self._preargs
            pargs.extend(self.get_remote_launcher_args())

            cwd = self._testrun.getWorkingDirectory()

            self._environ["PRIVATE_DBUS_ADDRESS"] = self._bus_address
            info("Setting PRIVATE_DBUS_ADDRESS : %r" % self._bus_address)
            info("bus:%r" % self._bus)

            # spawn the other process
            info("opening %r" % pargs)
            info("cwd %s" % cwd)
            try:
                self._subprocessspawntime = time.time()
                self._process = subprocess.Popen(
                    pargs, stdin=self._stdin, stdout=self._stdout, stderr=self._stderr, env=self._environ, cwd=cwd
                )
                self._pid = self._process.pid
            except:
                exception("Error starting the subprocess command ! %r", pargs)
                self.validateStep("dbus-process-spawned", False)
                return False
            debug("Subprocess created successfully [pid:%d]", self._pid)

            self.validateStep("dbus-process-spawned")
            # add a poller for the proces
            self._processpollid = gobject.timeout_add(500, self._pollSubProcess)
            # Don't forget to set a timeout for waiting for the connection
        else:
            # remote instance setup
            # self.remoteSetUp()
            pass
        return True
    def _newRemoteTest(self, testrun, uuid):
        if not uuid == self.uuid:
            return

        info("%s our remote counterpart has started", self.uuid)
        self.validateChecklistItem("dbus-process-connected")
        self._subprocessconnecttime = time.time()
        delay = self._subprocessconnecttime - self._subprocessspawntime
        self.extraInfo("subprocess-spawn-time", int(delay * 1000))
        # we need to give the remote process the following information:
        # * filename where the Test class is located (self.get_file())
        # * class name (self.__class__.__name__)
        # * the arguments (self.arguments)
        rname = "net.gstreamer.Insanity.Test.Test%s" % self.uuid
        rpath = "/net/gstreamer/Insanity/Test/Test%s" % self.uuid
        # get the proxy object to our counterpart
        remoteobj = self._bus.get_object(rname, rpath)
        debug("Got remote runner object %r" % remoteobj)
        # call createTestInstance()
        remoterunner = dbus.Interface(remoteobj,
                                      "net.gstreamer.Insanity.Test")
        debug("Got remote iface %r" % remoterunner)
        try:
            delay = time.time() - self._subprocessconnecttime
            self._remoteinstance = dbus.Interface(remoteobj,
                                                  "net.gstreamer.Insanity.Test")
            info ('Listening to signals from %s' % self._remoteinstance)
            self._remoteinstance.connect_to_signal("remoteDoneSignal",
                                                   self._remoteDoneCb)
            self._remoteinstance.connect_to_signal("remoteValidateChecklistItemSignal",
                                                   self._remoteValidateChecklistItemCb)
            self._remoteinstance.connect_to_signal("remoteExtraInfoSignal",
                                                   self._remoteExtraInfoCb)
            self._remoteinstance.connect_to_signal("remotePingSignal",
                                                   self._remotePingCb)
            self.callRemoteSetUp()
        except:
            exception("Exception raised when creating remote instance !")
            self.stop()