Exemple #1
0
    def run(self, argv):
        """Run the test runner.

        Invoke the test runner by calling it.
        """
        cf = self.runner.config
        cf.flags.INTERACTIVE = True
        cf.flags.DEBUG = 0
        cf.flags.VERBOSE = 0
        optlist, longopts, args = getopt.getopt(argv[1:], "h?dDvIc:f:m:e:r:")
        for opt, optarg in optlist:
            if opt in ("-h", "-?"):
                print(TestRunnerInterfaceDoc.format(
                    name=os.path.basename(argv[0])))
                return
            elif opt == "-d":
                cf.flags.DEBUG += 1
            elif opt == "-D":
                from pycopia import autodebug  # noqa
            elif opt == "-v":
                cf.flags.VERBOSE += 1
            elif opt == "-I":
                cf.flags.INTERACTIVE = False
            elif opt == "-c" or opt == "-f":
                cf.mergefile(optarg)
            elif opt == "-m":
                cf.comment = optarg
            elif opt == "-r":
                cf.reportname = optarg
            elif opt == "-e":
                cf.environmentname = optarg

        cf.evalupdate(longopts)
        # original command line arguments saved for the report
        cf.arguments = [os.path.basename(argv[0])] + argv[1:]

        ui = UI.get_userinterface(themename="ANSITheme")
        if not args:
            from . import simplechooser
            args = simplechooser.choose_tests(ui)
        if not args:
            return 10
        objects, errors = module.get_objects(args)
        if errors:
            logging.warn("Errors found while loading test object:")
            for error in errors:
                logging.warn(error)
        if objects:
            cf.argv = args
            rv = self.runner.run(objects, ui)
            if rv is None:
                return 11
            else:
                try:
                    return int(rv)
                except TypeError:
                    return 12
        else:
            return len(errors) + 20
Exemple #2
0
    def __call__(self, argv):
        """Run the test runner.

        Invoke the test runner by calling it.
        """
        cf = self.runner.config
        cf.flags.REPORT = False
        cf.flags.INTERACTIVE = False
        cf.flags.DEBUG = 0
        cf.flags.VERBOSE = 0
        optlist, extraopts, args = getopt.getopt(argv[1:], "h?dDviIrc:f:n:")
        for opt, optarg in optlist:
            if opt in ("-h", "-?"):
                print (TestRunnerInterfaceDoc % (os.path.basename(argv[0]),))
                return
            elif opt == "-d":
                cf.flags.DEBUG += 1
            elif opt == "-D":
                from pycopia import autodebug # top-level debug for framework bugs
            elif opt == "-v":
                cf.flags.VERBOSE += 1
            elif opt == "-i":
                cf.flags.INTERACTIVE = True
            elif opt == "-I":
                cf.flags.INTERACTIVE = False
            elif opt == "-c" or opt == "-f":
                cf.mergefile(optarg)
            elif opt == "-n":
                cf.comment = optarg
            elif opt == "-r":
                cf.flags.REPORT = True
        cf.evalupdate(extraopts)
        # original command line arguments saved for the report
        cf.arguments = [os.path.basename(argv[0])] + argv[1:]
        # Save extra options for overriding configuration after a mergefile
        # because command line options should have highest precedence.
        self.runner.set_options(extraopts)

        if not args:
            if cf.flags.REPORT:
                self.runner.report_global()
                return 0
            else:
                args = choose_tests()
        if not args:
            return 2
        objects, errors = module.get_objects(args)
        if errors:
            logging.warn("Errors found while loading test object:")
            for error in errors:
                logging.warn(error)
        if objects:
            cf.argv = args
            self.runner.initialize()
            rv = self.runner.run_objects(objects)
            self.runner.finalize()
            return not rv # inverted due to shell semantics (zero is good) being different from result code
        else:
            return int(bool(errors)) + 2
