示例#1
0
def get_analysis_list(meth_type):
    rst_list = []

    for subclass in get_subclasses(TraceAnalysisBase):
        class_path = "{}.{}".format(subclass.__module__, subclass.__qualname__)
        analysis = subclass.__module__.split(".")[-1]
        if meth_type == 'plot':
            meth_list = [f.__name__ for f in subclass.get_plot_methods()]
        elif meth_type == 'df':
            meth_list = [
                name
                for name, member in inspect.getmembers(subclass, callable)
                if name.startswith('df_')
            ]
        else:
            raise ValueError()

        rst_list += [
            ":class:`{analysis_name}<{cls}>`::meth:`~{cls}.{meth}`".format(
                analysis_name=analysis,
                cls=class_path,
                meth=meth,
            ) for meth in meth_list
        ]

    joiner = '\n* '
    return joiner + joiner.join(rst_list)
示例#2
0
    def from_conf(cls, target, conf, res_dir=None):
        """
        Build an instance of :class:`EnergyMeter` from a
        configuration object.

        :param target: Target to use
        :type target: lisa.target.Target

        :param conf: Configuration object to use

        :param res_dir: Result directory to use
        :type res_dir: str or None
        """
        # Select the right subclass according to the type of the configuration
        # object we are given
        for subcls in get_subclasses(cls) | {cls}:
            try:
                conf_cls = subcls.CONF_CLASS
            except AttributeError:
                continue
            if isinstance(conf, conf_cls):
                chosen_cls = subcls
                break
        else:
            chosen_cls = cls

        chosen_cls.get_logger(
            f'{chosen_cls.name} energy meter configuration:\n{conf}')
        kwargs = chosen_cls.conf_to_init_kwargs(conf)
        kwargs.update(
            target=target,
            res_dir=res_dir,
        )
        chosen_cls.check_init_param(**kwargs)
        return chosen_cls(**kwargs)
示例#3
0
def get_analysis_list(meth_type):
    rst_list = []

    deprecated = {entry['obj'] for entry in get_deprecated_map().values()}

    for subclass in get_subclasses(AnalysisHelpers):
        class_path = f"{subclass.__module__}.{subclass.__qualname__}"
        if meth_type == 'plot':
            meth_list = subclass.get_plot_methods()
        elif meth_type == 'df':
            meth_list = [
                member
                for name, member in inspect.getmembers(subclass, callable)
                if name.startswith('df_')
            ]
        else:
            raise ValueError()

        meth_list = [f.__name__ for f in meth_list if f not in deprecated]

        rst_list += [
            f":class:`{subclass.name}<{class_path}>`::meth:`~{class_path}.{meth}`"
            for meth in meth_list
        ]

    joiner = '\n* '
    return joiner + joiner.join(sorted(rst_list))
示例#4
0
def autodoc_process_analysis_plots(app, what, name, obj, options, lines, plot_conf):
    if what != 'method':
        return

    plot_methods = set(itertools.chain.from_iterable(
        subclass.get_plot_methods()
        for subclass in get_subclasses(TraceAnalysisBase)
    ))

    if obj not in plot_methods:
        return

    plot_conf = plot_conf['plots']

    default_spec = plot_conf.get('default', {})
    spec = plot_conf.get(obj.__qualname__, {})
    spec = {**default_spec, **spec}
    kwargs = spec.get('kwargs', {})
    trace = spec['trace']

    if spec.get('hide'):
        return

    print('Generating plot for {}'.format(obj.__qualname__))
    rst_figure = TraceAnalysisBase.call_on_trace(obj, trace, {
        'output': 'rst',
        'always_save': False,
        # avoid memory leaks
        'interactive': False,
        **kwargs
    })
    rst_figure = '\n:Example plot:\n\n{}'.format(rst_figure)
    lines.extend(rst_figure.splitlines())
示例#5
0
 def get_analysis_classes(cls):
     return {
         subcls.name: subcls
         for subcls in get_subclasses(cls)
         # Classes without a "name" attribute directly defined in their
         # scope will not get registered. That allows having unnamed
         # intermediate base classes that are not meant to be exposed.
         if 'name' in subcls.__dict__
     }
示例#6
0
def get_subclasses_bullets(cls, abbrev=True, style=None, only_leaves=False):
    """
    Return a formatted bullet list of the subclasses of the given class,
    including a short description for each.
    """
    return '\n'.join(f'* {subcls}: {doc}' for subcls, doc in sorted(
        (get_sphinx_name(subcls, style=style, abbrev=abbrev),
         get_short_doc(subcls))
        for subcls in get_subclasses(cls, only_leaves=only_leaves)))
