Beispiel #1
0
def collect_test_references(root, included_files, filter_package,
                            filter_module, filter_testname, test_prefix):
    """
        Finds the test references based on the expression provided and the excludes
        for this class.  The `find_test_references` method is intended to be called
        multiple times, once with each include expression provided by the users.

        :param expression: An include expression to process and collect references for.
    """

    test_references = {}

    import_errors = {}

    root_pkgname = os.path.basename(root)

    # Go through the files and import them, then go through the classes and find the TestPack and
    # TestContainer objects that match the specified include expression criteria
    rootlen = len(root)
    for ifile in included_files:
        modname = None
        try:
            ifilebase, _ = os.path.splitext(ifile)
            ifileleaf = ifilebase[rootlen:].strip("/")
            modname = "{}.{}".format(root_pkgname, ifileleaf.replace("/", "."))

            # Import the module for the file being processed
            mod = import_by_name(modname)

            # Go through all of the members of the
            candidate_function_coll = inspect.getmembers(
                mod, inspect.isfunction)
            for function_name, function_obj in candidate_function_coll:
                cand_module_name = function_obj.__module__
                # We only want to include the classes that are from the target module
                if cand_module_name != modname:
                    continue

                if function_name.startswith(test_prefix):
                    if filter_testname is not None:
                        # If we have a testname expression only add a reference to the test function
                        # if the function_name matches the filter expression
                        if fnmatch.fnmatch(function_name, filter_testname):
                            tref = TestRef(function_obj)
                            test_references[tref.test_name] = tref
                    else:
                        tref = TestRef(function_obj)
                        test_references[tref.test_name] = tref

        except ImportError:
            errmsg = traceback.format_exc()
            print(errmsg)
            import_errors[ifile] = (modname, ifile, errmsg)

    import_errors.update(import_errors)

    for modname, ifile, errmsg in import_errors.values():
        logger.error("TestCase: Import error filename=%r" % ifile)

    return test_references, import_errors
Beispiel #2
0
def collect_extensions_under_code_container(container: ModuleType,
                                            ext_base_type: type) -> List[type]:
    """
        Scans the code `container` provide and all descendant containers for classes
        that inherit from the type passed as `ext_base_type`

        :param container: A python package or module to scan for extension types.
        :param ext_base_type: A python class type that serves as a base class to identify other
                              types that are a type of extension.

        :returns: A list of types found that inherit from `ext_base_type`
    """
    ext_collection = []

    # This is declare here so it can be used as a closure
    nxtmod = None

    def is_extension_class(obj):
        result = False

        if inspect.isclass(obj):
            obj_container = obj.__module__
            if obj_container == nxtmod.__name__ and LoadableExtension in obj.__bases__:
                result = issubclass(obj,
                                    ext_base_type) and obj is not ext_base_type
        return result

    container_name = container.__name__
    container_dir = get_directory_for_code_container(container)
    container_parts = container_name.split(".")
    container_root = os.sep.join(
        container_dir.split(os.sep)[:-len(container_parts)])
    rootlen = len(container_root)

    for dirpath, _, filenames in os.walk(container_dir):
        leafdir = dirpath[rootlen:].lstrip(os.sep)
        leafcontainer = leafdir.replace(os.sep, ".")
        for nxtfile in filenames:
            nfbase, nfext = os.path.splitext(nxtfile)
            if nfext != ".py":
                continue

            if nfbase == "__init__":
                nxtmodname = "%s" % (leafcontainer)
            else:
                nxtmodname = "%s.%s" % (leafcontainer, nfbase)

            nxtmod = import_by_name(nxtmodname)
            if nxtmod is None:
                continue

            ext_collection.extend(
                inspect.getmembers(nxtmod, predicate=is_extension_class))

    return ext_collection
Beispiel #3
0
def execute_workflow(logger, *, environment: dict, parameters: dict,
                     tasklist: list, **kwargs):

    # Publish the environment variables so they will take effect in the current
    # process and any sub-processes lauched from this process
    for key, val in environment.items():
        os.environ[key] = val

    result_code = 0

    task_ordinal = 1
    for task_info in tasklist:
        task_label = task_info["label"]
        tasktype = task_info["tasktype"]

        task_module_name, task_module_class = tasktype.split("@")
        task_module = import_by_name(task_module_name)

        failure_section = None

        if hasattr(task_module, task_module_class):
            task_class = getattr(task_module, task_module_class)

            task_instance = task_class(task_ordinal, task_label, task_info,
                                       logger)

            if failure_section is not None:
                section = task_instance.section
                if failure_section == section:
                    failure_section = None
                else:
                    # Skip ahead until we file the failure section
                    continue

            task_result = task_instance.execute(parameters=parameters,
                                                **kwargs)
            if task_result != 0:
                result_code = 1
                if task_instance.onfailure is not None:
                    failure_section = task_instance.onfailure

        else:
            error_msg = "The specified task module %r does not contain a class %r" % (
                task_module_name, task_module_class)
            raise AKitConfigurationError(error_msg) from None

    return result_code