Exemple #3
0
    def run_objects(self, objects):
        """Invoke the `run` method on a list of mixed runnable objects.

        Arguments:
            objects:
                A list of runnable objects. A runnable object is basically
                something that has a callable named "run" that takes a
                configuration object as a parameter.

        May raise TestRunnerError if an object is not runnable by this test
        runner.
        """
        rv = 0
        testcases = []
        for obj in objects:
            objecttype = type(obj)
            if objecttype is ModuleType and hasattr(obj, "run"):
                rv = self.run_module(obj)
            elif objecttype is TypeType and issubclass(obj, core.Test):
                testcases.append(obj)
            elif isinstance(obj, core.TestSuite):
                rv = self.run_object(obj)
            elif objecttype is type and hasattr(obj, "run"):
                # a bare class uses as a subcontainer of test or suite constructor.
                rv = self.run_class(obj)
            else:
                logging.warn("%r is not a runnable object." % (obj,))
        if testcases:
            if len(testcases) > 1:
                rv = self.run_tests(testcases)
            else:
                args = []
                kwargs = {}
                opts = self.config.options_override.copy()
                for name, value in opts.items():
                    if name.startswith("arg"):
                        try:
                            index = int(name[3]) # use --arg1=XXX to place argument XXX
                        except (ValueError, IndexError):
                            logging.warn("{!r} not converted to argument.".format(name))
                        else:
                            try:
                                args[index] = value
                            except IndexError:
                                need = index - len(args)
                                while need:
                                    args.append(None)
                                    need -= 1
                                args.append(value)
                        del self.config.options_override[name]
                        del self.config[name]
                    elif name.startswith("kwarg_"): # use --kwarg_XXX to place keyword argument XXX
                        kwargs[name[6:]] = value
                        del self.config.options_override[name]
                        del self.config[name]
                rv = self.run_test(testcases[0], *args, **kwargs)
        return rv
Exemple #4
0
 def import_module(self, modname):
     if _DEBUG:
         print("Doing module: %s" % modname)
     try:
         mod = module.get_module(modname)
         do_module(mod, self.config)
     except:
         ex, val, tb = sys.exc_info()
         if _DEBUG:
             debugger.post_mortem(tb, ex, val)
         else:
             logging.warn("Could not import %s: %s" % ( modname, "%s: %s" % (ex, val)))
Exemple #5
0
    def run_objects(self, objects):
        """Invoke the `run` method on a list of mixed runnable objects.

        Arguments:
            objects:
                A list of runnable objects. A runnable object is basically
                something that has a callable named "run" that takes a
                configuration, environment, and UI object as a parameter.

                A special module with an "execute" function can also be run.

        May raise TestRunnerError if an object is not runnable by this test
        runner.

        Bare TestCase classes are grouped together and run in a temporary
        TestSuite.
        """
        rv = TestResult.INCOMPLETE
        results = []
        testcases = []
        for obj in objects:
            objecttype = type(obj)
            if objecttype is type:
                if issubclass(obj, core.TestCase):
                    testcases.append(obj)
                if issubclass(obj, core.UseCase):
                    rv = obj.run(self.config, self.environment, self._ui)
            elif isinstance(obj, core.TestSuite):
                obj.run()
                rv = obj.result
            elif objecttype is ModuleType:
                if hasattr(obj, "execute"):
                    rv = self._run_module_hack(obj)
                elif hasattr(obj, "run"):
                    rv = self._run_module(obj)
            else:
                logging.warn("{!r} is not a runnable object.".format(obj))
            results.append(rv)
        # Run any accumulated bare test classes.
        if testcases:
            if len(testcases) > 1:
                rv = self.run_tests(testcases)
            else:
                rv = self.run_test(testcases[0])
            results.append(rv)
        return _aggregate_returned_results(results)
Exemple #6
0
def get_TestEntry_instance(string, config):
    """Return a TestEntry instance from a string representing a test class
    plus arguments.
    """
    paren_i = string.find("(")
    if paren_i > 0:
        args = string[paren_i+1:-1]
        string = string[:paren_i]
        args, kwargs = core.parse_args(args)
    else:
        args = ()
        kwargs = {}
    try:
        cls = module.get_object(string)
    except (module.ModuleImportError, module.ObjectImportError), err:
        logging.warn(err)
        return None
