Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: telemetry/third_party/webpagereplay/replay.py

Issue 2162963002: [polymer] Merge of master into polymer10-migration (Closed) Base URL: git@github.com:catapult-project/catapult.git@polymer10-migration
Patch Set: Merge polymer10-migration int polymer10-merge Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2010 Google Inc. All Rights Reserved. 2 # Copyright 2010 Google Inc. All Rights Reserved.
3 # 3 #
4 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License. 5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at 6 # You may obtain a copy of the License at
7 # 7 #
8 # http://www.apache.org/licenses/LICENSE-2.0 8 # http://www.apache.org/licenses/LICENSE-2.0
9 # 9 #
10 # Unless required by applicable law or agreed to in writing, software 10 # Unless required by applicable law or agreed to in writing, software
(...skipping 21 matching lines...) Expand all
32 resources not in the recorded archive. 32 resources not in the recorded archive.
33 33
34 Network simulation examples: 34 Network simulation examples:
35 # 128KByte/s uplink bandwidth, 4Mbps/s downlink bandwidth with 100ms RTT time 35 # 128KByte/s uplink bandwidth, 4Mbps/s downlink bandwidth with 100ms RTT time
36 $ sudo ./replay.py --up 128KByte/s --down 4Mbit/s --delay_ms=100 archive.wpr 36 $ sudo ./replay.py --up 128KByte/s --down 4Mbit/s --delay_ms=100 archive.wpr
37 37
38 # 1% packet loss rate 38 # 1% packet loss rate
39 $ sudo ./replay.py --packet_loss_rate=0.01 archive.wpr 39 $ sudo ./replay.py --packet_loss_rate=0.01 archive.wpr
40 """ 40 """
41 41
42 import argparse
42 import json 43 import json
43 import logging 44 import logging
44 import optparse
45 import os 45 import os
46 import socket 46 import socket
47 import sys 47 import sys
48 import traceback 48 import traceback
49 49
50 import customhandlers 50 import customhandlers
51 import dnsproxy 51 import dnsproxy
52 import httparchive 52 import httparchive
53 import httpclient 53 import httpclient
54 import httpproxy 54 import httpproxy
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 server_manager.AppendTrafficShaper( 170 server_manager.AppendTrafficShaper(
171 trafficshaper.TrafficShaper, host=host, 171 trafficshaper.TrafficShaper, host=host,
172 use_loopback=not options.server_mode and host == '127.0.0.1', 172 use_loopback=not options.server_mode and host == '127.0.0.1',
173 **options.shaping_dummynet) 173 **options.shaping_dummynet)
174 174
175 175
176 class OptionsWrapper(object): 176 class OptionsWrapper(object):
177 """Add checks, updates, and methods to option values. 177 """Add checks, updates, and methods to option values.
178 178
179 Example: 179 Example:
180 options, args = option_parser.parse_args() 180 options, args = arg_parser.parse_args()
181 options = OptionsWrapper(options, option_parser) # run checks and updates 181 options = OptionsWrapper(options, arg_parser) # run checks and updates
182 if options.record and options.HasTrafficShaping(): 182 if options.record and options.HasTrafficShaping():
183 [...] 183 [...]
184 """ 184 """
185 _TRAFFICSHAPING_OPTIONS = { 185 _TRAFFICSHAPING_OPTIONS = {
186 'down', 'up', 'delay_ms', 'packet_loss_rate', 'init_cwnd', 'net'} 186 'down', 'up', 'delay_ms', 'packet_loss_rate', 'init_cwnd', 'net'}
187 _CONFLICTING_OPTIONS = ( 187 _CONFLICTING_OPTIONS = (
188 ('record', ('down', 'up', 'delay_ms', 'packet_loss_rate', 'net', 188 ('record', ('down', 'up', 'delay_ms', 'packet_loss_rate', 'net',
189 'spdy', 'use_server_delay')), 189 'spdy', 'use_server_delay')),
190 ('append', ('down', 'up', 'delay_ms', 'packet_loss_rate', 'net', 190 ('append', ('down', 'up', 'delay_ms', 'packet_loss_rate', 'net',
191 'use_server_delay')), # same as --record 191 'use_server_delay')), # same as --record
192 ('net', ('down', 'up', 'delay_ms')), 192 ('net', ('down', 'up', 'delay_ms')),
193 ('server', ('server_mode',)), 193 ('server', ('server_mode',)),
194 ) 194 )
195 195
196 def __init__(self, options, parser): 196 def __init__(self, options, parser):
197 self._options = options 197 self._options = options
198 self._parser = parser 198 self._parser = parser
199 self._nondefaults = set([ 199 self._nondefaults = set([
200 name for name, value in parser.defaults.items() 200 action.dest for action in parser._optionals._actions
201 if getattr(options, name) != value]) 201 if getattr(options, action.dest, action.default) is not action.default])
202 self._CheckConflicts() 202 self._CheckConflicts()
203 self._CheckValidIp('host') 203 self._CheckValidIp('host')
204 self._CheckFeatureSupport() 204 self._CheckFeatureSupport()
205 self._MassageValues() 205 self._MassageValues()
206 206
207 def _CheckConflicts(self): 207 def _CheckConflicts(self):
208 """Give an error if mutually exclusive options are used.""" 208 """Give an error if mutually exclusive options are used."""
209 for option, bad_options in self._CONFLICTING_OPTIONS: 209 for option, bad_options in self._CONFLICTING_OPTIONS:
210 if option in self._nondefaults: 210 if option in self._nondefaults:
211 for bad_option in bad_options: 211 for bad_option in bad_options:
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 except Exception: 366 except Exception:
367 logging.critical(traceback.format_exc()) 367 logging.critical(traceback.format_exc())
368 exit_status = 2 368 exit_status = 2
369 369
370 if options.record: 370 if options.record:
371 http_archive.Persist(replay_filename) 371 http_archive.Persist(replay_filename)
372 logging.info('Saved %d responses to %s', len(http_archive), replay_filename) 372 logging.info('Saved %d responses to %s', len(http_archive), replay_filename)
373 return exit_status 373 return exit_status
374 374
375 375
376 def GetOptionParser(): 376 def GetParser():
377 class PlainHelpFormatter(optparse.IndentedHelpFormatter): 377 arg_parser = argparse.ArgumentParser(
378 def format_description(self, description): 378 usage='%(prog)s [options] replay_file',
379 if description:
380 return description + '\n'
381 else:
382 return ''
383 option_parser = optparse.OptionParser(
384 usage='%prog [options] replay_file',
385 formatter=PlainHelpFormatter(),
386 description=__doc__, 379 description=__doc__,
380 formatter_class=argparse.RawDescriptionHelpFormatter,
387 epilog='http://code.google.com/p/web-page-replay/') 381 epilog='http://code.google.com/p/web-page-replay/')
388 382
389 option_parser.add_option('-r', '--record', default=False, 383 arg_parser.add_argument('replay_filename', type=str, help='Replay file',
384 nargs='?')
385
386 arg_parser.add_argument('-r', '--record', default=False,
390 action='store_true', 387 action='store_true',
391 help='Download real responses and record them to replay_file') 388 help='Download real responses and record them to replay_file')
392 option_parser.add_option('--append', default=False, 389 arg_parser.add_argument('--append', default=False,
393 action='store_true', 390 action='store_true',
394 help='Append responses to replay_file.') 391 help='Append responses to replay_file.')
395 option_parser.add_option('-l', '--log_level', default='debug', 392 arg_parser.add_argument('-l', '--log_level', default='debug',
396 action='store', 393 action='store',
397 type='choice', 394 type=str,
398 choices=('debug', 'info', 'warning', 'error', 'critical'), 395 choices=('debug', 'info', 'warning', 'error', 'critical'),
399 help='Minimum verbosity level to log') 396 help='Minimum verbosity level to log')
400 option_parser.add_option('-f', '--log_file', default=None, 397 arg_parser.add_argument('-f', '--log_file', default=None,
401 action='store', 398 action='store',
402 type='string', 399 type=str,
403 help='Log file to use in addition to writting logs to stderr.') 400 help='Log file to use in addition to writting logs to stderr.')
404 401
405 network_group = optparse.OptionGroup(option_parser, 402 network_group = arg_parser.add_argument_group(
406 'Network Simulation Options', 403 title='Network Simulation Options',
407 'These options configure the network simulation in replay mode') 404 description=('These options configure the network simulation in '
408 network_group.add_option('-u', '--up', default='0', 405 'replay mode'))
406 network_group.add_argument('-u', '--up', default='0',
409 action='store', 407 action='store',
410 type='string', 408 type=str,
411 help='Upload Bandwidth in [K|M]{bit/s|Byte/s}. Zero means unlimited.') 409 help='Upload Bandwidth in [K|M]{bit/s|Byte/s}. Zero means unlimited.')
412 network_group.add_option('-d', '--down', default='0', 410 network_group.add_argument('-d', '--down', default='0',
413 action='store', 411 action='store',
414 type='string', 412 type=str,
415 help='Download Bandwidth in [K|M]{bit/s|Byte/s}. Zero means unlimited.') 413 help='Download Bandwidth in [K|M]{bit/s|Byte/s}. Zero means unlimited.')
416 network_group.add_option('-m', '--delay_ms', default='0', 414 network_group.add_argument('-m', '--delay_ms', default='0',
417 action='store', 415 action='store',
418 type='string', 416 type=str,
419 help='Propagation delay (latency) in milliseconds. Zero means no delay.') 417 help='Propagation delay (latency) in milliseconds. Zero means no delay.')
420 network_group.add_option('-p', '--packet_loss_rate', default='0', 418 network_group.add_argument('-p', '--packet_loss_rate', default='0',
421 action='store', 419 action='store',
422 type='string', 420 type=str,
423 help='Packet loss rate in range [0..1]. Zero means no loss.') 421 help='Packet loss rate in range [0..1]. Zero means no loss.')
424 network_group.add_option('-w', '--init_cwnd', default='0', 422 network_group.add_argument('-w', '--init_cwnd', default='0',
425 action='store', 423 action='store',
426 type='string', 424 type=str,
427 help='Set initial cwnd (linux only, requires kernel patch)') 425 help='Set initial cwnd (linux only, requires kernel patch)')
428 network_group.add_option('--net', default=None, 426 network_group.add_argument('--net', default=None,
429 action='store', 427 action='store',
430 type='choice', 428 type=str,
431 choices=net_configs.NET_CONFIG_NAMES, 429 choices=net_configs.NET_CONFIG_NAMES,
432 help='Select a set of network options: %s.' % ', '.join( 430 help='Select a set of network options: %s.' % ', '.join(
433 net_configs.NET_CONFIG_NAMES)) 431 net_configs.NET_CONFIG_NAMES))
434 network_group.add_option('--shaping_type', default='dummynet', 432 network_group.add_argument('--shaping_type', default='dummynet',
435 action='store', 433 action='store',
436 choices=('dummynet', 'proxy'), 434 choices=('dummynet', 'proxy'),
437 help='When shaping is configured (i.e. --up, --down, etc.) decides ' 435 help='When shaping is configured (i.e. --up, --down, etc.) decides '
438 'whether to use |dummynet| (default), or |proxy| servers.') 436 'whether to use |dummynet| (default), or |proxy| servers.')
439 option_parser.add_option_group(network_group)
440 437
441 harness_group = optparse.OptionGroup(option_parser, 438 harness_group = arg_parser.add_argument_group(
442 'Replay Harness Options', 439 title='Replay Harness Options',
443 'These advanced options configure various aspects of the replay harness') 440 description=('These advanced options configure various aspects '
444 harness_group.add_option('-S', '--server', default=None, 441 'of the replay harness'))
442 harness_group.add_argument('-S', '--server', default=None,
445 action='store', 443 action='store',
446 type='string', 444 type=str,
447 help='IP address of host running "replay.py --server_mode". ' 445 help='IP address of host running "replay.py --server_mode". '
448 'This only changes the primary DNS nameserver to use the given IP.') 446 'This only changes the primary DNS nameserver to use the given IP.')
449 harness_group.add_option('-M', '--server_mode', default=False, 447 harness_group.add_argument('-M', '--server_mode', default=False,
450 action='store_true', 448 action='store_true',
451 help='Run replay DNS & http proxies, and trafficshaping on --port ' 449 help='Run replay DNS & http proxies, and trafficshaping on --port '
452 'without changing the primary DNS nameserver. ' 450 'without changing the primary DNS nameserver. '
453 'Other hosts may connect to this using "replay.py --server" ' 451 'Other hosts may connect to this using "replay.py --server" '
454 'or by pointing their DNS to this server.') 452 'or by pointing their DNS to this server.')
455 harness_group.add_option('-i', '--inject_scripts', default='deterministic.js', 453 harness_group.add_argument('-i', '--inject_scripts', default='deterministic.js ',
456 action='store', 454 action='store',
457 dest='inject_scripts', 455 dest='inject_scripts',
458 help='A comma separated list of JavaScript sources to inject in all ' 456 help='A comma separated list of JavaScript sources to inject in all '
459 'pages. By default a script is injected that eliminates sources ' 457 'pages. By default a script is injected that eliminates sources '
460 'of entropy such as Date() and Math.random() deterministic. ' 458 'of entropy such as Date() and Math.random() deterministic. '
461 'CAUTION: Without deterministic.js, many pages will not replay.') 459 'CAUTION: Without deterministic.js, many pages will not replay.')
462 harness_group.add_option('-D', '--no-diff_unknown_requests', default=True, 460 harness_group.add_argument('-D', '--no-diff_unknown_requests', default=True,
463 action='store_false', 461 action='store_false',
464 dest='diff_unknown_requests', 462 dest='diff_unknown_requests',
465 help='During replay, do not show a diff of unknown requests against ' 463 help='During replay, do not show a diff of unknown requests against '
466 'their nearest match in the archive.') 464 'their nearest match in the archive.')
467 harness_group.add_option('-C', '--use_closest_match', default=False, 465 harness_group.add_argument('-C', '--use_closest_match', default=False,
468 action='store_true', 466 action='store_true',
469 dest='use_closest_match', 467 dest='use_closest_match',
470 help='During replay, if a request is not found, serve the closest match' 468 help='During replay, if a request is not found, serve the closest match'
471 'in the archive instead of giving a 404.') 469 'in the archive instead of giving a 404.')
472 harness_group.add_option('-U', '--use_server_delay', default=False, 470 harness_group.add_argument('-U', '--use_server_delay', default=False,
473 action='store_true', 471 action='store_true',
474 dest='use_server_delay', 472 dest='use_server_delay',
475 help='During replay, simulate server delay by delaying response time to' 473 help='During replay, simulate server delay by delaying response time to'
476 'requests.') 474 'requests.')
477 harness_group.add_option('-I', '--screenshot_dir', default=None, 475 harness_group.add_argument('-I', '--screenshot_dir', default=None,
478 action='store', 476 action='store',
479 type='string', 477 type=str,
480 help='Save PNG images of the loaded page in the given directory.') 478 help='Save PNG images of the loaded page in the given directory.')
481 harness_group.add_option('-P', '--no-dns_private_passthrough', default=True, 479 harness_group.add_argument('-P', '--no-dns_private_passthrough', default=True,
482 action='store_false', 480 action='store_false',
483 dest='dns_private_passthrough', 481 dest='dns_private_passthrough',
484 help='Don\'t forward DNS requests that resolve to private network ' 482 help='Don\'t forward DNS requests that resolve to private network '
485 'addresses. CAUTION: With this option important services like ' 483 'addresses. CAUTION: With this option important services like '
486 'Kerberos will resolve to the HTTP proxy address.') 484 'Kerberos will resolve to the HTTP proxy address.')
487 harness_group.add_option('-x', '--no-dns_forwarding', default=True, 485 harness_group.add_argument('-x', '--no-dns_forwarding', default=True,
488 action='store_false', 486 action='store_false',
489 dest='dns_forwarding', 487 dest='dns_forwarding',
490 help='Don\'t forward DNS requests to the local replay server. ' 488 help='Don\'t forward DNS requests to the local replay server. '
491 'CAUTION: With this option an external mechanism must be used to ' 489 'CAUTION: With this option an external mechanism must be used to '
492 'forward traffic to the replay server.') 490 'forward traffic to the replay server.')
493 harness_group.add_option('--host', default=None, 491 harness_group.add_argument('--host', default=None,
494 action='store', 492 action='store',
495 type='str', 493 type=str,
496 help='The IP address to bind all servers to. Defaults to 0.0.0.0 or ' 494 help='The IP address to bind all servers to. Defaults to 0.0.0.0 or '
497 '127.0.0.1, depending on --server_mode and platform.') 495 '127.0.0.1, depending on --server_mode and platform.')
498 harness_group.add_option('-o', '--port', default=80, 496 harness_group.add_argument('-o', '--port', default=80,
499 action='store', 497 action='store',
500 type='int', 498 type=int,
501 help='Port number to listen on.') 499 help='Port number to listen on.')
502 harness_group.add_option('--ssl_port', default=443, 500 harness_group.add_argument('--ssl_port', default=443,
503 action='store', 501 action='store',
504 type='int', 502 type=int,
505 help='SSL port number to listen on.') 503 help='SSL port number to listen on.')
506 harness_group.add_option('--http_to_https_port', default=None, 504 harness_group.add_argument('--http_to_https_port', default=None,
507 action='store', 505 action='store',
508 type='int', 506 type=int,
509 help='Port on which WPR will listen for HTTP requests that it will send ' 507 help='Port on which WPR will listen for HTTP requests that it will send '
510 'along as HTTPS requests.') 508 'along as HTTPS requests.')
511 harness_group.add_option('--dns_port', default=53, 509 harness_group.add_argument('--dns_port', default=53,
512 action='store', 510 action='store',
513 type='int', 511 type=int,
514 help='DNS port number to listen on.') 512 help='DNS port number to listen on.')
515 harness_group.add_option('-c', '--https_root_ca_cert_path', default=None, 513 harness_group.add_argument('-c', '--https_root_ca_cert_path', default=None,
516 action='store', 514 action='store',
517 type='string', 515 type=str,
518 help='Certificate file to use with SSL (gets auto-generated if needed).') 516 help='Certificate file to use with SSL (gets auto-generated if needed).')
519 harness_group.add_option('--no-ssl', default=True, 517 harness_group.add_argument('--no-ssl', default=True,
520 action='store_false', 518 action='store_false',
521 dest='ssl', 519 dest='ssl',
522 help='Do not setup an SSL proxy.') 520 help='Do not setup an SSL proxy.')
523 option_parser.add_option_group(harness_group) 521 harness_group.add_argument('--should_generate_certs', default=False,
524 harness_group.add_option('--should_generate_certs', default=False,
525 action='store_true', 522 action='store_true',
526 help='Use OpenSSL to generate certificate files for requested hosts.') 523 help='Use OpenSSL to generate certificate files for requested hosts.')
527 harness_group.add_option('--no-admin-check', default=True, 524 harness_group.add_argument('--no-admin-check', default=True,
528 action='store_false', 525 action='store_false',
529 dest='admin_check', 526 dest='admin_check',
530 help='Do not check if administrator access is needed.') 527 help='Do not check if administrator access is needed.')
531 harness_group.add_option('--scramble_images', default=False, 528 harness_group.add_argument('--scramble_images', default=False,
532 action='store_true', 529 action='store_true',
533 dest='scramble_images', 530 dest='scramble_images',
534 help='Scramble image responses.') 531 help='Scramble image responses.')
535 harness_group.add_option('--rules_path', default=None, 532 harness_group.add_argument('--rules_path', default=None,
536 action='store', 533 action='store',
537 help='Path of file containing Python rules.') 534 help='Path of file containing Python rules.')
538 harness_group.add_option('--allowed_rule_imports', default='rules', 535 harness_group.add_argument('--allowed_rule_imports', default='rules',
539 action='store', 536 action='store',
540 help='A comma-separate list of allowed rule imports, or \'*\' to allow' 537 help='A comma-separate list of allowed rule imports, or \'*\' to allow'
541 ' all packages. Defaults to \'%default\'.') 538 ' all packages. Defaults to %(default)s.')
542 return option_parser 539 return arg_parser
543 540
544 541
545 def main(): 542 def main():
546 option_parser = GetOptionParser() 543 arg_parser = GetParser()
547 options, args = option_parser.parse_args() 544 options = arg_parser.parse_args()
548 options = OptionsWrapper(options, option_parser) 545 options = OptionsWrapper(options, arg_parser)
549 546
550 if options.server: 547 if options.server:
551 replay_filename = None 548 options.replay_filename = None
552 elif len(args) != 1: 549 elif options.replay_filename is None:
553 option_parser.error('Must specify a replay_file') 550 arg_parser.error('Must specify a replay_file')
554 else: 551 return replay(options, options.replay_filename)
555 replay_filename = args[0]
556
557 return replay(options, replay_filename)
558 552
559 553
560 if __name__ == '__main__': 554 if __name__ == '__main__':
561 sys.exit(main()) 555 sys.exit(main())
OLDNEW
« no previous file with comments | « telemetry/third_party/webpagereplay/httpclient.py ('k') | telemetry/third_party/webpagereplay/replay_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698