示例#7
0
    def get_prebuilt_op_set(self):
        non_reusable_type_set = self.get_non_reusable_type_set()
        op_set = set()

        # Try to build as many configurations instances from all the files we
        # are given
        conf_cls_set = set(get_subclasses(MultiSrcConf, only_leaves=True))
        conf_list = []
        for conf_path in self.args.conf:
            for conf_cls in conf_cls_set:
                try:
                    # Do not add the default source, to avoid overriding user
                    # configuration with the default one.
                    conf = conf_cls.from_yaml_map(conf_path,
                                                  add_default_src=False)
                except ValueError:
                    continue
                else:
                    conf_list.append((conf, conf_path))

        def keyfunc(conf_and_path):
            cls = type(conf_and_path[0])
            # We use the ID since classes are not comparable
            return id(cls), cls

        # Then aggregate all the conf from each type, so they just act as
        # alternative sources.
        for (_, conf_cls), conf_and_path_seq in groupby(conf_list,
                                                        key=keyfunc):
            conf_and_path_list = list(conf_and_path_seq)

            # Get the default configuration, and stack all user-defined keys
            conf = conf_cls()
            for conf_src, conf_path in conf_and_path_list:
                src = os.path.basename(conf_path)
                conf.add_src(src, conf_src)

            op_set.add(
                PrebuiltOperator(conf_cls, [conf],
                                 non_reusable_type_set=non_reusable_type_set))

        # Inject serialized objects as root operators
        for path in self.args.inject:
            obj = Serializable.from_path(path)
            op_set.add(
                PrebuiltOperator(type(obj), [obj],
                                 non_reusable_type_set=non_reusable_type_set))

        # Inject a dummy empty TargetConf
        if self.args.inject_empty_target_conf:
            op_set.add(
                PrebuiltOperator(TargetConf, [TargetConf(conf={})],
                                 non_reusable_type_set=non_reusable_type_set))

        return op_set
示例#8
0
    def __init__(self, path, kernel_path=None):
        self.path = path
        self.kernel_path = kernel_path

        collector_classes = {
            cls.NAME: cls
            for cls in get_subclasses(WACollectorBase, only_leaves=True)
        }
        auto_collectors = {
            name: cls
            for name, cls in collector_classes.items()
            if not self._needs_params(cls)
        }
        self._auto_collectors = auto_collectors
        self._available_collectors = collector_classes
示例#9
0
def autodoc_process_analysis_methods(app, what, name, obj, options, lines):
    """
    Append the list of required trace events
    """
    methods = {
        func: subclass
        for subclass in get_subclasses(TraceAnalysisBase)
        for name, func in inspect.getmembers(subclass, callable)
    }

    try:
        cls = methods[obj]
    except (KeyError, TypeError):
        return
    else:
        on_trace_name = f'trace.ana.{cls.name}.{obj.__name__}'
        extra_doc = f"\n*Called on* :class:`~lisa.trace.Trace` *instances as* ``{on_trace_name}()``\n\n"
        # prepend
        lines[:0] = extra_doc.splitlines()
示例#10
0
def autodoc_process_analysis_plots(app, what, name, obj, options, lines,
                                   plot_conf):
    if what != 'method':
        return

    plot_methods = set(
        itertools.chain.from_iterable(
            subclass.get_plot_methods()
            for subclass in get_subclasses(TraceAnalysisBase)))

    if obj not in plot_methods:
        return

    plot_conf = plot_conf['plots']

    default_spec = plot_conf.get('default', {})
    spec = plot_conf.get(obj.__qualname__, {})
    spec = {**default_spec, **spec}
    kwargs = spec.get('kwargs', {})
    trace = spec['trace']

    if spec.get('hide'):
        return

    print(f'Generating plot for {obj.__qualname__}')

    # Suppress deprecation warnings so we can still have them in the doc
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=DeprecationWarning)

        rst_figure = TraceAnalysisBase.call_on_trace(
            obj, trace, {
                'backend': 'bokeh',
                'output': 'sphinx-rst',
                'interactive': False,
                **kwargs
            })
    rst_figure = f'\n:Example plot:\n\n{rst_figure}'
    lines.extend(rst_figure.splitlines())