Exemple #7
0
def get_test_jobs(args):
    dbsession = models.get_session()
    TJ = models.TestJob
    for jobid in args:
        try:
            jobid = int(jobid)
        except ValueError:
            pass
        try:
            if type(jobid) is int:
                testjob = dbsession.query(TJ).get(jobid)
            else:
                testjob = dbsession.query(TJ).filter(TJ.name==jobid).one()
        except models.NoResultFound:
            logging.warn("No TestJob with id %r" % jobid)
            continue
        else:
            yield testjob
Exemple #8
0
 def resolve_prerequisite(self, testinstance):
     doc_prereqs = self._many2many["prerequisites"]
     self._many2many["prerequisites"] = []
     memo = set()
     for prereq in aid.removedups([pr.implementation for pr in testinstance.prerequisites] + doc_prereqs):
         if not _valid_prereq(prereq):
             continue
         if "." not in prereq:
             prereq = "%s.%s" % (testinstance.__class__.__module__, prereq)
         if prereq in memo:
             continue
         memo.add(prereq)
         entry = get_TestEntry_instance(prereq, testinstance.config)
         if entry:
             dbprereq = do_TestEntry(entry)
             self._many2many["prerequisites"].append(dbprereq)
         else:
             logging.warn("prerequisite %r could not be found." % (prereq,))
Exemple #9
0
 def get_test_suites(self, args):
     """Generator that yields valid TestSuite records from the database.
     """
     TS = models.TestSuite
     for suiteid in args:
         try:
             suiteid = int(suiteid)
         except ValueError:
             pass
         try:
             if type(suiteid) is int:
                 suite = self.dbsession.query(TS).get(suiteid)
             else:
                 suite = self.dbsession.query(TS).filter(models.and_(TS.name==suiteid, TS.valid==True)).one()
         except models.NoResultFound:
             logging.warn("No TestSuite with id or name %r" % suiteid)
             continue
         else:
             yield suite
Exemple #10
0
def choose_tests():
    try:
        import testcases
    except ImportError:
        logging.warn("Cannot find 'testcases' base package.")
        return None
    from pycopia import UI
    from pycopia.QA import core

    ui = UI.get_userinterface(themename="ANSITheme")
    ui.printf("Select any number of runnable objects. %n"
            "You can select %wmodules%N, %gUseCase%N objects, or single %yTest%N object.")
    # callback for testdir walker
    def filternames(flist, dirname, names):
        for name in names:
            if name.endswith(".py") and not name.startswith("_"):
                flist.append(os.path.join(dirname, name[:-3]))
    modnames = []
    runnables = []
    for testbase in testcases.__path__:
        mnlist = []
        os.path.walk(testbase, filternames, mnlist)
        testhome_index = len(os.path.dirname(testbase)) + 1
        modnames.extend(map(lambda n: n[testhome_index:].replace("/", "."), mnlist))
    modnames.sort()
    for modname in modnames:
        try:
            mod = module.get_module(modname)
        except module.ModuleImportError:
            ui.warning("  Warning: could not import '{}'".format(modname))
            continue
        if getattr(mod, "run", None) is not None:
            runnables.append(FormatWrapper(ui, modname, None, "%w%U%N"))
        for attrname in dir(mod):
            obj = getattr(mod, attrname)
            if type(obj) is type:
                if issubclass(obj, core.UseCase):
                    runnables.append(FormatWrapper(ui, modname, obj.__name__, "%U.%g%O%N"))
                if issubclass(obj, core.Test):
                    runnables.append(FormatWrapper(ui, modname, obj.__name__, "%U.%y%O%N"))
    return [o.fullname for o in ui.choose_multiple(runnables, prompt="Select tests")]
Exemple #11
0
 def skippedEntity(self, name):
     warn("unhandled ignorableWhitespace: %r" % (whitespace,))