Beispiel #4
0
    def __init__(self):
        """
            Initializes the Singleton initializer class
        """
        thisType = type(self)
        if not thisType._initialized:
            thisType._initialized = True

            self._dyn_embedded_device_registry = {}
            self._dyn_root_device_registry = {}
            self._dyn_service_registry = {}
            self._std_embedded_device_registry = {}
            self._std_root_device_registry = {}
            self._std_service_registry = {}

            dyn_ext_module = None
            dyn_ext_module_name = AKIT_VARIABLES.AKIT_UPNP_DYN_EXTENSIONS_MODULE
            if dyn_ext_module_name is not None:
                dyn_ext_module = import_by_name(dyn_ext_module_name)

            dyn_ext_folder = AKIT_VARIABLES.AKIT_UPNP_EXTENSIONS_INTEGRATION_BASE

            if dyn_ext_module is not None:
                self._scan_for_device_extensions_under_code_container(
                    dyn_ext_module, self._dyn_root_device_registry)
                self._scan_for_service_extensions_under_code_container(
                    dyn_ext_module, self._dyn_service_registry)
            elif dyn_ext_folder is not None:
                self._scan_for_device_extensions_under_folder(
                    dyn_ext_folder, self._dyn_root_device_registry)
                self._scan_for_service_extensions_under_folder(
                    dyn_ext_folder, self._dyn_service_registry)

            self._scan_for_device_extensions_under_code_container(
                standard_extensions, self._std_root_device_registry)
            self._scan_for_service_extensions_under_code_container(
                standard_extensions, self._std_service_registry)
        return
Beispiel #5
0
def is_subclass_of_extension_points(cand_type):
    """
        Returns a boolean value indicating if the candidate type is a subclass
        of :class:`Landscape`.
    """
    is_scoep = False
    if inspect.isclass(cand_type) and issubclass(cand_type,
                                                 AKitExtensionPoints):
        is_scoep = True
    return is_scoep


def load_and_set_extension_points_type(lscape_module):
    """
        Scans the module provided for :class:`Landscape` derived classes and will
        take the first one and assign it as the current runtime landscape type.
    """
    class_items = inspect.getmembers(lscape_module,
                                     is_subclass_of_extension_points)
    for _, cls_type in class_items:
        type_module_name = cls_type.__module__
        if type_module_name == lscape_module.__name__:
            AKitExtensionPoints._extension_points_type = cls_type  # pylint: disable=protected-access
            break
    return


if AKIT_VARIABLES.AKIT_CONFIG_EXTENSION_POINTS_MODULE != "akit.extensionpoints":
    ep_module_override = import_by_name(
        AKIT_VARIABLES.AKIT_CONFIG_EXTENSION_POINTS_MODULE)
    load_and_set_extension_points_type(ep_module_override)
Beispiel #6
0
def command_akit_jobs_run(root, job, output, start, branch, build, flavor, console_level, logfile_level):

    # pylint: disable=unused-import,import-outside-toplevel

    # We do the imports of the automation framework code inside the action functions because
    # we don't want to startup loggin and the processing of inputs and environment variables
    # until we have entered an action method.  Thats way we know how to setup the environment.

    # IMPORTANT: We need to load the context first because it will trigger the loading
    # of the default user configuration
    from akit.environment.context import Context

    from akit.compat import import_by_name
    from akit.environment.variables import extend_path

    try:
        ctx = Context()
        ctx.insert("/environment/jobtype", 'testrun')

        test_root = os.path.abspath(os.path.expandvars(os.path.expanduser(root)))
        if not os.path.isdir(test_root):
            errmsg = "The specified root folder does not exist. root=%s" % root
            if test_root != root:
                errmsg += " expanded=%s" % test_root
            raise argparse.ArgumentError("--root", errmsg)

        # Make sure we extend PATH to include the test root
        extend_path(test_root)

        # We perform activation a little later in the testrunner.py file so we can
        # handle exceptions in the context of testrunner_main function
        import akit.activation.testrun
        from akit.xlogging.foundations import logging_initialize, getAutomatonKitLogger

        # Initialize logging
        logging_initialize()
        logger = getAutomatonKitLogger()

        from akit.extensionpoints import AKitExtensionPoints
        akep = AKitExtensionPoints()

        # At this point in the code, we either lookup an existing test job or we create a test job
        # from the includes, excludes or test_module
        TestJobType = akep.get_testplus_default_job_type()

        if job is not None:
            job_parts = job.split("@")
            if len(job_parts) != 2:
                errmsg = "A --job parameter must be of the form 'package.module@JobClass'"
                raise click.UsageError(errmsg)

            job_package, job_class = job_parts

            try:
                job_mod = import_by_name(job_package)
            except ImportError as imperr:
                errmsg = "Failure while importing job package %r"  % job_package
                raise argparse.ArgumentError("--job", errmsg) from imperr

            if not hasattr(job_mod, job_class):
                errmsg = "The job package %r does not have a job type %r." % (job_package, job_class)
                raise argparse.ArgumentError("--job", errmsg)

            TestJobType = getattr(job_mod, job_class)

        result_code = 0
        with TestJobType(logger, test_root) as tjob:
            result_code = tjob.execute()

        sys.exit(result_code)

    finally:
        pass

    return
Beispiel #7
0
def load_and_set_landscape_type(lscape_module):
    """
        Scans the module provided for :class:`Landscape` derived classes and will
        take the first one and assign it as the current runtime landscape type.
    """
    class_items = inspect.getmembers(lscape_module, is_subclass_of_landscape)
    for _, cls_type in class_items:
        type_module_name = cls_type.__module__
        if type_module_name == lscape_module.__name__:
            Landscape._landscape_type = cls_type  # pylint: disable=protected-access
            break
    return


if AKIT_VARIABLES.AKIT_CONFIG_LANDSCAPE_MODULE is not None:
    lscape_module_override = import_by_name(
        AKIT_VARIABLES.AKIT_CONFIG_LANDSCAPE_MODULE)
    load_and_set_landscape_type(lscape_module_override)

# We need to ensure that the first time this module is loaded that we trigger
# the initialization of the landscape and that we activate the configuration
first_landscape = Landscape()
first_landscape.activate_configuration()


def startup_landscape(include_ssh: bool = True,
                      include_upnp: bool = True,
                      allow_missing_devices: bool = False,
                      allow_unknown_devices: bool = False,
                      validate_topology: bool = True,
                      interactive: Optional[bool] = None) -> Landscape:
    """