199 lines
6.6 KiB
Python
Executable file
199 lines
6.6 KiB
Python
Executable file
#!/usr/bin/python
|
|
#
|
|
# Copyright 2011 Google Inc. All Rights Reserved.
|
|
"""Script to profile a page cycler, and get it back to the host."""
|
|
|
|
import copy
|
|
import optparse
|
|
import os
|
|
import pickle
|
|
import re
|
|
import sys
|
|
import tempfile
|
|
import time
|
|
|
|
import build_chrome_browser
|
|
import cros_login
|
|
import lock_machine
|
|
import run_tests
|
|
from cros_utils import command_executer
|
|
from cros_utils import logger
|
|
from cros_utils import misc
|
|
|
|
|
|
class CyclerProfiler:
|
|
REMOTE_TMP_DIR = '/tmp'
|
|
|
|
def __init__(self, chromeos_root, board, cycler, profile_dir, remote):
|
|
self._chromeos_root = chromeos_root
|
|
self._cycler = cycler
|
|
self._profile_dir = profile_dir
|
|
self._remote = remote
|
|
self._board = board
|
|
self._ce = command_executer.GetCommandExecuter()
|
|
self._l = logger.GetLogger()
|
|
|
|
self._gcov_prefix = os.path.join(self.REMOTE_TMP_DIR, self._GetProfileDir())
|
|
|
|
def _GetProfileDir(self):
|
|
return misc.GetCtargetFromBoard(self._board, self._chromeos_root)
|
|
|
|
def _CopyTestData(self):
|
|
page_cycler_dir = os.path.join(self._chromeos_root, 'distfiles', 'target',
|
|
'chrome-src-internal', 'src', 'data',
|
|
'page_cycler')
|
|
if not os.path.isdir(page_cycler_dir):
|
|
raise RuntimeError('Page cycler dir %s not found!' % page_cycler_dir)
|
|
self._ce.CopyFiles(page_cycler_dir,
|
|
os.path.join(self.REMOTE_TMP_DIR, 'page_cycler'),
|
|
dest_machine=self._remote,
|
|
chromeos_root=self._chromeos_root,
|
|
recursive=True,
|
|
dest_cros=True)
|
|
|
|
def _PrepareTestData(self):
|
|
# chmod files so everyone can read them.
|
|
command = ('cd %s && find page_cycler -type f | xargs chmod a+r' %
|
|
self.REMOTE_TMP_DIR)
|
|
self._ce.CrosRunCommand(command,
|
|
chromeos_root=self._chromeos_root,
|
|
machine=self._remote)
|
|
command = ('cd %s && find page_cycler -type d | xargs chmod a+rx' %
|
|
self.REMOTE_TMP_DIR)
|
|
self._ce.CrosRunCommand(command,
|
|
chromeos_root=self._chromeos_root,
|
|
machine=self._remote)
|
|
|
|
def _CopyProfileToHost(self):
|
|
dest_dir = os.path.join(self._profile_dir,
|
|
os.path.basename(self._gcov_prefix))
|
|
# First remove the dir if it exists already
|
|
if os.path.exists(dest_dir):
|
|
command = 'rm -rf %s' % dest_dir
|
|
self._ce.RunCommand(command)
|
|
|
|
# Strip out the initial prefix for the Chrome directory before doing the
|
|
# copy.
|
|
chrome_dir_prefix = misc.GetChromeSrcDir()
|
|
|
|
command = 'mkdir -p %s' % dest_dir
|
|
self._ce.RunCommand(command)
|
|
self._ce.CopyFiles(self._gcov_prefix,
|
|
dest_dir,
|
|
src_machine=self._remote,
|
|
chromeos_root=self._chromeos_root,
|
|
recursive=True,
|
|
src_cros=True)
|
|
|
|
def _RemoveRemoteProfileDir(self):
|
|
command = 'rm -rf %s' % self._gcov_prefix
|
|
self._ce.CrosRunCommand(command,
|
|
chromeos_root=self._chromeos_root,
|
|
machine=self._remote)
|
|
|
|
def _LaunchCycler(self, cycler):
|
|
command = (
|
|
'DISPLAY=:0 '
|
|
'XAUTHORITY=/home/chronos/.Xauthority '
|
|
'GCOV_PREFIX=%s '
|
|
'GCOV_PREFIX_STRIP=3 '
|
|
'/opt/google/chrome/chrome '
|
|
'--no-sandbox '
|
|
'--renderer-clean-exit '
|
|
'--user-data-dir=$(mktemp -d) '
|
|
"--url \"file:///%s/page_cycler/%s/start.html?iterations=10&auto=1\" "
|
|
'--enable-file-cookies '
|
|
'--no-first-run '
|
|
'--js-flags=expose_gc &' % (self._gcov_prefix, self.REMOTE_TMP_DIR,
|
|
cycler))
|
|
|
|
self._ce.CrosRunCommand(command,
|
|
chromeos_root=self._chromeos_root,
|
|
machine=self._remote,
|
|
command_timeout=60)
|
|
|
|
def _PkillChrome(self, signal='9'):
|
|
command = 'pkill -%s chrome' % signal
|
|
self._ce.CrosRunCommand(command,
|
|
chromeos_root=self._chromeos_root,
|
|
machine=self._remote)
|
|
|
|
def DoProfile(self):
|
|
# Copy the page cycler data to the remote
|
|
self._CopyTestData()
|
|
self._PrepareTestData()
|
|
self._RemoveRemoteProfileDir()
|
|
|
|
for cycler in self._cycler.split(','):
|
|
self._ProfileOneCycler(cycler)
|
|
|
|
# Copy the profile back
|
|
self._CopyProfileToHost()
|
|
|
|
def _ProfileOneCycler(self, cycler):
|
|
# With aura, all that's needed is a stop/start ui.
|
|
self._PkillChrome()
|
|
cros_login.RestartUI(self._remote, self._chromeos_root, login=False)
|
|
# Run the cycler
|
|
self._LaunchCycler(cycler)
|
|
self._PkillChrome(signal='INT')
|
|
# Let libgcov dump the profile.
|
|
# TODO(asharif): There is a race condition here. Fix it later.
|
|
time.sleep(30)
|
|
|
|
|
|
def Main(argv):
|
|
"""The main function."""
|
|
# Common initializations
|
|
### command_executer.InitCommandExecuter(True)
|
|
command_executer.InitCommandExecuter()
|
|
l = logger.GetLogger()
|
|
ce = command_executer.GetCommandExecuter()
|
|
parser = optparse.OptionParser()
|
|
parser.add_option('--cycler',
|
|
dest='cycler',
|
|
default='alexa_us',
|
|
help=('Comma-separated cyclers to profile. '
|
|
'Example: alexa_us,moz,moz2'
|
|
'Use all to profile all cyclers.'))
|
|
parser.add_option('--chromeos_root',
|
|
dest='chromeos_root',
|
|
default='../../',
|
|
help='Output profile directory.')
|
|
parser.add_option('--board',
|
|
dest='board',
|
|
default='x86-zgb',
|
|
help='The target board.')
|
|
parser.add_option('--remote',
|
|
dest='remote',
|
|
help=('The remote chromeos machine that'
|
|
' has the profile image.'))
|
|
parser.add_option('--profile_dir',
|
|
dest='profile_dir',
|
|
default='profile_dir',
|
|
help='Store profiles in this directory.')
|
|
|
|
options, _ = parser.parse_args(argv)
|
|
|
|
all_cyclers = ['alexa_us', 'bloat', 'dhtml', 'dom', 'intl1', 'intl2',
|
|
'morejs', 'morejsnp', 'moz', 'moz2']
|
|
|
|
if options.cycler == 'all':
|
|
options.cycler = ','.join(all_cyclers)
|
|
|
|
try:
|
|
cp = CyclerProfiler(options.chromeos_root, options.board, options.cycler,
|
|
options.profile_dir, options.remote)
|
|
cp.DoProfile()
|
|
retval = 0
|
|
except Exception as e:
|
|
retval = 1
|
|
print e
|
|
finally:
|
|
print 'Exiting...'
|
|
return retval
|
|
|
|
|
|
if __name__ == '__main__':
|
|
retval = Main(sys.argv)
|
|
sys.exit(retval)
|