Exemple #12
0
def run_server(argv):
    username = None
    do_daemon = True
    debug = False
    killserver = False
    try:
        optlist, args = getopt.getopt(argv[1:], "dnh?kl:f:p:s:")
    except getopt.GetoptError:
        print (run_server._doc % (argv[0],))
        return

    if len(args) > 0:
        servername = args[0]
    else:
        servername = os.path.basename(argv[0])

    logfilename = "/var/log/%s.log" % (servername,)
    cffilename = "/etc/pycopia/%s.conf" % (servername,)
    pidfile="/var/run/%s.pid" % (servername,)
    socketpath = '/tmp/%s.sock' % (servername,)

    for opt, optarg in optlist:
        if opt == "-n":
            do_daemon = False
        elif opt == "-k":
            killserver = True
        elif opt == "-d":
            debug = True
        elif opt == "-u":
            username = optarg
        elif opt == "-l":
            logfilename = optarg
        elif opt == "-f":
            cffilename = optarg
        elif opt == "-p":
            pidfile = optarg
        elif opt == "-s":
            socketpath = optarg
        elif opt in ("-h", "-?"):
            print (run_server._doc % (argv[0],))
            return 2

    try:
        config = basicconfig.get_config(cffilename,
                    CONFIGFILE=cffilename,
                    PIDFILE=pidfile,
                    SOCKETPATH=socketpath,
                    LOGFILENAME=logfilename,
                    DEBUG=debug,
                    SERVERNAME=servername)
    except:
        ex, val, tb = sys.exc_info()
        logging.warn("Could not get server config: %s (%s)" % (ex, val))
        return 1

    if username:
        config.USERNAME = username

    if killserver:
        kill_server(config)
        return 0

    if check4server(config):
        logging.warn("Server %r already running on socket %r." % (servername, socketpath))
        return 1

    if do_daemon and not debug:
        from pycopia import daemonize
        from pycopia import logfile
        lf = logfile.ManagedStdio(logfilename)
        daemonize.daemonize(lf, pidfile=pidfile)
    else: # for controller
        fo = open(pidfile, "w")
        fo.write("%s\n" % (os.getpid(),))
        fo.close()
        del fo

    server = get_server(config)
    return int(server.run())
Exemple #13
0
def run_server(argv):
    username = None
    do_daemon = True
    debug = False
    killserver = False
    try:
        optlist, longopts, args = getopt.getopt(argv[1:], "dnh?kl:f:p:s:")
    except getopt.GetoptError:
        print(run_server._doc.format(procname=argv[0]))
        return

    if len(args) > 0:
        servername = args[0]
    else:
        servername = os.path.basename(argv[0])

    logfilename = "/var/log/{}.log".format(servername)
    cffilename = "/etc/pycopia/{}.conf".format(servername)
    pidfile = "/var/run/{}.pid".format(servername)
    socketpath = '/tmp/{}.sock'.format(servername)

    for opt, optarg in optlist:
        if opt == "-n":
            do_daemon = False
        elif opt == "-k":
            killserver = True
        elif opt == "-d":
            from pycopia import autodebug  # noqa
            debug = True
        elif opt == "-u":
            username = optarg
        elif opt == "-l":
            logfilename = optarg
        elif opt == "-f":
            cffilename = optarg
        elif opt == "-p":
            pidfile = optarg
        elif opt == "-s":
            socketpath = optarg
        elif opt in ("-h", "-?"):
            print(run_server._doc.format(procname=argv[0]))
            return 2

    try:
        config = basicconfig.get_config(cffilename,
                                        CONFIGFILE=cffilename,
                                        PIDFILE=pidfile,
                                        SOCKETPATH=socketpath,
                                        LOGFILENAME=logfilename,
                                        DEBUG=debug,
                                        SERVERNAME=servername)
    except:
        ex, val, tb = sys.exc_info()
        logging.warn(
            "Could not get server config: {} ({})".format(ex.__name__, val))
        return 1
    config.update(longopts)

    if username:
        config.USERNAME = username

    if killserver:
        kill_server(config)
        return 0

    if check4server(config):
        logging.warn(
            "Server {!r} already running on socket {!r}.".format(servername,
                                                                 socketpath))
        return 1

    if do_daemon and not debug:
        from pycopia import daemonize
        from pycopia import logfile
        lf = logfile.ManagedStdio(logfilename)
        daemonize.daemonize(lf, pidfile=pidfile)
    else:  # for controller
        with open(pidfile, "w") as fo:
            fo.write("{}\n".format(os.getpid()))

    server = get_server(config)
    return int(server.run())
