☠☠ backed out by 5d2aa419a72c ☠ ☠ | |
author | Chris Hartjes <chartjes@mozilla.com> |
Thu, 09 May 2019 20:39:43 +0000 | |
changeset 535188 | ba9d948d404c9e4d2b915bc1c0e3e6c249e13677 |
parent 535187 | b447fc4d689de4b9fea2f1f487ed63cd04806f82 |
child 535189 | 5e3d6e5df827b23b963386002c4ba2c6fba87fae |
push id | 2082 |
push user | ffxbld-merge |
push date | Mon, 01 Jul 2019 08:34:18 +0000 |
treeherder | mozilla-release@2fb19d0466d2 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | rwood |
bugs | 1544470 |
milestone | 68.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/taskcluster/ci/config.yml +++ b/taskcluster/ci/config.yml @@ -30,16 +30,18 @@ treeherder: 'R-sw': 'Reftests with serviceworker redesign' 'R-sw-1proc': 'Reftests with serviceworker redesign enabled without e10s' 'Rap': 'Raptor performance tests on Firefox' 'Rap-1proc': 'Raptor performance tests on Firefox without e10s' 'Rap-Prof': 'Raptor performance tests on Firefox with Gecko Profiling' 'Rap-Prof-1proc': 'Raptor performance tests on Firefox with Gecko Profiling and without e10s' 'Rap-ChC': 'Raptor performance tests on Google Chrome Canary' 'Rap-ChD': 'Raptor performance tests on Google Chrome Dev' + 'Rap-Cpu': 'Raptor CPU tests on Android' + 'Rap-CPU-1proc': 'Reaptor CPU tests on Android without e10s' 'Rap-Cr': 'Raptor performance tests on Google Chromium' 'Rap-P': 'Raptor power tests on Firefox' 'Rap-P-1proc': 'Raptor power tests on Firefox without e10s' 'Rap-fenix': 'Raptor performance tests on Fenix' 'Rap-refbrow': 'Raptor performance tests on the reference browser' 'T': 'Talos performance tests' 'T-1proc': 'Talos performance tests without e10s' 'Tsd': 'Talos performance tests with e10s, Stylo disabled'
--- a/taskcluster/ci/test/raptor.yml +++ b/taskcluster/ci/test/raptor.yml @@ -1021,16 +1021,36 @@ raptor-speedometer-geckoview-power: - --test=raptor-speedometer - --app=geckoview - --binary=org.mozilla.geckoview_example - --power-test - --page-cycles 5 - --host HOST_IP - --activity=GeckoViewActivity +raptor-speedometer-geckoview-cpu: + description: "Raptor Speedometer CPU on Geckoview" + try-name: raptor-speedometer-geckoview-cpu + treeherder-symbol: Rap-Cpu(sp) + target: geckoview_example.apk + run-on-projects: + by-test-platform: + android-hw.*/pgo: ['try', 'mozilla-central'] + android-hw-.*-aarch64/opt: ['try', 'mozilla-central'] + android-hw-.*-api-16/opt: ['try'] + tier: 2 + max-run-time: 1800 + mozharness: + extra-options: + - --test=raptor-speedometer + - --app=geckoview + - --binary=org.mozilla.geckoview_example + - --cpu-test + - --activity=GeckoViewActivity + raptor-speedometer-fennec: description: "Raptor Speedometer on Fennec" try-name: raptor-speedometer-fennec treeherder-symbol: Rap(sp) target: target.apk run-on-projects: by-test-platform: android-hw-.*-api-16/opt: ['try']
--- a/taskcluster/ci/test/test-sets.yml +++ b/taskcluster/ci/test/test-sets.yml @@ -555,19 +555,21 @@ android-hw-aarch64-raptor: - raptor-tp6m-10-geckoview-cold - raptor-tp6m-11-geckoview-cold - raptor-tp6m-12-geckoview-cold - raptor-tp6m-13-geckoview-cold - raptor-tp6m-14-geckoview-cold android-hw-arm7-raptor-power: - raptor-speedometer-geckoview-power + - raptor-speedometer-geckoview-cpu android-hw-aarch64-raptor-power: - raptor-speedometer-geckoview-power + - raptor-speedometer-geckoview-cpu android-hw-arm7-raptor-nightly: - raptor-speedometer-fennec - raptor-tp6m-1-fennec - raptor-tp6m-2-fennec - raptor-tp6m-3-fennec - raptor-tp6m-4-fennec - raptor-tp6m-5-fennec
--- a/testing/mozharness/mozharness/mozilla/testing/raptor.py +++ b/testing/mozharness/mozharness/mozilla/testing/raptor.py @@ -151,16 +151,22 @@ class Raptor(TestingMixin, MercurialScri "argument.", }], [["--memory-test"], { "dest": "memory_test", "action": "store_true", "default": False, "help": "Use Raptor to measure memory usage.", }], + [["--cpu-test"], { + "dest": "cpu_test", + "action": "store_true", + "default": False, + "help": "Use Raptor to measure CPU usage" + }], [["--debug-mode"], { "dest": "debug_mode", "action": "store_true", "default": False, "help": "Run Raptor in debug mode (open browser console, limited page-cycles, etc.)", }], ] + testing_config_options + copy.deepcopy(code_coverage_config_options) @@ -242,16 +248,17 @@ class Raptor(TestingMixin, MercurialScri self.gecko_profile_interval = self.config.get('gecko_profile_interval') self.gecko_profile_entries = self.config.get('gecko_profile_entries') self.test_packages_url = self.config.get('test_packages_url') self.host = self.config.get('host') if self.host == 'HOST_IP': self.host = os.environ['HOST_IP'] self.power_test = self.config.get('power_test') self.memory_test = self.config.get('memory_test') + self.cpu_test = self.config.get('cpu_test') self.is_release_build = self.config.get('is_release_build') self.debug_mode = self.config.get('debug_mode', False) self.firefox_android_browsers = ["fennec", "geckoview", "refbrow", "fenix"] # We accept some configuration options from the try commit message in the # format mozharness: <options>. Example try commit message: mozharness: # --geckoProfile try: <stuff> def query_gecko_profile_options(self): @@ -377,16 +384,18 @@ class Raptor(TestingMixin, MercurialScri if self.config.get('code_coverage', False): options.extend(['--code-coverage']) if self.config.get('is_release_build', False): options.extend(['--is-release-build']) if self.config.get('power_test', False): options.extend(['--power-test']) if self.config.get('memory_test', False): options.extend(['--memory-test']) + if self.config.get('cpu_test', False): + options.extend(['--cpu-test']) for key, value in kw_options.items(): options.extend(['--%s' % key, value]) return options def populate_webroot(self): """Populate the production test slaves' webroots""" self.raptor_path = os.path.join( @@ -490,16 +499,18 @@ class Raptor(TestingMixin, MercurialScri # late import is required, because install is done in create_virtualenv import jsonschema expected_perfherder = 1 if self.config.get('power_test', None): expected_perfherder += 1 if self.config.get('memory_test', None): expected_perfherder += 1 + if self.config.get('cpu_test', None): + expected_perfherder += 1 if len(parser.found_perf_data) != expected_perfherder: self.critical("PERFHERDER_DATA was seen %d times, expected %d." % (len(parser.found_perf_data), expected_perfherder)) return schema_path = os.path.join(external_tools_path, 'performance-artifact-schema.json') self.info("Validating PERFHERDER_DATA against %s" % schema_path) @@ -629,16 +640,20 @@ class Raptor(TestingMixin, MercurialScri if self.power_test: src = os.path.join(self.query_abs_dirs()['abs_work_dir'], 'raptor-power.json') self._artifact_perf_data(src, dest) if self.memory_test: src = os.path.join(self.query_abs_dirs()['abs_work_dir'], 'raptor-memory.json') self._artifact_perf_data(src, dest) + if self.cpu_test: + src = os.path.join(self.query_abs_dirs()['abs_work_dir'], 'raptor-cpu.json') + self._artifact_perf_data(src, dest) + src = os.path.join(self.query_abs_dirs()['abs_work_dir'], 'screenshots.html') if os.path.exists(src): dest = os.path.join(env['MOZ_UPLOAD_DIR'], 'screenshots.html') self.info(str(dest)) self._artifact_perf_data(src, dest) class RaptorOutputParser(OutputParser):
--- a/testing/raptor/raptor/cmdline.py +++ b/testing/raptor/raptor/cmdline.py @@ -83,16 +83,18 @@ def create_parser(mach_interface=False): "The value HOST_IP will cause the value of host to be " "loaded from the environment variable HOST_IP.", default='127.0.0.1') add_arg('--power-test', dest="power_test", action="store_true", help="Use Raptor to measure power usage. Currently supported for Geckoview. " "The host ip address must be specified via the --host command line argument.") add_arg('--memory-test', dest="memory_test", action="store_true", help="Use Raptor to measure memory usage.") + add_arg('--cpu-test', dest="cpu_test", action="store_true", + help="Use Raptor to measure CPU usage. Currently supported for Android only.") add_arg('--is-release-build', dest="is_release_build", default=False, action='store_true', help="Whether the build is a release build which requires work arounds " "using MOZ_DISABLE_NONLOCAL_CONNECTIONS to support installing unsigned " "webextensions. Defaults to False.") add_arg('--geckoProfile', action="store_true", dest="gecko_profile", help=argparse.SUPPRESS) add_arg('--geckoProfileInterval', dest='gecko_profile_interval', type=float,
new file mode 100644 --- /dev/null +++ b/testing/raptor/raptor/cpu.py @@ -0,0 +1,46 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import absolute_import + + +def get_app_cpu_usage(raptor): + cpu_usage = 0 + app_name = raptor.config['binary'] + verbose = raptor.device._verbose + raptor.device._verbose = False + cpuinfo = raptor.device.shell_output("top -O %CPU -n 1").split("\n") + raptor.device._verbose = verbose + ''' + When parsing the output of the shell command, you will + get a line that looks like this: + + 17504 u0_a83 93.7 93.7 14.2 0:12.12 org.mozilla.geckoview_example + + When you split on whitespace you end up with the + name of the process at index 6 and the + amount of CPU being used at index 3 + (Remember that indexes start at 0 because COMPUTERS) + ''' + for line in cpuinfo: + data = line.split() + if len(data) == 7 and data[6] == app_name: + cpu_usage = data[3] + return cpu_usage + + +def generate_android_cpu_profile(raptor, test_name): + if not raptor.device or not raptor.config['cpu_test']: + return + + result = get_app_cpu_usage(raptor) + + cpuinfo_data = { + u'type': u'cpu', + u'test': test_name, + u'unit': u'%', + u'values': { + u'browser_cpu_usage': result + } + } + raptor.control_server.submit_supporting_data(cpuinfo_data)
--- a/testing/raptor/raptor/raptor.py +++ b/testing/raptor/raptor/raptor.py @@ -59,16 +59,17 @@ from gecko_profile import GeckoProfile from gen_test_config import gen_test_config from outputhandler import OutputHandler from manifest import get_raptor_test_list from memory import generate_android_memory_profile from mozproxy import get_playback from power import init_android_power_test, finish_android_power_test from results import RaptorResultsHandler from utils import view_gecko_profile +from cpu import generate_android_cpu_profile class SignalHandler: def __init__(self): signal.signal(signal.SIGINT, self.handle_signal) signal.signal(signal.SIGTERM, self.handle_signal) @@ -80,42 +81,41 @@ class SignalHandlerException(Exception): pass class Raptor(object): """Container class for Raptor""" def __init__(self, app, binary, run_local=False, obj_path=None, gecko_profile=False, gecko_profile_interval=None, gecko_profile_entries=None, - symbols_path=None, host=None, power_test=False, memory_test=False, - is_release_build=False, debug_mode=False, post_startup_delay=None, - interrupt_handler=None, **kwargs): + symbols_path=None, host=None, power_test=False, cpu_test=False, memory_test=False, + is_release_build=False, debug_mode=False, post_startup_delay=None, activity=None, + interrupt_handler=None, intent=None, **kwargs): # Override the magic --host HOST_IP with the value of the environment variable. if host == 'HOST_IP': host = os.environ['HOST_IP'] - self.config = { - 'app': app, - 'binary': binary, - 'platform': mozinfo.os, - 'processor': mozinfo.processor, - 'run_local': run_local, - 'obj_path': obj_path, - 'gecko_profile': gecko_profile, - 'gecko_profile_interval': gecko_profile_interval, - 'gecko_profile_entries': gecko_profile_entries, - 'symbols_path': symbols_path, - 'host': host, - 'power_test': power_test, - 'memory_test': memory_test, - 'is_release_build': is_release_build, - 'enable_control_server_wait': memory_test, - } - + self.config = {} + self.config['app'] = app + self.config['binary'] = binary + self.config['platform'] = mozinfo.os + self.config['processor'] = mozinfo.processor + self.config['run_local'] = run_local + self.config['obj_path'] = obj_path + self.config['gecko_profile'] = gecko_profile + self.config['gecko_profile_interval'] = gecko_profile_interval + self.config['gecko_profile_entries'] = gecko_profile_entries + self.config['symbols_path'] = symbols_path + self.config['host'] = host + self.config['power_test'] = power_test + self.config['cpu_test'] = cpu_test + self.config['memory_test'] = memory_test + self.config['is_release_build'] = is_release_build + self.config['enable_control_server_wait'] = memory_test self.raptor_venv = os.path.join(os.getcwd(), 'raptor-venv') self.log = get_default_logger(component='raptor-main') self.control_server = None self.playback = None self.benchmark = None self.benchmark_port = 0 self.gecko_profiler = None self.post_startup_delay = post_startup_delay @@ -337,16 +337,17 @@ class Raptor(object): # and the time an exception is propagated through the framework timeout += (int(self.post_startup_delay / 1000) + 10) # if geckoProfile enabled, give browser more time for profiling if self.config['gecko_profile'] is True: timeout += 5 * 60 elapsed_time = 0 + while not self.control_server._finished: if self.config['enable_control_server_wait']: response = self.control_server_wait_get() if response == 'webext_status/__raptor_shutdownBrowser': if self.config['memory_test']: generate_android_memory_profile(self, test['name']) self.control_server_wait_continue() time.sleep(1) @@ -583,16 +584,25 @@ class RaptorDesktopFirefox(RaptorDesktop def set_browser_test_prefs(self, raw_prefs): # add test specific preferences self.log.info("setting test-specific Firefox preferences") self.profile.set_preferences(json.loads(raw_prefs)) class RaptorDesktopChrome(RaptorDesktop): + def __init__(self, app, binary, run_local=False, obj_path=None, + gecko_profile=False, gecko_profile_interval=None, gecko_profile_entries=None, + symbols_path=None, host=None, power_test=False, cpu_test=False, memory_test=False, + is_release_build=False, debug_mode=False, post_startup_delay=None, + activity=None, intent=None): + RaptorDesktop.__init__(self, app, binary, run_local, obj_path, gecko_profile, + gecko_profile_interval, gecko_profile_entries, symbols_path, + host, power_test, cpu_test, memory_test, is_release_build, + debug_mode, post_startup_delay) def setup_chrome_desktop_for_playback(self): # if running a pageload test on google chrome, add the cmd line options # to turn on the proxy and ignore security certificate errors # if using host localhost, 127.0.0.1. chrome_args = [ '--proxy-server=127.0.0.1:8080', '--proxy-bypass-list=localhost;127.0.0.1', @@ -614,18 +624,25 @@ class RaptorDesktopChrome(RaptorDesktop) if test.get('playback') is not None: self.setup_chrome_desktop_for_playback() self.start_runner_proc() class RaptorAndroid(Raptor): - def __init__(self, app, binary, activity=None, intent=None, **kwargs): - super(RaptorAndroid, self).__init__(app, binary, **kwargs) + def __init__(self, app, binary, run_local=False, obj_path=None, + gecko_profile=False, gecko_profile_interval=None, gecko_profile_entries=None, + symbols_path=None, host=None, power_test=False, cpu_test=False, memory_test=False, + is_release_build=False, debug_mode=False, post_startup_delay=None, activity=None, + intent=None, interrupt_handler=None): + Raptor.__init__(self, app, binary, run_local, obj_path, gecko_profile, + gecko_profile_interval, gecko_profile_entries, symbols_path, host, + power_test, cpu_test, memory_test, is_release_build, debug_mode, + post_startup_delay) # on android, when creating the browser profile, we want to use a 'firefox' type profile self.profile_class = "firefox" self.config.update({ 'activity': activity, 'intent': intent, }) @@ -889,16 +906,18 @@ class RaptorAndroid(Raptor): url='about:blank', e10s=True, fail_if_running=False) except Exception as e: self.log.error("Exception launching %s" % self.config['binary']) self.log.error("Exception: %s %s" % (type(e).__name__, str(e))) if self.config['power_test']: finish_android_power_test(self, test_name) + if self.config['cpu_test']: + generate_android_cpu_profile(self, test_name) raise # give our control server the device and app info self.control_server.device = self.device self.control_server.app_name = self.config['binary'] def copy_cert_db(self, source_dir, target_dir): # copy browser cert db (that was previously created via certutil) from source to target @@ -922,17 +941,18 @@ class RaptorAndroid(Raptor): self.run_test_warm(test, timeout) except SignalHandlerException: self.device.stop_application(self.config['binary']) finally: if self.config['power_test']: finish_android_power_test(self, test['name']) - + if self.config['cpu_test']: + generate_android_cpu_profile(self, test['name']) self.run_test_teardown() def run_test_cold(self, test, timeout=None): ''' Run the Raptor test but restart the entire browser app between page-cycles. Note: For page-load tests, playback will only be started once - at the beginning of all browser cycles, and then stopped after all cycles are finished. The proxy is set via prefs @@ -955,16 +975,19 @@ class RaptorAndroid(Raptor): The default will be to run in warm mode; unless 'cold = true' is set in the test INI. ''' self.log.info("test %s is running in cold mode; browser WILL be restarted between " "page cycles" % test['name']) if self.config['power_test']: init_android_power_test(self) + if self.config['cpu_test']: + generate_android_cpu_profile(self, test['name']) + for test['browser_cycle'] in range(1, test['expected_browser_cycles'] + 1): self.log.info("begin browser cycle %d of %d for test %s" % (test['browser_cycle'], test['expected_browser_cycles'], test['name'])) self.run_test_setup(test) if test['browser_cycle'] == 1: @@ -1024,16 +1047,19 @@ class RaptorAndroid(Raptor): break def run_test_warm(self, test, timeout=None): self.log.info("test %s is running in warm mode; browser will NOT be restarted between " "page cycles" % test['name']) if self.config['power_test']: init_android_power_test(self) + if self.config['cpu_test']: + generate_android_cpu_profile(self, test['name']) + self.run_test_setup(test) self.create_raptor_sdcard_folder() if test.get('playback') is not None: self.start_playback(test) if self.config['host'] not in ('localhost', '127.0.0.1'): self.delete_proxy_settings_from_profile() @@ -1125,16 +1151,17 @@ def main(args=sys.argv[1:]): run_local=args.run_local, obj_path=args.obj_path, gecko_profile=args.gecko_profile, gecko_profile_interval=args.gecko_profile_interval, gecko_profile_entries=args.gecko_profile_entries, symbols_path=args.symbols_path, host=args.host, power_test=args.power_test, + cpu_test=args.cpu_test, memory_test=args.memory_test, is_release_build=args.is_release_build, debug_mode=args.debug_mode, post_startup_delay=args.post_startup_delay, activity=args.activity, intent=args.intent, interrupt_handler=SignalHandler(), )
new file mode 100644 --- /dev/null +++ b/testing/raptor/test/files/top-info.txt @@ -0,0 +1,41 @@ +Tasks: 142 total, 1 running, 140 sleeping, 0 stopped, 1 zombie +Mem: 1548824k total, 1234756k used, 314068k free, 37080k buffers +Swap: 0k total, 0k used, 0k free, 552360k cached +200%cpu 122%user 9%nice 50%sys 13%idle 0%iow 0%irq 6%sirq 0%host + PID USER [%CPU]%CPU %MEM TIME+ ARGS +17504 u0_a83 93.7 93.7 14.2 0:12.12 org.mozilla.geckoview_example +17529 u0_a83 43.7 43.7 19.3 0:11.80 org.mozilla.geckoview_example:tab + 7030 u0_a54 28.1 28.1 5.6 0:05.47 com.google.android.tts + 1598 root 9.3 9.3 0.1 0:13.73 dhcpclient -i eth0 + 1667 system 6.2 6.2 9.6 16:10.78 system_server + 1400 system 6.2 6.2 0.2 8:15.20 android.hardware.sensors@1.0-service +17729 shell 3.1 3.1 0.1 0:00.02 top -O %CPU -n 1 + 1411 system 3.1 3.1 0.7 23:06.11 surfaceflinger +17497 shell 0.0 0.0 0.1 0:00.01 sh - +17321 root 0.0 0.0 0.0 0:00.13 [kworker/0:1] +17320 root 0.0 0.0 0.0 0:00.15 [kworker/u4:1] +17306 root 0.0 0.0 0.0 0:00.21 [kworker/u5:1] +16545 root 0.0 0.0 0.0 0:00.17 [kworker/0:0] +16543 root 0.0 0.0 0.0 0:00.15 [kworker/u4:2] +16411 root 0.0 0.0 0.0 0:00.41 [kworker/u5:2] +15827 root 0.0 0.0 0.0 0:00.04 [kworker/1:2] +14998 root 0.0 0.0 0.0 0:00.03 [kworker/1:1] +14996 root 0.0 0.0 0.0 0:00.38 [kworker/0:2] +14790 root 0.0 0.0 0.0 0:01.04 [kworker/u5:0] +14167 root 0.0 0.0 0.0 0:01.32 [kworker/u4:0] +11922 u0_a50 0.0 0.0 6.9 0:00.80 com.google.android.apps.docs +11906 u0_a67 0.0 0.0 5.0 0:00.25 com.google.android.apps.photos +11887 u0_a11 0.0 0.0 4.3 0:00.25 com.android.documentsui +11864 u0_a6 0.0 0.0 3.3 0:00.19 com.android.defcontainer +10866 u0_a15 0.0 0.0 3.3 0:00.04 com.google.android.partnersetup + 8956 u0_a1 0.0 0.0 3.7 0:00.40 com.android.providers.calendar + 8070 u0_a10 0.0 0.0 6.7 0:01.21 com.google.android.gms.unstable + 6638 u0_a10 0.0 0.0 7.4 0:12.89 com.google.android.gms + 2291 u0_a30 0.0 0.0 9.0 5:45.93 com.google.android.googlequicksearchbox:search + 2230 u0_a10 0.0 0.0 3.9 0:02.00 com.google.process.gapps + 2213 u0_a22 0.0 0.0 7.2 4:12.95 com.google.android.apps.nexuslauncher + 2195 u0_a30 0.0 0.0 4.1 0:00.37 com.google.android.googlequicksearchbox:interactor + 2163 u0_a10 0.0 0.0 8.2 1:49.32 com.google.android.gms.persistent + 1882 radio 0.0 0.0 5.1 0:53.61 com.android.phone + 1875 wifi 0.0 0.0 0.4 0:02.25 wpa_supplicant -Dnl80211 -iwlan0 -c/vendor/etc/wifi/wpa_supplicant.conf -g@android:wpa_wla+ + 1828 webview_zyg+ 0.0 0.0 3.0 0:00.45 webview_zygote32 \ No newline at end of file
--- a/testing/raptor/test/python.ini +++ b/testing/raptor/test/python.ini @@ -4,8 +4,9 @@ skip-if = python == 3 [test_cmdline.py] [test_manifest.py] [test_control_server.py] [test_utils.py] [test_playback.py] [test_print_tests.py] [test_raptor.py] +[test_cpu.py]
--- a/testing/raptor/test/test_cmdline.py +++ b/testing/raptor/test/test_cmdline.py @@ -12,16 +12,17 @@ from raptor.cmdline import verify_option def test_verify_options(filedir): args = Namespace(app='firefox', binary='invalid/path', gecko_profile='False', page_cycles=1, page_timeout=60000, debug='True', power_test=False, + cpu_test=False, memory_test=False) parser = ArgumentParser() with pytest.raises(SystemExit): verify_options(parser, args) args.binary = os.path.join(filedir, 'fake_binary.exe') verify_options(parser, args) # assert no exception @@ -29,49 +30,65 @@ def test_verify_options(filedir): args = Namespace(app='geckoview', binary='org.mozilla.geckoview_example', activity='GeckoViewActivity', intent='android.intent.action.MAIN', gecko_profile='False', is_release_build=False, host='sophie', power_test=False, + cpu_test=False, memory_test=False) verify_options(parser, args) # assert no exception args = Namespace(app='refbrow', binary='org.mozilla.reference.browser', activity='BrowserTestActivity', intent='android.intent.action.MAIN', gecko_profile='False', is_release_build=False, host='sophie', power_test=False, + cpu_test=False, memory_test=False) verify_options(parser, args) # assert no exception args = Namespace(app='fenix', binary='org.mozilla.fenix.browser', activity='BrowserTestActivity', intent='android.intent.action.VIEW', gecko_profile='False', is_release_build=False, host='sophie', power_test=False, + cpu_test=False, + memory_test=False) + verify_options(parser, args) # assert no exception + + args = Namespace(app='geckoview', + binary='org.mozilla.geckoview_example', + activity='GeckoViewActivity', + intent='android.intent.action.MAIN', + gecko_profile='False', + is_release_build=False, + host='sophie', + power_test=False, + cpu_test=True, memory_test=False) verify_options(parser, args) # assert no exception args = Namespace(app='refbrow', binary='org.mozilla.reference.browser', activity=None, intent='android.intent.action.MAIN', gecko_profile='False', is_release_build=False, host='sophie', power_test=False, + cpu_test=False, memory_test=False) parser = ArgumentParser() verify_options(parser, args) # also will work as uses default activity if __name__ == '__main__': mozunit.main()
new file mode 100644 --- /dev/null +++ b/testing/raptor/test/test_cpu.py @@ -0,0 +1,98 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import absolute_import, unicode_literals + +import mozunit +import os +import mock +import sys + +from raptor import cpu +from raptor.raptor import Raptor + +# need this so raptor imports work both from /raptor and via mach +here = os.path.abspath(os.path.dirname(__file__)) +if os.environ.get('SCRIPTSPATH', None) is not None: + # in production it is env SCRIPTS_PATH + mozharness_dir = os.environ['SCRIPTSPATH'] +else: + # locally it's in source tree + mozharness_dir = os.path.join(here, '../../mozharness') +sys.path.insert(0, mozharness_dir) + + +def test_no_device(): + raptor = Raptor('geckoview', 'org.mozilla.org.mozilla.geckoview_example', cpu_test=True) + raptor.device = None + resp = cpu.generate_android_cpu_profile(raptor, 'no_control_server_device') + + assert resp is None + + +def test_usage_with_invalid_data_returns_zero(): + with mock.patch('mozdevice.adb.ADBDevice') as device: + with mock.patch('raptor.raptor.RaptorControlServer') as control_server: + # Create a device that returns invalid data + device.shell_output.return_value = 'geckoview' + device._verbose = True + + # Create a control server + control_server.cpu_test = True + control_server.device = device + raptor = Raptor('geckoview', 'org.mozilla.geckoview_example', cpu_test=True) + raptor.config['cpu_test'] = True + raptor.control_server = control_server + raptor.device = device + + # Verify the call to submit data was made + cpuinfo_data = { + 'type': 'cpu', + 'test': 'usage_with_invalid_data_returns_zero', + 'unit': '%', + 'values': { + 'browser_cpu_usage': float(0) + } + } + cpu.generate_android_cpu_profile( + raptor, + "usage_with_invalid_data_returns_zero") + control_server.submit_supporting_data.assert_called_once_with(cpuinfo_data) + + +def test_usage_with_output(): + with mock.patch('mozdevice.adb.ADBDevice') as device: + with mock.patch('raptor.raptor.RaptorControlServer') as control_server: + # Override the shell output with sample CPU usage details + filepath = os.path.abspath(os.path.dirname(__file__)) + '/files/' + f = open(filepath + 'top-info.txt', 'r') + device.shell_output.return_value = f.read() + device._verbose = True + + # Create a control server + control_server.cpu_test = True + control_server.test_name = 'cpuunittest' + control_server.device = device + control_server.app_name = 'org.mozilla.geckoview_example' + raptor = Raptor('geckoview', 'org.mozilla.geckoview_example', cpu_test=True) + raptor.device = device + raptor.config['cpu_test'] = True + raptor.control_server = control_server + + # Verify the response contains our expected CPU % of 93.7 + cpuinfo_data = { + u'type': u'cpu', + u'test': u'usage_with_integer_cpu_info_output', + u'unit': u'%', + u'values': { + u'browser_cpu_usage': '93.7' + } + } + cpu.generate_android_cpu_profile( + raptor, + "usage_with_integer_cpu_info_output") + control_server.submit_supporting_data.assert_called_once_with(cpuinfo_data) + + +if __name__ == '__main__': + mozunit.main()