| OLD | NEW |
| 1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
| 2 # Copyright 2016 The Chromium Authors. All rights reserved. | 2 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Instructs Chrome to load series of web pages and reports results. | 6 """Instructs Chrome to load series of web pages and reports results. |
| 7 | 7 |
| 8 When running Chrome is sandwiched between preprocessed disk caches and | 8 When running Chrome is sandwiched between preprocessed disk caches and |
| 9 WepPageReplay serving all connections. | 9 WepPageReplay serving all connections. |
| 10 | 10 |
| 11 TODO(pasko): implement cache preparation and WPR. | 11 TODO(pasko): implement cache preparation and WPR. |
| 12 """ | 12 """ |
| 13 | 13 |
| 14 import argparse | 14 import argparse |
| 15 import csv |
| 15 import json | 16 import json |
| 16 import logging | 17 import logging |
| 17 import os | 18 import os |
| 18 import shutil | 19 import shutil |
| 19 import sys | 20 import sys |
| 20 import tempfile | 21 import tempfile |
| 21 import time | 22 import time |
| 22 | 23 |
| 23 _SRC_DIR = os.path.abspath(os.path.join( | 24 _SRC_DIR = os.path.abspath(os.path.join( |
| 24 os.path.dirname(__file__), '..', '..', '..')) | 25 os.path.dirname(__file__), '..', '..', '..')) |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 shutil.rmtree(self._local_cache_directory_path) | 279 shutil.rmtree(self._local_cache_directory_path) |
| 279 self._local_cache_directory_path = None | 280 self._local_cache_directory_path = None |
| 280 if self.cache_operation == 'save': | 281 if self.cache_operation == 'save': |
| 281 self._PullCacheFromDevice() | 282 self._PullCacheFromDevice() |
| 282 if self.trace_output_directory: | 283 if self.trace_output_directory: |
| 283 self._SaveRunInfos(ran_urls) | 284 self._SaveRunInfos(ran_urls) |
| 284 | 285 |
| 285 | 286 |
| 286 def _ArgumentParser(): | 287 def _ArgumentParser(): |
| 287 """Build a command line argument's parser.""" | 288 """Build a command line argument's parser.""" |
| 289 # Command parser when dealing with jobs. |
| 290 common_job_parser = argparse.ArgumentParser(add_help=False) |
| 291 common_job_parser.add_argument('--job', required=True, |
| 292 help='JSON file with job description.') |
| 293 |
| 294 # Main parser |
| 288 parser = argparse.ArgumentParser() | 295 parser = argparse.ArgumentParser() |
| 289 parser.add_argument('--job', required=True, | |
| 290 help='JSON file with job description.') | |
| 291 subparsers = parser.add_subparsers(dest='subcommand', help='subcommand line') | 296 subparsers = parser.add_subparsers(dest='subcommand', help='subcommand line') |
| 292 | 297 |
| 293 # Record WPR subcommand. | 298 # Record WPR subcommand. |
| 294 record_wpr = subparsers.add_parser('record-wpr', | 299 record_wpr = subparsers.add_parser('record-wpr', parents=[common_job_parser], |
| 295 help='Record WPR from sandwich job.') | 300 help='Record WPR from sandwich job.') |
| 296 record_wpr.add_argument('--wpr-archive', required=True, type=str, | 301 record_wpr.add_argument('--wpr-archive', required=True, type=str, |
| 297 dest='wpr_archive_path', | 302 dest='wpr_archive_path', |
| 298 help='Web page replay archive to generate.') | 303 help='Web page replay archive to generate.') |
| 299 | 304 |
| 300 # Patch WPR subcommand. | 305 # Patch WPR subcommand. |
| 301 patch_wpr = subparsers.add_parser('patch-wpr', | 306 patch_wpr = subparsers.add_parser('patch-wpr', |
| 302 help='Patch WPR response headers.') | 307 help='Patch WPR response headers.') |
| 303 patch_wpr.add_argument('--wpr-archive', required=True, type=str, | 308 patch_wpr.add_argument('--wpr-archive', required=True, type=str, |
| 304 dest='wpr_archive_path', | 309 dest='wpr_archive_path', |
| 305 help='Web page replay archive to generate.') | 310 help='Web page replay archive to patch.') |
| 306 | 311 |
| 307 # Create cache subcommand. | 312 # Create cache subcommand. |
| 308 create_cache_parser = subparsers.add_parser('create-cache', | 313 create_cache_parser = subparsers.add_parser('create-cache', |
| 314 parents=[common_job_parser], |
| 309 help='Create cache from sandwich job.') | 315 help='Create cache from sandwich job.') |
| 310 create_cache_parser.add_argument('--cache-archive', required=True, type=str, | 316 create_cache_parser.add_argument('--cache-archive', required=True, type=str, |
| 311 dest='cache_archive_path', | 317 dest='cache_archive_path', |
| 312 help='Cache archive destination path.') | 318 help='Cache archive destination path.') |
| 313 create_cache_parser.add_argument('--wpr-archive', default=None, type=str, | 319 create_cache_parser.add_argument('--wpr-archive', default=None, type=str, |
| 314 dest='wpr_archive_path', | 320 dest='wpr_archive_path', |
| 315 help='Web page replay archive to create ' + | 321 help='Web page replay archive to create ' + |
| 316 'the cache from.') | 322 'the cache from.') |
| 317 | 323 |
| 318 # Run subcommand. | 324 # Run subcommand. |
| 319 run_parser = subparsers.add_parser('run', help='Run sandwich benchmark.') | 325 run_parser = subparsers.add_parser('run', parents=[common_job_parser], |
| 326 help='Run sandwich benchmark.') |
| 320 run_parser.add_argument('--output', required=True, type=str, | 327 run_parser.add_argument('--output', required=True, type=str, |
| 321 dest='trace_output_directory', | 328 dest='trace_output_directory', |
| 322 help='Path of output directory to create.') | 329 help='Path of output directory to create.') |
| 323 run_parser.add_argument('--cache-archive', type=str, | 330 run_parser.add_argument('--cache-archive', type=str, |
| 324 dest='cache_archive_path', | 331 dest='cache_archive_path', |
| 325 help='Cache archive destination path.') | 332 help='Cache archive destination path.') |
| 326 run_parser.add_argument('--cache-op', | 333 run_parser.add_argument('--cache-op', |
| 327 choices=['clear', 'push', 'reload'], | 334 choices=['clear', 'push', 'reload'], |
| 328 dest='cache_operation', | 335 dest='cache_operation', |
| 329 default='clear', | 336 default='clear', |
| (...skipping 13 matching lines...) Expand all Loading... |
| 343 choices=['browser', 'wpr'], | 350 choices=['browser', 'wpr'], |
| 344 help='Set which component is emulating the network condition.' + | 351 help='Set which component is emulating the network condition.' + |
| 345 ' (Default to browser). Wpr network emulator requires --wpr-archive' + | 352 ' (Default to browser). Wpr network emulator requires --wpr-archive' + |
| 346 ' to be set.') | 353 ' to be set.') |
| 347 run_parser.add_argument('--job-repeat', default=1, type=int, | 354 run_parser.add_argument('--job-repeat', default=1, type=int, |
| 348 help='How many times to run the job.') | 355 help='How many times to run the job.') |
| 349 run_parser.add_argument('--wpr-archive', default=None, type=str, | 356 run_parser.add_argument('--wpr-archive', default=None, type=str, |
| 350 dest='wpr_archive_path', | 357 dest='wpr_archive_path', |
| 351 help='Web page replay archive to load job\'s urls ' + | 358 help='Web page replay archive to load job\'s urls ' + |
| 352 'from.') | 359 'from.') |
| 360 |
| 361 # Pull metrics subcommand. |
| 362 create_cache_parser = subparsers.add_parser('extract-metrics', |
| 363 help='Extracts metrics from a loading trace and saves as CSV.') |
| 364 create_cache_parser.add_argument('--trace-directory', required=True, |
| 365 dest='trace_output_directory', type=str, |
| 366 help='Path of loading traces directory.') |
| 367 create_cache_parser.add_argument('--out-metrics', default=None, type=str, |
| 368 dest='metrics_csv_path', |
| 369 help='Path where to save the metrics\'s '+ |
| 370 'CSV.') |
| 371 |
| 353 return parser | 372 return parser |
| 354 | 373 |
| 355 | 374 |
| 356 def _RecordWprMain(args): | 375 def _RecordWprMain(args): |
| 357 sandwich_runner = SandwichRunner(args.job) | 376 sandwich_runner = SandwichRunner(args.job) |
| 358 sandwich_runner.PullConfigFromArgs(args) | 377 sandwich_runner.PullConfigFromArgs(args) |
| 359 sandwich_runner.wpr_record = True | 378 sandwich_runner.wpr_record = True |
| 360 sandwich_runner.PrintConfig() | 379 sandwich_runner.PrintConfig() |
| 380 if not os.path.isdir(os.path.dirname(args.wpr_archive_path)): |
| 381 os.makedirs(os.path.dirname(args.wpr_archive_path)) |
| 361 sandwich_runner.Run() | 382 sandwich_runner.Run() |
| 362 return 0 | 383 return 0 |
| 363 | 384 |
| 364 | 385 |
| 365 def _PatchWprMain(args): | 386 def _PatchWprMain(args): |
| 366 # Sets the resources cache max-age to 10 years. | 387 # Sets the resources cache max-age to 10 years. |
| 367 MAX_AGE = 10 * 365 * 24 * 60 * 60 | 388 MAX_AGE = 10 * 365 * 24 * 60 * 60 |
| 368 CACHE_CONTROL = 'public, max-age={}'.format(MAX_AGE) | 389 CACHE_CONTROL = 'public, max-age={}'.format(MAX_AGE) |
| 369 | 390 |
| 370 wpr_archive = wpr_backend.WprArchiveBackend(args.wpr_archive_path) | 391 wpr_archive = wpr_backend.WprArchiveBackend(args.wpr_archive_path) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 390 url_entry.SetResponseHeader('cache-control', CACHE_CONTROL) | 411 url_entry.SetResponseHeader('cache-control', CACHE_CONTROL) |
| 391 wpr_archive.Persist() | 412 wpr_archive.Persist() |
| 392 return 0 | 413 return 0 |
| 393 | 414 |
| 394 | 415 |
| 395 def _CreateCacheMain(args): | 416 def _CreateCacheMain(args): |
| 396 sandwich_runner = SandwichRunner(args.job) | 417 sandwich_runner = SandwichRunner(args.job) |
| 397 sandwich_runner.PullConfigFromArgs(args) | 418 sandwich_runner.PullConfigFromArgs(args) |
| 398 sandwich_runner.cache_operation = 'save' | 419 sandwich_runner.cache_operation = 'save' |
| 399 sandwich_runner.PrintConfig() | 420 sandwich_runner.PrintConfig() |
| 421 if not os.path.isdir(os.path.dirname(args.cache_archive_path)): |
| 422 os.makedirs(os.path.dirname(args.cache_archive_path)) |
| 400 sandwich_runner.Run() | 423 sandwich_runner.Run() |
| 401 return 0 | 424 return 0 |
| 402 | 425 |
| 403 | 426 |
| 404 def _RunJobMain(args): | 427 def _RunJobMain(args): |
| 405 sandwich_runner = SandwichRunner(args.job) | 428 sandwich_runner = SandwichRunner(args.job) |
| 406 sandwich_runner.PullConfigFromArgs(args) | 429 sandwich_runner.PullConfigFromArgs(args) |
| 407 sandwich_runner.PrintConfig() | 430 sandwich_runner.PrintConfig() |
| 408 sandwich_runner.Run() | 431 sandwich_runner.Run() |
| 409 return 0 | 432 return 0 |
| 410 | 433 |
| 411 | 434 |
| 435 def _ExtractMetricsMain(args): |
| 436 trace_metrics_list = pull_sandwich_metrics.PullMetricsFromOutputDirectory( |
| 437 args.trace_output_directory) |
| 438 trace_metrics_list.sort(key=lambda e: e['id']) |
| 439 with open(args.metrics_csv_path, 'w') as csv_file: |
| 440 writer = csv.DictWriter(csv_file, |
| 441 fieldnames=pull_sandwich_metrics.CSV_FIELD_NAMES) |
| 442 writer.writeheader() |
| 443 for trace_metrics in trace_metrics_list: |
| 444 writer.writerow(trace_metrics) |
| 445 return 0 |
| 446 |
| 447 |
| 412 def main(command_line_args): | 448 def main(command_line_args): |
| 413 logging.basicConfig(level=logging.INFO) | 449 logging.basicConfig(level=logging.INFO) |
| 414 devil_chromium.Initialize() | 450 devil_chromium.Initialize() |
| 415 | 451 |
| 416 # Don't give the argument yet. All we are interested in for now is accessing | 452 # Don't give the argument yet. All we are interested in for now is accessing |
| 417 # the default values of OPTIONS. | 453 # the default values of OPTIONS. |
| 418 OPTIONS.ParseArgs([]) | 454 OPTIONS.ParseArgs([]) |
| 419 | 455 |
| 420 args = _ArgumentParser().parse_args(command_line_args) | 456 args = _ArgumentParser().parse_args(command_line_args) |
| 421 | 457 |
| 422 if args.subcommand == 'record-wpr': | 458 if args.subcommand == 'record-wpr': |
| 423 return _RecordWprMain(args) | 459 return _RecordWprMain(args) |
| 424 if args.subcommand == 'patch-wpr': | 460 if args.subcommand == 'patch-wpr': |
| 425 return _PatchWprMain(args) | 461 return _PatchWprMain(args) |
| 426 if args.subcommand == 'create-cache': | 462 if args.subcommand == 'create-cache': |
| 427 return _CreateCacheMain(args) | 463 return _CreateCacheMain(args) |
| 428 if args.subcommand == 'run': | 464 if args.subcommand == 'run': |
| 429 return _RunJobMain(args) | 465 return _RunJobMain(args) |
| 466 if args.subcommand == 'extract-metrics': |
| 467 return _ExtractMetricsMain(args) |
| 430 assert False | 468 assert False |
| 431 | 469 |
| 432 | 470 |
| 433 if __name__ == '__main__': | 471 if __name__ == '__main__': |
| 434 sys.exit(main(sys.argv[1:])) | 472 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |