blob: 647e18e5516f45229079f1faa4d0dc1ae5207da8 [file] [log] [blame]
#! /usr/bin/env python
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Instructs Chrome to load series of web pages and reports results.
When running Chrome is sandwiched between preprocessed disk caches and
WepPageReplay serving all connections.
TODO(pasko): implement cache preparation and WPR.
"""
import argparse
import logging
import os
import sys
_SRC_DIR = os.path.abspath(os.path.join(
os.path.dirname(__file__), '..', '..', '..'))
sys.path.append(os.path.join(_SRC_DIR, 'third_party', 'catapult', 'devil'))
from devil.android import device_utils
sys.path.append(os.path.join(_SRC_DIR, 'build', 'android'))
import devil_chromium
import device_setup
import devtools_monitor
import json
import page_track
import tracing
_JOB_SEARCH_PATH = 'sandwich_jobs'
def _ReadUrlsFromJobDescription(job_name):
"""Retrieves the list of URLs associated with the job name."""
try:
# Extra sugar: attempt to load from a relative path.
json_file_name = os.path.join(os.path.dirname(__file__), _JOB_SEARCH_PATH,
job_name)
with open(json_file_name) as f:
json_data = json.load(f)
except IOError:
# Attempt to read by regular file name.
with open(job_name) as f:
json_data = json.load(f)
key = 'urls'
if json_data and key in json_data:
url_list = json_data[key]
if isinstance(url_list, list) and len(url_list) > 0:
return url_list
raise Exception('Job description does not define a list named "urls"')
def _SaveChromeTrace(events, directory, subdirectory):
"""Saves the trace events, ignores IO errors.
Args:
events: a dict as returned by TracingTrack.ToJsonDict()
directory: directory name contining all traces
subdirectory: directory name to create this particular trace in
"""
target_directory = os.path.join(directory, subdirectory)
file_name = os.path.join(target_directory, 'trace.json')
try:
os.makedirs(target_directory)
with open(file_name, 'w') as f:
json.dump({'traceEvents': events['events'], 'metadata': {}}, f)
except IOError:
logging.warning('Could not save a trace: %s' % file_name)
# Swallow the exception.
def main():
logging.basicConfig(level=logging.INFO)
devil_chromium.Initialize()
parser = argparse.ArgumentParser()
parser.add_argument('--job', required=True,
help='JSON file with job description.')
parser.add_argument('--output', required=True,
help='Name of output directory to create.')
parser.add_argument('--repeat', default=1, type=int,
help='How many times to run the job')
args = parser.parse_args()
try:
os.makedirs(args.output)
except OSError:
logging.error('Cannot create directory for results: %s' % args.output)
raise
job_urls = _ReadUrlsFromJobDescription(args.job)
device = device_utils.DeviceUtils.HealthyDevices()[0]
pages_loaded = 0
for _ in xrange(args.repeat):
for url in job_urls:
with device_setup.DeviceConnection(device) as connection:
page_track.PageTrack(connection)
tracing_track = tracing.TracingTrack(connection,
categories='blink,cc,netlog,renderer.scheduler,toplevel,v8')
connection.SetUpMonitoring()
connection.SendAndIgnoreResponse('Page.navigate', {'url': url})
connection.StartMonitoring()
pages_loaded += 1
_SaveChromeTrace(tracing_track.ToJsonDict(), args.output,
str(pages_loaded))
if __name__ == '__main__':
sys.exit(main())