mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-01-19 04:21:17 +00:00
RecordCommand: Improved record command to handle workloads
The wa record command now has the ability to record revent files for wa workload. The command with automatically deploy the workload and record both setup and run revent recordings Conflicts: wlauto/commands/record.py
This commit is contained in:
parent
98b46894d8
commit
0057a531fd
@ -16,11 +16,15 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
from wlauto import Command, settings
|
||||
from wlauto.core import pluginloader
|
||||
from wlauto.common.resources import Executable
|
||||
from wlauto.core.resource import NO_ONE
|
||||
from wlauto.core.resolver import ResourceResolver
|
||||
from wlauto.core.configuration import RunConfiguration
|
||||
from wlauto.core.agenda import Agenda
|
||||
from wlauto.common.android.workload import ApkWorkload
|
||||
|
||||
|
||||
class RecordCommand(Command):
|
||||
@ -50,78 +54,126 @@ class RecordCommand(Command):
|
||||
def initialize(self, context):
|
||||
self.context = context
|
||||
self.parser.add_argument('-d', '--device', help='The name of the device')
|
||||
self.parser.add_argument('-s', '--suffix', help='The suffix of the revent file, e.g. ``setup``')
|
||||
self.parser.add_argument('-o', '--output', help='Directory to save the recording in')
|
||||
self.parser.add_argument('-p', '--package', help='Package to launch before recording')
|
||||
|
||||
# Need validation
|
||||
self.parser.add_argument('-s', '--suffix', help='The suffix of the revent file, e.g. ``setup``')
|
||||
self.parser.add_argument('-C', '--clear', help='Clear app cache before launching it',
|
||||
action="store_true")
|
||||
|
||||
group = self.parser.add_mutually_exclusive_group(required=False)
|
||||
group.add_argument('-p', '--package', help='Package to launch before recording')
|
||||
group.add_argument('-w', '--workload', help='Name of a revent workload (mostly games)')
|
||||
|
||||
# Validate command options
|
||||
def validate_args(self, args):
|
||||
if args.clear and not args.package:
|
||||
print "Package must be specified if you want to clear cache\n"
|
||||
if args.clear and not (args.package or args.workload):
|
||||
self.logger.error("Package/Workload must be specified if you want to clear cache")
|
||||
self.parser.print_help()
|
||||
sys.exit()
|
||||
if args.workload and args.suffix:
|
||||
self.logger.error("cannot specify manual suffixes for workloads")
|
||||
self.parser.print_help()
|
||||
sys.exit()
|
||||
if args.suffix:
|
||||
args.suffix += "."
|
||||
|
||||
# pylint: disable=W0201
|
||||
def execute(self, args):
|
||||
self.validate_args(args)
|
||||
self.logger.info("Connecting to device...")
|
||||
|
||||
ext_loader = PluginLoader(packages=settings.plugin_packages,
|
||||
paths=settings.plugin_paths)
|
||||
|
||||
# Setup config
|
||||
self.config = RunConfiguration(ext_loader)
|
||||
for filepath in settings.get_config_paths():
|
||||
self.config = RunConfiguration(pluginloader)
|
||||
for filepath in settings.config_paths:
|
||||
self.config.load_config(filepath)
|
||||
self.config.set_agenda(Agenda())
|
||||
self.config.finalize()
|
||||
|
||||
context = LightContext(self.config)
|
||||
|
||||
# Setup device
|
||||
self.device = ext_loader.get_device(settings.device, **settings.device_config)
|
||||
self.device.validate()
|
||||
self.device.connect()
|
||||
self.device.initialize(context)
|
||||
|
||||
host_binary = context.resolver.get(Executable(NO_ONE, self.device.abi, 'revent'))
|
||||
self.target_binary = self.device.install_if_needed(host_binary)
|
||||
|
||||
self.run(args)
|
||||
|
||||
def run(self, args):
|
||||
self.device_manager = pluginloader.get_manager(self.config.device)
|
||||
self.device_manager.validate()
|
||||
self.device_manager.connect()
|
||||
context = LightContext(self.config, self.device_manager)
|
||||
self.device_manager.initialize(context)
|
||||
self.device = self.device_manager.target
|
||||
if args.device:
|
||||
self.device_name = args.device
|
||||
else:
|
||||
self.device_name = self.device.get_device_model()
|
||||
self.device_name = self.device.model
|
||||
|
||||
if args.suffix:
|
||||
args.suffix += "."
|
||||
# Install Revent
|
||||
host_binary = context.resolver.get(Executable(NO_ONE, self.device.abi, 'revent'))
|
||||
self.target_binary = self.device.install_if_needed(host_binary)
|
||||
|
||||
revent_file = self.device.path.join(self.device.working_directory,
|
||||
'{}.{}revent'.format(self.device_name, args.suffix or ""))
|
||||
if args.workload:
|
||||
self.workload_record(args, context)
|
||||
elif args.package:
|
||||
self.package_record(args, context)
|
||||
else:
|
||||
self.manual_record(args, context)
|
||||
|
||||
def manual_record(self, args, context):
|
||||
revent_file = self.device.get_workpath('{}.{}revent'.format(self.device_name, args.suffix or ""))
|
||||
self._record(revent_file, "", args.output)
|
||||
|
||||
def package_record(self, args, context):
|
||||
revent_file = self.device.get_workpath('{}.{}revent'.format(self.device_name, args.suffix or ""))
|
||||
if args.clear:
|
||||
self.device.execute("pm clear {}".format(args.package))
|
||||
|
||||
if args.package:
|
||||
self.logger.info("Starting {}".format(args.package))
|
||||
self.device.execute('monkey -p {} -c android.intent.category.LAUNCHER 1'.format(args.package))
|
||||
self.logger.info("Starting {}".format(args.package))
|
||||
self.device.execute('monkey -p {} -c android.intent.category.LAUNCHER 1'.format(args.package))
|
||||
|
||||
self.logger.info("Press Enter when you are ready to record...")
|
||||
self._record(revent_file, "", args.output)
|
||||
|
||||
def workload_record(self, args, context):
|
||||
setup_file = self.device.get_workpath('{}.setup.revent'.format(self.device_name))
|
||||
run_file = self.device.get_workpath('{}.run.revent'.format(self.device_name))
|
||||
|
||||
self.logger.info("Deploying {}".format(args.workload))
|
||||
workload = pluginloader.get_workload(args.workload, self.device)
|
||||
workload.apk_init_resources(context)
|
||||
workload.initialize_package(context)
|
||||
workload.do_post_install(context)
|
||||
workload.start_activity()
|
||||
|
||||
if args.clear:
|
||||
workload.reset(context)
|
||||
|
||||
self._record(setup_file, " SETUP",
|
||||
args.output or os.path.join(workload.dependencies_directory, 'revent_files'))
|
||||
self._record(run_file, " RUN",
|
||||
args.output or os.path.join(workload.dependencies_directory, 'revent_files'))
|
||||
|
||||
self.logger.info("Tearing down {}".format(args.workload))
|
||||
workload.apk_teardown(context)
|
||||
|
||||
def _record(self, revent_file, name, output_path):
|
||||
self.logger.info("Press Enter when you are ready to record{}...".format(name))
|
||||
raw_input("")
|
||||
command = "{} record -t 100000 -s {}".format(self.target_binary, revent_file)
|
||||
self.device.kick_off(command)
|
||||
|
||||
self.logger.info("Press Enter when you have finished recording...")
|
||||
self.logger.info("Press Enter when you have finished recording {}...".format(name))
|
||||
raw_input("")
|
||||
self.device.killall("revent")
|
||||
|
||||
self.logger.info("Pulling files from device")
|
||||
self.device.pull(revent_file, args.output or os.getcwdu())
|
||||
output_path = output_path or os.getcwdu()
|
||||
if not os.path.isdir(output_path):
|
||||
os.mkdirs(output_path)
|
||||
|
||||
revent_file_name = self.device.path.basename(revent_file)
|
||||
host_path = os.path.join(output_path, revent_file_name)
|
||||
if os.path.exists(host_path):
|
||||
self.logger.info("Revent file '{}' already exists, overwrite? [y/n]".format(revent_file_name))
|
||||
if raw_input("") == "y":
|
||||
os.remove(host_path)
|
||||
else:
|
||||
self.logger.warning("Did not pull and overwrite '{}'".format(revent_file_name))
|
||||
return
|
||||
self.logger.info("Pulling '{}' from device".format(self.device.path.basename(revent_file)))
|
||||
self.device.pull(revent_file, output_path)
|
||||
|
||||
class ReplayCommand(RecordCommand):
|
||||
|
||||
@ -139,6 +191,7 @@ class ReplayCommand(RecordCommand):
|
||||
self.parser.add_argument('-C', '--clear', help='Clear app cache before launching it',
|
||||
action="store_true")
|
||||
|
||||
|
||||
# pylint: disable=W0201
|
||||
def run(self, args):
|
||||
self.logger.info("Pushing file to device")
|
||||
@ -159,6 +212,7 @@ class ReplayCommand(RecordCommand):
|
||||
|
||||
# Used to satisfy the API
|
||||
class LightContext(object):
|
||||
def __init__(self, config):
|
||||
def __init__(self, config, device_manager):
|
||||
self.resolver = ResourceResolver(config)
|
||||
self.resolver.load()
|
||||
self.device_manager = device_manager
|
||||
|
@ -301,19 +301,24 @@ class ReventWorkload(Workload):
|
||||
default_setup_timeout = 5 * 60 # in seconds
|
||||
default_run_timeout = 10 * 60 # in seconds
|
||||
|
||||
@property
|
||||
def on_device_setup_revent(self):
|
||||
return self.device.get_workpath('{}.setup.revent'.format(self.device.model))
|
||||
|
||||
@property
|
||||
def on_device_run_revent(self):
|
||||
return self.device.get_workpath('{}.run.revent'.format(self.device.model))
|
||||
|
||||
def __init__(self, device, _call_super=True, **kwargs):
|
||||
if _call_super:
|
||||
super(ReventWorkload, self).__init__(device, **kwargs)
|
||||
devpath = self.device.path
|
||||
self.on_device_revent_binary = devpath.join(self.device.binaries_directory, 'revent')
|
||||
self.on_device_setup_revent = devpath.join(self.device.working_directory, '{}.setup.revent'.format(self.device.name))
|
||||
self.on_device_run_revent = devpath.join(self.device.working_directory, '{}.run.revent'.format(self.device.name))
|
||||
self.on_device_revent_binary = None
|
||||
self.setup_timeout = kwargs.get('setup_timeout', self.default_setup_timeout)
|
||||
self.run_timeout = kwargs.get('run_timeout', self.default_run_timeout)
|
||||
self.revent_setup_file = None
|
||||
self.revent_run_file = None
|
||||
|
||||
def init_resources(self, context):
|
||||
def initialize(self, context):
|
||||
self.revent_setup_file = context.resolver.get(wlauto.common.android.resources.ReventFile(self, 'setup'))
|
||||
self.revent_run_file = context.resolver.get(wlauto.common.android.resources.ReventFile(self, 'run'))
|
||||
|
||||
@ -433,8 +438,11 @@ class GameWorkload(ApkWorkload, ReventWorkload):
|
||||
self.module_dir = os.path.dirname(sys.modules[self.__module__].__file__)
|
||||
self.revent_dir = os.path.join(self.module_dir, 'revent_files')
|
||||
|
||||
def init_resources(self, context):
|
||||
def apk_init_resources(self, context):
|
||||
ApkWorkload.init_resources(self, context)
|
||||
|
||||
def init_resources(self, context):
|
||||
self.apk_init_resources(context)
|
||||
ReventWorkload.init_resources(self, context)
|
||||
|
||||
def setup(self, context):
|
||||
@ -461,11 +469,14 @@ class GameWorkload(ApkWorkload, ReventWorkload):
|
||||
def run(self, context):
|
||||
ReventWorkload.run(self, context)
|
||||
|
||||
def teardown(self, context):
|
||||
def apk_teardown(self, context):
|
||||
if not self.saved_state_file:
|
||||
ApkWorkload.teardown(self, context)
|
||||
else:
|
||||
self.device.execute('am force-stop {}'.format(self.package))
|
||||
|
||||
def teardown(self, context):
|
||||
self.apk_teardown(context)
|
||||
ReventWorkload.teardown(self, context)
|
||||
|
||||
def _deploy_assets(self, context, timeout=300):
|
||||
@ -478,7 +489,7 @@ class GameWorkload(ApkWorkload, ReventWorkload):
|
||||
kind = 'data'
|
||||
if ':' in resource_file:
|
||||
kind, resource_file = resource_file.split(':', 1)
|
||||
ondevice_cache = self.device.path.join(self.device.resource_cache, self.name, resource_file)
|
||||
ondevice_cache = self.device.path.join(self.device.working_directory, '.cache', self.name, resource_file)
|
||||
if not self.device.file_exists(ondevice_cache):
|
||||
asset_tarball = context.resolver.get(PluginAsset(self, resource_file))
|
||||
if not asset_tarball:
|
||||
@ -488,7 +499,7 @@ class GameWorkload(ApkWorkload, ReventWorkload):
|
||||
# exist.
|
||||
self.device.push(asset_tarball, ondevice_cache, timeout=timeout)
|
||||
|
||||
device_asset_directory = self.device.path.join(self.context.device_manager.external_storage_directory, 'Android', kind)
|
||||
device_asset_directory = self.device.path.join(context.device_manager.external_storage_directory, 'Android', kind)
|
||||
deploy_command = 'cd {} && {} tar -xzf {}'.format(device_asset_directory,
|
||||
self.device.busybox,
|
||||
ondevice_cache)
|
||||
|
Loading…
x
Reference in New Issue
Block a user