Exemple #14
0
 def warning(self, exception):
     "Handle a warning."
     warn("XML Warning: %s" % (exception,))
Exemple #15
0
 def fatalError(self, exception):
     "Handle a non-recoverable error."
     #raise exception
     warn("XML fatalError: %s" % (exception,))
Exemple #16
0
 def error(self, exception):
     "Handle a recoverable error."
     #raise exception
     warn("XML error: %s" % (exception,))
Exemple #17
0
 def unparsedEntityDecl(self, name, publicId, systemId, ndata):
     warn("unhandled unparsedEntityDecl: %r %r %r %r" % ( name, publicId, systemId, ndata))
Exemple #18
0
 def notationDecl(self, name, publicId, systemId):
     """Handle a notation declaration event."""
     warn("unhandled notationDecl: %r %r %r" % ( name, publicId, systemId))
Exemple #19
0
 def startPrefixMapping(self, prefix, uri):
     warn("!!! Unhandled prefix: %r" % (prefix,))
Exemple #20
0
 def startPrefixMapping(self, prefix, uri):
     warn("!!! Unhandled prefix: %r" % (prefix, ))
Exemple #21
0
 def skippedEntity(self, name):
     warn("unhandled ignorableWhitespace: %r" % (whitespace, ))
Exemple #22
0
 def ignorableWhitespace(self, whitespace):
     warn("unhandled ignorableWhitespace: %r" % (whitespace,))
Exemple #23
0
def run_server(argv):
    username = None
    do_daemon = True
    debug = False
    killserver = False
    try:
        optlist, longopts, args = getopt.getopt(argv[1:], "dnh?kl:f:p:s:")
    except getopt.GetoptError:
        print(run_server._doc.format(procname=argv[0]))
        return

    if len(args) > 0:
        servername = args[0]
    else:
        servername = os.path.basename(argv[0])

    logfilename = "/var/log/{}.log".format(servername)
    cffilename = "/etc/pycopia/{}.conf".format(servername)
    pidfile = "/var/run/{}.pid".format(servername)
    socketpath = '/tmp/{}.sock'.format(servername)

    for opt, optarg in optlist:
        if opt == "-n":
            do_daemon = False
        elif opt == "-k":
            killserver = True
        elif opt == "-d":
            from pycopia import autodebug  # noqa
            debug = True
        elif opt == "-u":
            username = optarg
        elif opt == "-l":
            logfilename = optarg
        elif opt == "-f":
            cffilename = optarg
        elif opt == "-p":
            pidfile = optarg
        elif opt == "-s":
            socketpath = optarg
        elif opt in ("-h", "-?"):
            print(run_server._doc.format(procname=argv[0]))
            return 2

    try:
        config = basicconfig.get_config(cffilename,
                                        CONFIGFILE=cffilename,
                                        PIDFILE=pidfile,
                                        SOCKETPATH=socketpath,
                                        LOGFILENAME=logfilename,
                                        DEBUG=debug,
                                        SERVERNAME=servername)
    except:
        ex, val, tb = sys.exc_info()
        logging.warn("Could not get server config: {} ({})".format(
            ex.__name__, val))
        return 1
    config.update(longopts)

    if username:
        config.USERNAME = username

    if killserver:
        kill_server(config)
        return 0

    if check4server(config):
        logging.warn("Server {!r} already running on socket {!r}.".format(
            servername, socketpath))
        return 1

    if do_daemon and not debug:
        from pycopia import daemonize
        from pycopia import logfile
        lf = logfile.ManagedStdio(logfilename)
        daemonize.daemonize(lf, pidfile=pidfile)
    else:  # for controller
        with open(pidfile, "w") as fo:
            fo.write("{}\n".format(os.getpid()))

    server = get_server(config)
    return int(server.run())