Home | History | Annotate | Download | only in telemetry_AFDOGenerateClient
      1 # Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """
      6 Run a pre-defined set of pages on the DUT for Chrome profile collection.
      7 
      8 The purpose of this test is to exercise chrome with a meaningful set
      9 of pages while a profile of Chrome is captured. It also aims at using
     10 the minimum set of functionality from Telemetry since Telemetry is not
     11 very stable on ChromeOS at this point.
     12 
     13 This test is designed to be called from the telemetry_AFDOGenerate
     14 server test. The server test will start the "perf" profiling tool on
     15 the DUT before starting this test. It will also capture the chrome
     16 profile and upload it to Google Storage to be used for an optimized
     17 build of Chrome.
     18 """
     19 
     20 import logging
     21 import os
     22 import sys
     23 import time
     24 import traceback
     25 
     26 from autotest_lib.client.common_lib import error
     27 from autotest_lib.client.common_lib.cros import chrome
     28 from autotest_lib.client.bin import test
     29 from autotest_lib.client.cros import httpd
     30 
     31 # List of page cycler pages to use for Chrome profiling
     32 PAGE_CYCLER_BENCHMARKS = [
     33         'alexa_us',
     34         'bloat',
     35         'dhtml',
     36         'dom',
     37         'intl1',
     38         'intl2',
     39         'morejs',
     40         'morejsnp',
     41         'moz',
     42         'moz2' ]
     43 
     44 HTTP_PORT = 8000
     45 FILE_URL_PREFIX = 'http://localhost:%d/test_src/' % HTTP_PORT
     46 
     47 class telemetry_AFDOGenerateClient(test.test):
     48     """
     49     Run a set of pre-defined set of pages to exercise Chrome so that
     50     we can capture a Chrome profile.
     51     """
     52     version = 1
     53 
     54 
     55     def initialize(self):
     56         """Setup required DEPS and start the http listener."""
     57         dep = 'page_cycler_dep'
     58         dep_dir = os.path.join(self.autodir, 'deps', dep)
     59         self.job.install_pkg(dep, 'dep', dep_dir)
     60 
     61         try:
     62             self.listener = httpd.HTTPListener(HTTP_PORT, docroot=dep_dir)
     63             self.listener.run()
     64         except Exception as err:
     65             logging.info('Timeout starting HTTP listener')
     66             raise error.TestFailRetry(err)
     67 
     68 
     69     def cleanup(self):
     70         """Stop the active http listener."""
     71         self.listener.stop()
     72 
     73 
     74     def run_once(self):
     75         """Display predetermined set of pages so that we can profile Chrome."""
     76         with chrome.Chrome() as cr:
     77             for benchmark in PAGE_CYCLER_BENCHMARKS:
     78                 self._try_page_cycler(cr, benchmark)
     79 
     80     def _try_page_cycler(self, cr, benchmark):
     81         """Try executing a page cycler and recover if browser dies.
     82 
     83         Navigates to the specified page_cycler, checks if the browser
     84         died while executing it and waits until browser recovers.
     85 
     86         @param cr: instance of chrome.Chrome class to control chrome.
     87         @param benchmark: page_cycler page to display.
     88         """
     89         if cr.did_browser_crash(
     90                 lambda: self._navigate_page_cycler(cr, benchmark)):
     91             logging.info('Browser died while navigating %s', benchmark)
     92             logging.info('Trying to continue...')
     93             cr.wait_for_browser_to_come_up()
     94 
     95 
     96     def _navigate_page_cycler(self, cr, benchmark):
     97         """Navigate to a specific page_cycler page.
     98 
     99         Navigates to the specified page_cycler and waits for the value
    100         of the __pc_done cookie to indicate it is done.
    101 
    102         @param cr: instance of chrome.Chrome class to control chrome.
    103         @param benchmark: page_cycler page to display.
    104         """
    105         PC_START_PAGE = 'data/page_cycler/%s/start.html?auto=1'
    106         PC_DONE_EXP = 'window.document.cookie.indexOf("__pc_done=1") >= 0'
    107         tab = cr.browser.tabs.New()
    108         try:
    109             tab.Activate()
    110             logging.info('Navigating to page cycler %s', benchmark)
    111             start_time = time.time()
    112             benchmark_start_page = PC_START_PAGE % benchmark
    113             tab.Navigate(FILE_URL_PREFIX + benchmark_start_page)
    114             tab.WaitForDocumentReadyStateToBeComplete(timeout=180)
    115             tab.WaitForJavaScriptCondition(PC_DONE_EXP, timeout=600)
    116             tab.Close()
    117             end_time = time.time()
    118             logging.info('Completed page cycler %s in %f seconds',
    119                          benchmark, end_time - start_time)
    120         except Exception as unk_exc:
    121             end_time = time.time()
    122             logging.info('After navigating %s for %f seconds got exception %s',
    123                          benchmark, end_time - start_time, str(unk_exc))
    124             traceback.print_exc(file=sys.stdout)
    125             raise
    126