示例#11
0
    def _init_target(self, kind, name, workdir, device, host,
            port, username, password, keyfile,
            devlib_platform, devlib_excluded_modules,
            wait_boot, wait_boot_timeout,
    ):
        """
        Initialize the Target
        """
        logger = self.get_logger()
        conn_settings = {}

        # If the target is Android, we need just (eventually) the device
        if kind == 'android':
            logger.debug('Setting up Android target...')
            devlib_target_cls = devlib.AndroidTarget

            # Workaround for ARM-software/devlib#225
            workdir = workdir or '/data/local/tmp/devlib-target'

            if device:
                pass
            elif host:
                port = port or self.ADB_PORT_DEFAULT
                device = '{}:{}'.format(host, port)
            else:
                device = 'DEFAULT'

            conn_settings['device'] = device

        elif kind == 'linux':
            logger.debug('Setting up Linux target...')
            devlib_target_cls = devlib.LinuxTarget

            conn_settings['username'] = username
            conn_settings['port'] = port or self.SSH_PORT_DEFAULT
            conn_settings['host'] = host


            # Configure password or SSH keyfile
            if keyfile:
                conn_settings['keyfile'] = keyfile
            else:
                conn_settings['password'] = password
        elif kind == 'host':
            logger.debug('Setting up localhost Linux target...')
            devlib_target_cls = devlib.LocalLinuxTarget
            # If we are given a password, assume we can use it as a sudo
            # password.
            conn_settings['unrooted'] = password is None
            conn_settings['password'] = password
        else:
            raise ValueError('Unsupported platform type {}'.format(kind))

        logger.info('%s %s target connection settings:', kind, name)
        for key, val in conn_settings.items():
            logger.info('%10s : %s', key, val)

        ########################################################################
        # Devlib Platform configuration
        ########################################################################

        if not devlib_platform:
            devlib_platform = devlib.platform.Platform()

        ########################################################################
        # Devlib modules configuration
        ########################################################################

        # Make sure all submodules of devlib.module are imported so the classes
        # are all created
        import_all_submodules(devlib.module)
        # Get all devlib Module subclasses that exist
        devlib_module_set = {
            cls.name
            for cls in get_subclasses(devlib.module.Module)
            if (
                getattr(cls, 'name', None)
                # early modules try to connect to UART and do very
                # platform-specific things we are not interested in
                and getattr(cls, 'stage') != 'early'
            )
        }

        # The platform can define a list of modules to exclude, in case a given
        # module really have troubles on a given platform.
        devlib_module_set.difference_update(devlib_excluded_modules)

        devlib_module_list = sorted(devlib_module_set)
        logger.info('Devlib modules to load: %s', ', '.join(devlib_module_list))

        ########################################################################
        # Create devlib Target object
        ########################################################################

        target = devlib_target_cls(
            platform = devlib_platform,
            modules = devlib_module_list,
            load_default_modules = False,
            connection_settings = conn_settings,
            working_directory = workdir,
            connect=False,
        )

        target.connect(check_boot_completed=wait_boot, timeout=wait_boot_timeout)

        logger.debug('Checking target connection...')
        logger.debug('Target info:')
        logger.debug('      ABI: %s', target.abi)
        logger.debug('     CPUs: %s', target.cpuinfo)
        logger.debug(' clusters: %s', target.core_clusters)
        logger.debug('  workdir: %s', target.working_directory)

        target.setup()

        if isinstance(target, devlib.AndroidTarget):
            target.adb_root(force=True)

        # Verify that all the required modules have been initialized
        for module in devlib_module_list:
            if not hasattr(target, module):
                logger.warning('Failed to initialized "{}" devlib Module'.format(module))
        return target
示例#12
0
from lisa.conf import SimpleMultiSrcConf, KeyDesc, LevelKeyDesc, TopLevelKeyDesc, StrList, Configurable

from lisa.platforms.platinfo import PlatformInfo


class PasswordKeyDesc(KeyDesc):
    def pretty_format(self, v):
        return '<password>'


# Make sure all submodules of devlib.module are imported so the classes
# are all created before we list them
import_all_submodules(devlib.module)
_DEVLIB_AVAILABLE_MODULES = {
    cls.name
    for cls in get_subclasses(devlib.module.Module) if
    (getattr(cls, 'name', None)
     # early modules try to connect to UART and do very
     # platform-specific things we are not interested in
     and getattr(cls, 'stage') != 'early')
}


class TargetConf(SimpleMultiSrcConf, HideExekallID):
    """
    Target connection settings.

    Only keys defined below are allowed, with the given meaning and type:

    {generated_help}