diff options
Diffstat (limited to 'client/site_tests/power_Consumption/power_Consumption.py')
-rw-r--r-- | client/site_tests/power_Consumption/power_Consumption.py | 553 |
1 files changed, 0 insertions, 553 deletions
diff --git a/client/site_tests/power_Consumption/power_Consumption.py b/client/site_tests/power_Consumption/power_Consumption.py deleted file mode 100644 index 9249a884a6..0000000000 --- a/client/site_tests/power_Consumption/power_Consumption.py +++ /dev/null @@ -1,553 +0,0 @@ -# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import logging -import os -import time -import urllib - -from autotest_lib.client.bin import test, utils -from autotest_lib.client.common_lib import error -from autotest_lib.client.common_lib.cros import chrome -from autotest_lib.client.cros import backchannel -from autotest_lib.client.cros import httpd -from autotest_lib.client.cros import service_stopper -from autotest_lib.client.cros.graphics import graphics_utils -from autotest_lib.client.cros.networking import wifi_proxy -from autotest_lib.client.cros.power import power_rapl, power_status, power_utils - - -class power_Consumption(test.test): - """Measure power consumption for different types of loads. - - This test runs a series of different tasks like media playback, flash - animation, large file download etc. It measures and reports power - consumptions during each of those tasks. - """ - - version = 2 - - - def initialize(self, ac_ok=False): - """Initialize test. - - Args: - ac_ok: boolean to allow running on AC - """ - # Objects that need to be taken care of in cleanup() are initialized - # here to None. Otherwise we run the risk of AttributeError raised in - # cleanup() masking a real error that caused the test to fail during - # initialize() before those variables were assigned. - self._backlight = None - self._tmp_keyvals = {} - - self._services = service_stopper.ServiceStopper( - service_stopper.ServiceStopper.POWER_DRAW_SERVICES) - self._services.stop_services() - - - # Time to exclude from calculation after firing a task [seconds] - self._stabilization_seconds = 5 - self._power_status = power_status.get_status() - self._tmp_keyvals['b_on_ac'] = self._power_status.on_ac() - - if not ac_ok: - # Verify that we are running on battery and the battery is - # sufficiently charged - self._power_status.assert_battery_state(30) - - # Local data and web server settings. Tarballs with traditional names - # like *.tgz don't get copied to the image by ebuilds (see - # AUTOTEST_FILE_MASK in autotest-chrome ebuild). - self._static_sub_dir = 'static_sites' - utils.extract_tarball_to_dir( - 'static_sites.tgz.keep', - os.path.join(self.bindir, self._static_sub_dir)) - self._media_dir = '/home/chronos/user/Downloads/' - self._httpd_port = 8000 - self._url_base = 'http://localhost:%s/' % self._httpd_port - self._test_server = httpd.HTTPListener(self._httpd_port, - docroot=self.bindir) - - # initialize various interesting power related stats - self._statomatic = power_status.StatoMatic() - self._test_server.run() - - - logging.info('initialize() finished') - - - def _download_test_data(self): - """Download audio and video files. - - This is also used as payload for download test. - - Note, can reach payload via browser at - https://console.developers.google.com/storage/chromeos-test-public/big_buck_bunny - Start with README - """ - - repo = 'http://commondatastorage.googleapis.com/chromeos-test-public/' - file_list = [repo + 'big_buck_bunny/big_buck_bunny_trailer_400p.mp4', ] - if not self.short: - file_list += [ - repo + 'big_buck_bunny/big_buck_bunny_trailer_400p.ogg', - repo + 'big_buck_bunny/big_buck_bunny_trailer_400p.vp8.webm', - repo + 'big_buck_bunny/big_buck_bunny_trailer_400p.vp9.webm', - repo + 'big_buck_bunny/big_buck_bunny_trailer_720p.mp4', - repo + 'big_buck_bunny/big_buck_bunny_trailer_720p.ogg', - repo + 'big_buck_bunny/big_buck_bunny_trailer_720p.vp8.webm', - repo + 'big_buck_bunny/big_buck_bunny_trailer_720p.vp9.webm', - repo + 'big_buck_bunny/big_buck_bunny_trailer_1080p.mp4', - repo + 'big_buck_bunny/big_buck_bunny_trailer_1080p.ogg', - repo + 'big_buck_bunny/big_buck_bunny_trailer_1080p.vp8.webm', - repo + 'big_buck_bunny/big_buck_bunny_trailer_1080p.vp9.webm', - repo + 'wikimedia/Greensleeves.ogg', - ] - - for url in file_list: - logging.info('Downloading %s', url) - utils.unmap_url('', url, self._media_dir) - - - def _toggle_fullscreen(self): - """Toggle full screen mode.""" - # Note: full screen mode toggled with F11 is different from clicking the - # full screen icon on video player controls. This needs improvement. - # Bug: http://crbug.com/248939 - graphics_utils.screen_toggle_fullscreen() - - - # Below are a series of generic sub-test runners. They run a given task - # and record the task name and start-end timestamps for future computation - # of power consumption during the task. - def _run_func(self, name, func, repeat=1, save_checkpoint=True): - """Run a given python function as a sub-test.""" - start_time = time.time() + self._stabilization_seconds - for _ in xrange(repeat): - ret = func() - if save_checkpoint: - self._plog.checkpoint(name, start_time) - return ret - - - def _run_sleep(self, name, seconds=60): - """Just sleep and record it as a named sub-test""" - start_time = time.time() + self._stabilization_seconds - time.sleep(seconds) - self._plog.checkpoint(name, start_time) - - - def _run_cmd(self, name, cmd, repeat=1): - """Run command in a shell as a sub-test""" - start_time = time.time() + self._stabilization_seconds - for _ in xrange(repeat): - logging.info('Executing command: %s', cmd) - exit_status = utils.system(cmd, ignore_status=True) - if exit_status != 0: - logging.error('run_cmd: the following command terminated with' - 'a non zero exit status: %s', cmd) - self._plog.checkpoint(name, start_time) - return exit_status - - - def _run_until(self, name, predicate, timeout=60): - """Probe the |predicate| function and wait until it returns true. - Record the waiting time as a sub-test - """ - start_time = time.time() + self._stabilization_seconds - utils.poll_for_condition(predicate, timeout=timeout) - self._plog.checkpoint(name, start_time) - - - def _run_url(self, name, url, duration): - """Navigate to URL, sleep for some time and record it as a sub-test.""" - logging.info('Navigating to %s', url) - self._tab.Activate() - self._tab.Navigate(url) - self._run_sleep(name, duration) - tab_title = self._tab.EvaluateJavaScript('document.title') - logging.info('Sub-test name: %s Tab title: %s.', name, tab_title) - - - def _run_url_bg(self, name, url, duration): - """Run a web site in background tab. - - Navigate to the given URL, open an empty tab to put the one with the - URL in background, then sleep and record it as a sub-test. - - Args: - name: sub-test name. - url: url to open in background tab. - duration: number of seconds to sleep while taking measurements. - """ - bg_tab = self._tab - bg_tab.Navigate(url) - # Let it load and settle - time.sleep(self._stabilization_seconds / 2.) - tab_title = bg_tab.EvaluateJavaScript('document.title') - logging.info('App name: %s Tab title: %s.', name, tab_title) - # Open a new empty tab to cover the one with test payload. - fg_tab = self._browser.tabs.New() - fg_tab.Activate() - self._run_sleep(name, duration) - fg_tab.Close() - bg_tab.Activate() - - - def _run_group_download(self): - """Download over ethernet. Using video test data as payload.""" - - # For short run, the payload is too small to take measurement - self._run_func('download_eth', - self._download_test_data , - repeat=self._repeats, - save_checkpoint=not(self.short)) - - - def _run_group_webpages(self): - """Runs a series of web pages as sub-tests.""" - data_url = self._url_base + self._static_sub_dir + '/' - - # URLs to be only tested in foreground tab. - # Can't use about:blank here - crbug.com/248945 - # but chrome://version is just as good for our needs. - urls = [('ChromeVer', 'chrome://version/')] - # URLs to be tested in both, background and foreground modes. - bg_urls = [] - - more_urls = [('BallsDHTML', - data_url + 'balls/DHTMLBalls/dhtml.htm'), - ('BallsFlex', - data_url + 'balls/FlexBalls/flexballs.html'), - ] - - if self.short: - urls += more_urls - else: - bg_urls += more_urls - bg_urls += [('Parapluesch', - 'http://www.parapluesch.de/whiskystore/test.htm'), - ('PosterCircle', - 'http://www.webkit.org' - '/blog-files/3d-transforms/poster-circle.html'), ] - - for name, url in urls + bg_urls: - self._run_url(name, url, duration=self._duration_secs) - - for name, url in bg_urls: - self._run_url_bg('bg_' + name, url, duration=self._duration_secs) - - - def _run_group_speedometer(self): - """Run the Speedometer benchmark suite as a sub-test. - - Fire it up and wait until it displays "Score". - """ - - # TODO: check in a local copy of the test if we can get permission if - # the network causes problems. - url = 'http://browserbench.org/Speedometer/' - start_js = 'startTest()' - score_js = "document.getElementById('result-number').innerText" - tab = self._tab - - def speedometer_func(): - """To be passed as the callable to self._run_func()""" - tab.Navigate(url) - tab.WaitForDocumentReadyStateToBeComplete() - tab.EvaluateJavaScript(start_js) - # Speedometer test should be done in less than 15 minutes (actual - # runs are closer to 5). - is_done = lambda: tab.EvaluateJavaScript(score_js) != "" - time.sleep(self._stabilization_seconds) - utils.poll_for_condition(is_done, timeout=900, - desc='Speedometer score found') - - self._run_func('Speedometer', speedometer_func, repeat=self._repeats) - - # Write speedometer score from the last run to log - score = tab.EvaluateJavaScript(score_js) - logging.info('Speedometer Score: %s', score) - - - def _run_group_video(self): - """Run video and audio playback in the browser.""" - - # Note: for perf keyvals, key names are defined as VARCHAR(30) in the - # results DB. Chars above 30 are truncated when saved to DB. - urls = [('vid400p_h264', 'big_buck_bunny_trailer_400p.mp4'), ] - fullscreen_urls = [] - bg_urls = [] - - if not self.short: - urls += [ - ('vid400p_ogg', 'big_buck_bunny_trailer_400p.ogg'), - ('vid400p_vp8', 'big_buck_bunny_trailer_400p.vp8.webm'), - ('vid400p_vp9', 'big_buck_bunny_trailer_400p.vp9.webm'), - ('vid720_h264', 'big_buck_bunny_trailer_720p.mp4'), - ('vid720_ogg', 'big_buck_bunny_trailer_720p.ogg'), - ('vid720_vp8', 'big_buck_bunny_trailer_720p.vp8.webm'), - ('vid720_vp9', 'big_buck_bunny_trailer_720p.vp9.webm'), - ('vid1080_h264', 'big_buck_bunny_trailer_1080p.mp4'), - ('vid1080_ogg', 'big_buck_bunny_trailer_1080p.ogg'), - ('vid1080_vp8', 'big_buck_bunny_trailer_1080p.vp8.webm'), - ('vid1080_vp9', 'big_buck_bunny_trailer_1080p.vp9.webm'), - ('audio', 'Greensleeves.ogg'), - ] - - fullscreen_urls += [ - ('vid720_h264_fs', 'big_buck_bunny_trailer_720p.mp4'), - ('vid720_vp8_fs', 'big_buck_bunny_trailer_720p.vp8.webm'), - ('vid720_vp9_fs', 'big_buck_bunny_trailer_720p.vp9.webm'), - ('vid1080_h264_fs', 'big_buck_bunny_trailer_1080p.mp4'), - ('vid1080_vp8_fs', 'big_buck_bunny_trailer_1080p.vp8.webm'), - ('vid1080_vp9_fs', 'big_buck_bunny_trailer_1080p.vp9.webm'), - ] - - bg_urls += [ - ('bg_vid400p', 'big_buck_bunny_trailer_400p.vp8.webm'), - ] - - # The video files are run from a file:// url. In order to work properly - # from an http:// url, some careful web server configuration is needed - def full_url(filename): - """Create a file:// url for the media file and verify it exists. - - @param filename: string - """ - p = os.path.join(self._media_dir, filename) - if not os.path.isfile(p): - raise error.TestError('Media file %s is missing.', p) - return 'file://' + p - - js_loop_enable = """ve = document.getElementsByTagName('video')[0]; - ve.loop = true; - ve.play(); - """ - - for name, url in urls: - logging.info('Playing video %s', url) - self._tab.Navigate(full_url(url)) - self._tab.ExecuteJavaScript(js_loop_enable) - self._run_sleep(name, self._duration_secs) - - for name, url in fullscreen_urls: - self._toggle_fullscreen() - self._tab.Navigate(full_url(url)) - self._tab.ExecuteJavaScript(js_loop_enable) - self._run_sleep(name, self._duration_secs) - self._toggle_fullscreen() - - for name, url in bg_urls: - logging.info('Playing video in background tab %s', url) - self._tab.Navigate(full_url(url)) - self._tab.ExecuteJavaScript(js_loop_enable) - fg_tab = self._browser.tabs.New() - self._run_sleep(name, self._duration_secs) - fg_tab.Close() - self._tab.Activate() - - - def _run_group_sound(self): - """Run non-UI sound test using 'speaker-test'.""" - # For some reason speaker-test won't work on CrOS without a reasonable - # buffer size specified with -b. - # http://crbug.com/248955 - cmd = 'speaker-test -l %s -t sine -c 2 -b 16384' % (self._repeats * 6) - self._run_cmd('speaker_test', cmd) - - - def _run_group_lowlevel(self): - """Low level system stuff""" - mb = min(1024, 32 * self._repeats) - self._run_cmd('memtester', '/usr/local/sbin/memtester %s 1' % mb) - - # one rep of dd takes about 15 seconds - root_dev = utils.get_root_partition() - cmd = 'dd if=%s of=/dev/null' % root_dev - self._run_cmd('dd', cmd, repeat=2 * self._repeats) - - - def _run_group_backchannel(self): - """WiFi sub-tests.""" - - shill = wifi_proxy.WifiProxy() - for _ in xrange(3): - succeeded, _, _, _, _ = shill.connect_to_wifi_network( - ssid='GoogleGuest', - security='none', - security_parameters={}, - save_credentials=False) - if succeeded: - break - - if not succeeded: - logging.error("Could not connect to WiFi") - return - - logging.info('Starting Backchannel') - with backchannel.Backchannel(): - # Wifi needs some time to recover after backchanel is activated - # TODO (kamrik) remove this sleep, once backchannel handles this - time.sleep(15) - - cmd = 'ping -c %s www.google.com' % (self._duration_secs) - self._run_cmd('ping_wifi', cmd) - - # This URL must be visible from WiFi network used for test - big_file_url = ('http://googleappengine.googlecode.com' - '/files/GoogleAppEngine-1.6.2.msi') - cmd = 'curl %s > /dev/null' % big_file_url - self._run_cmd('download_wifi', cmd, repeat=self._repeats) - - - def _run_group_backlight(self): - """Vary backlight brightness and record power at each setting.""" - for i in [100, 50, 0]: - self._backlight.set_percent(i) - start_time = time.time() + self._stabilization_seconds - time.sleep(30 * self._repeats) - self._plog.checkpoint('backlight_%03d' % i, start_time) - self._backlight.set_default() - - - def _web_echo(self, msg): - """ Displays a message in the browser.""" - url = self._url_base + 'echo.html?' - url += urllib.quote(msg) - self._tab.Navigate(url) - - - def _run_test_groups(self, groups): - """ Run all the test groups. - - Args: - groups: list of sub-test groups to run. Each sub-test group refers - to a _run_group_...() function. - """ - - for group in groups: - logging.info('Running group %s', group) - # The _web_echo here is important for some tests (esp. non UI) - # it gets the previous web page replaced with an almost empty one. - self._tab.Activate() - self._web_echo('Running test %s' % group) - test_func = getattr(self, '_run_group_%s' % group) - test_func() - - - def run_once(self, short=False, test_groups=None, reps=1): - # Some sub-tests have duration specified directly, _base_secs * reps - # is used in this case. Others complete whenever the underlying task - # completes, those are manually tuned to be roughly around - # reps * 30 seconds. Don't change _base_secs unless you also - # change the manual tuning in sub-tests - self._base_secs = 30 - self._repeats = reps - self._duration_secs = self._base_secs * reps - - # Lists of default tests to run - UI_TESTS = ['backlight', 'download', 'webpages', 'video', 'speedometer'] - NONUI_TESTS = ['backchannel', 'sound', 'lowlevel'] - DEFAULT_TESTS = UI_TESTS + NONUI_TESTS - DEFAULT_SHORT_TESTS = ['download', 'webpages', 'video'] - - self.short = short - if test_groups is None: - if self.short: - test_groups = DEFAULT_SHORT_TESTS - else: - test_groups = DEFAULT_TESTS - logging.info('Test groups to run: %s', ', '.join(test_groups)) - - self._backlight = power_utils.Backlight() - self._backlight.set_default() - - measure = [] - if not self._power_status.on_ac(): - measure += \ - [power_status.SystemPower(self._power_status.battery_path)] - if power_utils.has_powercap_support(): - measure += power_rapl.create_powercap() - elif power_utils.has_rapl_support(): - measure += power_rapl.create_rapl() - self._plog = power_status.PowerLogger(measure) - self._plog.start() - - # Log in. - with chrome.Chrome() as cr: - self._browser = cr.browser - graphics_utils.screen_disable_energy_saving() - # Most of the tests will be running in this tab. - self._tab = cr.browser.tabs[0] - - # Verify that we have a functioning browser and local web server. - self._tab.Activate() - self._web_echo("Sanity_test") - self._tab.WaitForDocumentReadyStateToBeComplete() - - # Video test must have the data from download test - if ('video' in test_groups): - iv = test_groups.index('video') - if 'download' not in test_groups[:iv]: - msg = '"download" test must run before "video".' - raise error.TestError(msg) - - # Run all the test groups - self._run_test_groups(test_groups) - - # Wrap up - keyvals = self._plog.calc() - keyvals.update(self._tmp_keyvals) - keyvals.update(self._statomatic.publish()) - - # check AC status is still the same as init - self._power_status.refresh() - on_ac = self._power_status.on_ac() - if keyvals['b_on_ac'] != on_ac: - raise error.TestError('on AC changed between start & stop of test') - - if not on_ac: - whrs = self._power_status.battery.energy_full_design - logging.info("energy_full_design = %0.3f Wh", whrs) - - # Calculate expected battery life time with ChromeVer power draw - idle_name = 'ChromeVer_system_pwr_avg' - if idle_name in keyvals: - hours_life = whrs / keyvals[idle_name] - keyvals['hours_battery_ChromeVer'] = hours_life - - # Calculate a weighted power draw and battery life time. The weights - # are intended to represent "typical" usage. Some video, some Flash - # ... and most of the time idle. see, - # http://www.chromium.org/chromium-os/testing/power-testing - weights = {'vid400p_h264_system_pwr_avg':0.1, - 'BallsFlex_system_pwr_avg':0.1, - 'BallsDHTML_system_pwr_avg':0.3, - } - weights[idle_name] = 1 - sum(weights.values()) - - if set(weights).issubset(set(keyvals)): - p = sum(w * keyvals[k] for (k, w) in weights.items()) - keyvals['w_Weighted_system_pwr_avg'] = p - keyvals['hours_battery_Weighted'] = whrs / p - - self.write_perf_keyval(keyvals) - self._plog.save_results(self.resultsdir) - - - def cleanup(self): - # cleanup() is run by common_lib/test.py - try: - self._test_server.stop() - except AttributeError: - logging.debug('test_server could not be stopped in cleanup') - - if self._backlight: - self._backlight.restore() - if self._services: - self._services.restore_services() - - super(power_Consumption, self).cleanup() |