Exemple #1
0
def load_bytecode_processors():
    """
    Loading BytecodeProcessor from modipyd.BYTECODE_PROCESSORS
    settings. Return ChainedBytecodeProcessor instance holds
    all loaded processors.
    """
    if (BYTECODE_PROCESSORS and 
            (len(BYTECODE_PROCESSORS_CACHE) != len(BYTECODE_PROCESSORS))):
        del BYTECODE_PROCESSORS_CACHE[:]
        for i, name in enumerate(BYTECODE_PROCESSORS[:]):
            LOGGER.info("Loading BytecodeProcesser '%s'" % name)
            try:
                klass = utils.import_component(name)
            except (ImportError, AttributeError):
                LOGGER.warn(
                    "Loading BytecodeProcesser '%s' failed. "
                    "This setting is removed" % name,
                    exc_info=True)
                del BYTECODE_PROCESSORS[i]
            else:
                BYTECODE_PROCESSORS_CACHE.append(klass)

    processors = []
    for klass in BYTECODE_PROCESSORS_CACHE:
        processors.append(klass())
    return bc.ChainedBytecodeProcessor(processors)
def collect_unittest(paths):
    suite = unittest.TestSuite()
    loader = unittest.defaultTestLoader
    resolver = resolve.ModuleNameResolver()
    paths = utils.sequence(paths)

    for filepath in paths:
        try:
            name, package = resolver.resolve(filepath)
        except ImportError:
            # .py file not in the search path
            name = filepath_to_identifier(filepath)
            package = None

        try:
            if package:
                module = utils.import_module(name)
            else:
                module = imp.load_source(name, filepath)
        except ImportError:
            LOGGER.warn("ImportError occurred while loading module", exc_info=True)
        else:
            tests = loader.loadTestsFromModule(module)
            if tests.countTestCases():
                suite.addTest(tests)
                LOGGER.info("Found %d test(s) in module '%s'" % (tests.countTestCases(), module.__name__))
            else:
                LOGGER.warn("No tests found in module '%s'" % module.__name__)
    return suite
Exemple #3
0
    def install_plugin(self, plugin):
        """
        Install a plugin specified by *plugin*. The *plugin* argument
        must be callable object (e.g. function, class) or a qualified
        name of the plugin itself.

        Read the ``modipyd.application.plugins`` module documentation
        for the plugin architecture details.
        """

        if isinstance(plugin, basestring):
            try:
                plugin = import_component(plugin)
            except (ImportError, AttributeError):
                LOGGER.error("Loading plugin '%s' failed" % plugin)
                raise

        if not callable(plugin):
            raise TypeError("The plugin must be callable object")

        if hasattr(plugin, 'func_code'):
            LOGGER.info("Loading plugin: %s" % plugin.func_code.co_name)
        else:
            LOGGER.info("Loading plugin: %s" % plugin)

        self.plugins.append(plugin)
Exemple #4
0
    def reload(self, descriptors, co=None):
        """
        Reload module code, update dependency graph
        """
        LOGGER.info("Reload module descriptor '%s' at %s" % (self.name, relativepath(self.filename)))

        try:
            self.module_code.reload(co)
        except SyntaxError:
            # SyntaxError is OK
            LOGGER.warn("SyntaxError found in %s" % self.filename, exc_info=True)
        else:
            self.update_dependencies(descriptors)
Exemple #5
0
    def start(self, interval=1.0, refresh_factor=5):
        if refresh_factor < 1:
            raise RuntimeError("refresh_factor must be greater or eqaul to 1")
        if interval <= 0:
            raise RuntimeError("interval must not be negative or 0")

        descriptors = self.descriptors

        if LOGGER.isEnabledFor(logging.INFO):
            desc = "\n".join([
                desc.describe(indent=4)
                for desc in descriptors.itervalues()])
            LOGGER.info("Monitoring:\n%s" % desc)

        # Prior to Python 2.5, the ``yield`` statement is not
        # allowed in the ``try`` clause of a ``try ... finally``
        # construct.
        try:
            self.monitoring = True

            times = 0
            while descriptors and self.monitoring:

                time.sleep(interval)
                times += 1

                if times % refresh_factor == 0:
                    monitor = self.refresh()
                else:
                    monitor = self.monitor()

                for modified in monitor:
                    if not self.monitoring:
                        break
                    yield modified
            else:
                LOGGER.info("Terminating monitor %s" % str(self))
        except:
            self.monitoring = False
            raise
Exemple #6
0
def make_application(options, filepath):
    # options handling
    if options.verbosity > 0:
        LOGGER.setLevel(logging.INFO)
    if options.verbosity > 1:
        LOGGER.setLevel(logging.DEBUG)

    # So many projects contain its modules and packages at
    # the top level directory, modipyd inserts current directory
    # in ``sys.path`` module search path variable for convenience.
    sys.path.insert(0, os.getcwd())

    # Create Application instance, Install plugins
    application = Application(filepath)
    for plugin in options.plugins:
        application.install_plugin(plugin)

    # Predefine variables
    variables = {}
    for var in options.defines:
        i = var.find('=')
        if i == -1:
            variables[var] = ''
        else:
            variables[var[:i]] = var[i+1:]

    if variables:
        import pprint
        application.update_variables(variables)
        LOGGER.info(
            "Predefined variables: %s" % pprint.pformat(variables))

    # Load configuration (startup) file
    for rcfile in find_startup_files(os.environ, options.rcfile):
        LOGGER.info("Loading startup file from %s" % rcfile)
        execfile(rcfile, globals(), {'application': application})

    return application
Exemple #7
0
    def __call__(self):

        # Walking dependency graph in imported module to
        # module imports order.
        testables = []
        for desc in self.descriptor.walk_dependency_graph(reverse=True):
            LOGGER.info("-> Affected: %s" % desc.name)
            if has_subclass(desc, unittest.TestCase):
                LOGGER.debug("-> unittest.TestCase detected: %s" % desc.name)
                testables.append(desc)

        # Runntine tests
        if testables:
            # We can reload affected modules manually and run
            # all TestCase in same process. Running another process,
            # however, is simple and perfect solution.
            if LOGGER.isEnabledFor(logging.INFO):
                desc = ', '.join([x.name for x in testables])
                LOGGER.info("Running UnitTests: %s" % desc)
            # Propagates the level of modipyd.LOGGER to
            # the unittest runner subprocess.
            extra = ['--loglevel', LOGGER.getEffectiveLevel()]
            self.spawn_unittest_runner(testables, extra)
Exemple #8
0
 def run(self):
     monitor = Monitor(self.paths)
     for event in monitor.start():
         LOGGER.info("%s: %s" % (TYPE_STRINGS[event.type],
             event.descriptor.describe(indent=4)))
         self.invoke_plugins(event, monitor)