def from_cli(cls, argv=None) -> 'Target': """ Create a Target from command line arguments. :param argv: The list of arguments. ``sys.argv[1:]`` will be used if this is ``None``. :type argv: list(str) Trying to use this in a script that expects extra arguments is bound to be confusing (help message woes, argument clashes...), so for now this should only be used in scripts that only expect Target args. """ parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=textwrap.dedent(""" Connect to a target using the provided configuration in order to run a test. EXAMPLES --target-conf can point to a YAML target configuration file with all the necessary connection information: $ {script} --target-conf my_target.yml Alternatively, --kind must be set along the relevant credentials: $ {script} --kind linux --host 192.0.2.1 --username root --password root In both cases, --platform-info can point to a PlatformInfo YAML file. """.format(script=os.path.basename(sys.argv[0])))) kind_group = parser.add_mutually_exclusive_group(required=True) kind_group.add_argument("--kind", "-k", choices=["android", "linux", "host"], help="The kind of target to connect to.") kind_group.add_argument( "--target-conf", "-t", help= "Path to a TargetConf yaml file. Superseeds other target connection related options." ) device_group = parser.add_mutually_exclusive_group() device_group.add_argument( "--device", "-d", help= "The ADB ID of the target. Superseeds --host. Only applies to Android kind." ) device_group.add_argument("--host", "-n", help="The hostname/IP of the target.") parser.add_argument("--username", "-u", help="Login username. Only applies to Linux kind.") parser.add_argument("--password", "-p", help="Login password. Only applies to Linux kind.") parser.add_argument("--platform-info", "-pi", help="Path to a PlatformInfo yaml file.") parser.add_argument("--log-level", default='info', choices=('warning', 'info', 'debug'), help="Verbosity level of the logs.") parser.add_argument( "--res-dir", "-o", help= "Result directory of the created Target. If no directory is specified, a default location under $LISA_HOME will be used." ) # Options that are not a key in TargetConf must be listed here not_target_conf_opt = ( 'platform_info', 'log_level', 'res_dir', 'target_conf', ) args = parser.parse_args(argv) setup_logging(level=args.log_level.upper()) if args.kind == 'android': if not (args.host or args.device): parser.error('--host or --device must be specified') if args.kind == 'linux': for required in ['host', 'username', 'password']: if getattr(args, required) is None: parser.error('--{} must be specified'.format(required)) platform_info = PlatformInfo.from_yaml_map( args.platform_info) if args.platform_info else None if args.target_conf: target_conf = TargetConf.from_yaml_map(args.target_conf) else: target_conf = TargetConf({ k: v for k, v in vars(args).items() if v is not None and k not in not_target_conf_opt }) return cls.from_conf(conf=target_conf, plat_info=platform_info, res_dir=args.res_dir)
def from_custom_cli(cls, argv=None, params=None) -> 'Target': """ Create a Target from command line arguments. :param argv: The list of arguments. ``sys.argv[1:]`` will be used if this is ``None``. :type argv: list(str) :param params: Dictionary of custom parameters to add to the parser. It is in the form of ``{param_name: {dict of ArgumentParser.add_argument() options}}``. :type params: dict(str, dict) :return: A tuple ``(args, target)`` .. note:: This method should not be relied upon to implement long-term scripts, it's more designed for quick scripting. """ parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=textwrap.dedent( """ Connect to a target using the provided configuration in order to run a test. EXAMPLES --conf can point to a YAML target configuration file with all the necessary connection information: $ {script} --conf my_target.yml Alternatively, --kind must be set along the relevant credentials: $ {script} --kind linux --host 192.0.2.1 --username root --password root In both cases, --conf can also contain a PlatformInfo YAML description. """.format( script=os.path.basename(sys.argv[0]) ))) parser.add_argument("--conf", '-c', help="Path to a TargetConf and PlatformInfo yaml file. Other options will override what is specified in the file." ) parser.add_argument("--kind", "-k", choices=["android", "linux", "host"], help="The kind of target to connect to.") device_group = parser.add_mutually_exclusive_group() device_group.add_argument("--device", "-d", help="The ADB ID of the target. Superseeds --host. Only applies to Android kind.") device_group.add_argument("--host", "-n", help="The hostname/IP of the target.") parser.add_argument("--username", "-u", help="Login username. Only applies to Linux kind.") parser.add_argument("--password", "-p", help="Login password. Only applies to Linux kind.") parser.add_argument("--log-level", default='info', choices=('warning', 'info', 'debug'), help="Verbosity level of the logs.") parser.add_argument("--res-dir", "-o", help="Result directory of the created Target. If no directory is specified, a default location under $LISA_HOME will be used.") params = params or {} for param, settings in params.items(): parser.add_argument('--{}'.format(param), **settings) custom_params = {k.replace('-', '_') for k in params.keys()} # Options that are not a key in TargetConf must be listed here not_target_conf_opt = { 'platform_info', 'log_level', 'res_dir', 'conf', } not_target_conf_opt.update(custom_params) args = parser.parse_args(argv) setup_logging(level=args.log_level.upper()) target_conf = TargetConf() platform_info = None if args.conf: # Tentatively load a PlatformInfo from the conf file with contextlib.suppress(KeyError): platform_info = PlatformInfo.from_yaml_map(args.conf) # Load the TargetConf from the file, and update it with command # line arguments try: conf = TargetConf.from_yaml_map(args.conf) except KeyError: pass else: target_conf.add_src(args.conf, conf) target_conf.add_src('command-line', { k: v for k, v in vars(args).items() if v is not None and k not in not_target_conf_opt }) # Some sanity check to get better error messages if not target_conf: parser.error('--conf with target configuration or any of the connection options is required') if args.kind == 'android': if ('host' not in target_conf) and ('device' not in target_conf): parser.error('--host or --device must be specified') if args.kind == 'linux': for required in ['host', 'username', 'password']: if required not in target_conf: parser.error('--{} must be specified'.format(required)) custom_args = { param: value for param, value in vars(args).items() if param in custom_params } custom_args = argparse.Namespace(**custom_args) return custom_args, cls.from_conf(conf=target_conf, plat_info=platform_info, res_dir=args.res_dir)
import logging import os from lisa.trace import FtraceCollector, Trace from lisa.utils import setup_logging from lisa.target import Target, TargetConf from lisa.wlgen.rta import RTA, Periodic from lisa.datautils import df_filter_task_ids import pandas as pd setup_logging() target = Target.from_one_conf('conf/lisa/qemu_target_default.yml') #target = Target.from_default_conf() rtapp_profile = {} tasks = [] for cpu in range(4): tasks.append("tsk{}-{}".format(cpu, cpu)) rtapp_profile["tsk{}".format(cpu)] = Periodic(duty_cycle_pct=50, duration_s=120) wload = RTA.by_profile(target, "experiment_wload", rtapp_profile) ftrace_coll = FtraceCollector(target, events=["sched_switch"]) trace_path = os.path.join(wload.res_dir, "trace.dat") with ftrace_coll: wload.run() ftrace_coll.get_trace(trace_path) trace = Trace(trace_path, target.plat_info, events=["sched_switch"]) # sched_switch __comm __pid __cpu __line prev_comm prev_pid prev_prio prev_state next_comm next_pid next_prio