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

Side by Side Diff: tools/callstats.py

Issue 2380643002: [tools] Add support to launch the replay server separately for callstats.py (Closed)
Patch Set: rename function Created 4 years, 2 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2016 the V8 project authors. All rights reserved. 2 # Copyright 2016 the V8 project 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 Usage: callstats.py [-h] <command> ... 6 Usage: callstats.py [-h] <command> ...
7 7
8 Optional arguments: 8 Optional arguments:
9 -h, --help show this help message and exit 9 -h, --help show this help message and exit
10 10
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 }, timeout); 116 }, timeout);
117 return; 117 return;
118 } 118 }
119 console.log("Ignoring: " + url); 119 console.log("Ignoring: " + url);
120 }; 120 };
121 var sites = 121 var sites =
122 """, json.dumps(sites), """; 122 """, json.dumps(sites), """;
123 onLoad(window.location.href); 123 onLoad(window.location.href);
124 })();""" 124 })();"""
125 125
126 def get_chrome_flags(js_flags, user_data_dir):
127 return [
128 "--no-default-browser-check",
129 "--no-sandbox",
130 "--disable-translate",
131 "--enable-benchmarking",
132 "--js-flags={}".format(js_flags),
133 "--no-first-run",
134 "--user-data-dir={}".format(user_data_dir),
135 ]
136
137 def get_chrome_replay_flags(args):
138 http_port = 4080 + args.port_offset
139 https_port = 4443 + args.port_offset
140 return [
141 "--host-resolver-rules=MAP *:80 localhost:%s, " \
142 "MAP *:443 localhost:%s, " \
143 "EXCLUDE localhost" % (
144 http_port, https_port),
145 "--ignore-certificate-errors",
146 "--disable-seccomp-sandbox",
147 "--disable-web-security",
148 "--reduce-security-for-testing",
149 "--allow-insecure-localhost",
150 ]
126 151
127 def run_site(site, domain, args, timeout=None): 152 def run_site(site, domain, args, timeout=None):
128 print "="*80 153 print "="*80
129 print "RUNNING DOMAIN %s" % domain 154 print "RUNNING DOMAIN %s" % domain
130 print "="*80 155 print "="*80
131 result_template = "{domain}#{count}.txt" if args.repeat else "{domain}.txt" 156 result_template = "{domain}#{count}.txt" if args.repeat else "{domain}.txt"
132 count = 0 157 count = 0
133 if timeout is None: timeout = args.timeout 158 if timeout is None: timeout = args.timeout
134 if args.replay_wpr: 159 if args.replay_wpr:
135 timeout *= 1 + args.refresh 160 timeout *= 1 + args.refresh
136 timeout += 1 161 timeout += 1
137 retries_since_good_run = 0 162 retries_since_good_run = 0
138 while count == 0 or args.repeat is not None and count < args.repeat: 163 while count == 0 or args.repeat is not None and count < args.repeat:
139 count += 1 164 count += 1
140 result = result_template.format(domain=domain, count=count) 165 result = result_template.format(domain=domain, count=count)
141 retries = 0 166 retries = 0
142 while args.retries is None or retries < args.retries: 167 while args.retries is None or retries < args.retries:
143 retries += 1 168 retries += 1
144 try: 169 try:
145 if args.user_data_dir: 170 if args.user_data_dir:
146 user_data_dir = args.user_data_dir 171 user_data_dir = args.user_data_dir
147 else: 172 else:
148 user_data_dir = tempfile.mkdtemp(prefix="chr_") 173 user_data_dir = tempfile.mkdtemp(prefix="chr_")
149 js_flags = "--runtime-call-stats" 174 js_flags = "--runtime-call-stats"
150 if args.replay_wpr: js_flags += " --allow-natives-syntax" 175 if args.replay_wpr: js_flags += " --allow-natives-syntax"
151 if args.js_flags: js_flags += " " + args.js_flags 176 if args.js_flags: js_flags += " " + args.js_flags
152 chrome_flags = [ 177 chrome_flags = get_chrome_flags(js_flags, user_data_dir)
153 "--no-default-browser-check",
154 "--no-sandbox",
155 "--disable-translate",
156 "--enable-benchmarking",
157 "--js-flags={}".format(js_flags),
158 "--no-first-run",
159 "--user-data-dir={}".format(user_data_dir),
160 ]
161 if args.replay_wpr: 178 if args.replay_wpr:
162 http_port = 4080 + args.port_offset 179 chrome_flags += get_chrome_replay_flags(args)
163 https_port = 4443 + args.port_offset
164 chrome_flags += [
165 "--host-resolver-rules=MAP *:80 localhost:%s, " \
166 "MAP *:443 localhost:%s, " \
167 "EXCLUDE localhost" % (
168 http_port, https_port),
169 "--ignore-certificate-errors",
170 "--disable-seccomp-sandbox",
171 "--disable-web-security",
172 "--reduce-security-for-testing",
173 "--allow-insecure-localhost",
174 ]
175 else: 180 else:
176 chrome_flags += [ 181 chrome_flags += [ "--single-process", ]
177 "--single-process",
178 ]
179 if args.chrome_flags: 182 if args.chrome_flags:
180 chrome_flags += args.chrome_flags.split() 183 chrome_flags += args.chrome_flags.split()
181 cmd_args = [ 184 cmd_args = [
182 "timeout", str(timeout), 185 "timeout", str(timeout),
183 args.with_chrome 186 args.with_chrome
184 ] + chrome_flags + [ site ] 187 ] + chrome_flags + [ site ]
185 print "- " * 40 188 print "- " * 40
186 print_command(cmd_args) 189 print_command(cmd_args)
187 print "- " * 40 190 print "- " * 40
188 with open(result, "wt") as f: 191 with open(result, "wt") as f:
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 for line in f: 231 for line in f:
229 line = line.strip() 232 line = line.strip()
230 if not line or line.startswith('#'): continue 233 if not line or line.startswith('#'): continue
231 sites.append({'url': line, 'timeout': args.timeout}) 234 sites.append({'url': line, 'timeout': args.timeout})
232 return sites 235 return sites
233 except IOError as e: 236 except IOError as e:
234 args.error("Cannot read from {}. {}.".format(args.sites_file, e.strerror)) 237 args.error("Cannot read from {}. {}.".format(args.sites_file, e.strerror))
235 sys.exit(1) 238 sys.exit(1)
236 239
237 240
238 def do_run(args): 241 def read_sites(args):
239 # Determine the websites to benchmark. 242 # Determine the websites to benchmark.
240 if args.sites_file: 243 if args.sites_file:
241 sites = read_sites_file(args) 244 return read_sites_file(args)
242 else: 245 return [{'url': site, 'timeout': args.timeout} for site in args.sites]
243 sites = [{'url': site, 'timeout': args.timeout} for site in args.sites] 246
247 def do_run(args):
248 sites = read_sites(args)
249 replay_server = start_replay_server(args, sites) if args.replay_wpr else None
244 # Disambiguate domains, if needed. 250 # Disambiguate domains, if needed.
245 L = [] 251 L = []
246 domains = {} 252 domains = {}
247 for item in sites: 253 for item in sites:
248 site = item['url'] 254 site = item['url']
249 domain = None 255 domain = None
250 if args.domain: 256 if args.domain:
251 domain = args.domain 257 domain = args.domain
252 elif 'domain' in item: 258 elif 'domain' in item:
253 domain = item['domain'] 259 domain = item['domain']
254 else: 260 else:
255 m = re.match(r'^(https?://)?([^/]+)(/.*)?$', site) 261 m = re.match(r'^(https?://)?([^/]+)(/.*)?$', site)
256 if not m: 262 if not m:
257 args.error("Invalid URL {}.".format(site)) 263 args.error("Invalid URL {}.".format(site))
258 continue 264 continue
259 domain = m.group(2) 265 domain = m.group(2)
260 entry = [site, domain, None, item['timeout']] 266 entry = [site, domain, None, item['timeout']]
261 if domain not in domains: 267 if domain not in domains:
262 domains[domain] = entry 268 domains[domain] = entry
263 else: 269 else:
264 if not isinstance(domains[domain], int): 270 if not isinstance(domains[domain], int):
265 domains[domain][2] = 1 271 domains[domain][2] = 1
266 domains[domain] = 1 272 domains[domain] = 1
267 domains[domain] += 1 273 domains[domain] += 1
268 entry[2] = domains[domain] 274 entry[2] = domains[domain]
269 L.append(entry) 275 L.append(entry)
270 replay_server = start_replay_server(args, sites) if args.replay_wpr else None
271 try: 276 try:
272 # Run them. 277 # Run them.
273 for site, domain, count, timeout in L: 278 for site, domain, count, timeout in L:
274 if count is not None: domain = "{}%{}".format(domain, count) 279 if count is not None: domain = "{}%{}".format(domain, count)
275 print site, domain, timeout 280 print(site, domain, timeout)
276 run_site(site, domain, args, timeout) 281 run_site(site, domain, args, timeout)
277 finally: 282 finally:
278 if replay_server: 283 if replay_server:
279 stop_replay_server(replay_server) 284 stop_replay_server(replay_server)
280 285
281 286
287 def do_run_replay_server(args):
288 sites = read_sites(args)
289 print("- " * 40)
290 print("Available URLs:")
291 for site in sites:
292 print(" "+site['url'])
293 print("- " * 40)
294 print("Launch chromium with the following commands for debugging:")
295 flags = get_chrome_flags("'--runtime-calls-stats --allow-natives-syntax'",
296 "/var/tmp/`date +%s`")
297 flags += get_chrome_replay_flags(args)
298 print(" $CHROMIUM_DIR/out/Release/chomium " + (" ".join(flags)) + " <URL>")
299 print("- " * 40)
300 replay_server = start_replay_server(args, sites)
301 try:
302 replay_server['process'].wait()
303 finally:
304 stop_replay_server(replay_server)
305
306
282 # Calculate statistics. 307 # Calculate statistics.
283 308
284 def statistics(data): 309 def statistics(data):
285 N = len(data) 310 N = len(data)
286 average = numpy.average(data) 311 average = numpy.average(data)
287 median = numpy.median(data) 312 median = numpy.median(data)
288 low = numpy.min(data) 313 low = numpy.min(data)
289 high= numpy.max(data) 314 high= numpy.max(data)
290 if N > 1: 315 if N > 1:
291 # evaluate sample variance by setting delta degrees of freedom (ddof) to 316 # evaluate sample variance by setting delta degrees of freedom (ddof) to
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 given = sum(1 for x in l if x) 553 given = sum(1 for x in l if x)
529 return given == 0 or given == len(l) 554 return given == 0 or given == len(l)
530 555
531 def main(): 556 def main():
532 parser = argparse.ArgumentParser() 557 parser = argparse.ArgumentParser()
533 subparser_adder = parser.add_subparsers(title="commands", dest="command", 558 subparser_adder = parser.add_subparsers(title="commands", dest="command",
534 metavar="<command>") 559 metavar="<command>")
535 subparsers = {} 560 subparsers = {}
536 # Command: run. 561 # Command: run.
537 subparsers["run"] = subparser_adder.add_parser( 562 subparsers["run"] = subparser_adder.add_parser(
538 "run", help="run --help") 563 "run", help="Replay websites and collect runtime stats data.")
539 subparsers["run"].set_defaults( 564 subparsers["run"].set_defaults(
540 func=do_run, error=subparsers["run"].error) 565 func=do_run, error=subparsers["run"].error)
541 subparsers["run"].add_argument( 566 subparsers["run"].add_argument(
542 "--chrome-flags", type=str, default="", 567 "--chrome-flags", type=str, default="",
543 help="specify additional chrome flags") 568 help="specify additional chrome flags")
544 subparsers["run"].add_argument( 569 subparsers["run"].add_argument(
545 "--js-flags", type=str, default="", 570 "--js-flags", type=str, default="",
546 help="specify additional V8 flags") 571 help="specify additional V8 flags")
547 subparsers["run"].add_argument( 572 subparsers["run"].add_argument(
548 "--domain", type=str, default="",
549 help="specify the output file domain name")
550 subparsers["run"].add_argument(
551 "--no-url", dest="print_url", action="store_false", default=True,
552 help="do not include url in statistics file")
553 subparsers["run"].add_argument(
554 "-n", "--repeat", type=int, metavar="<num>",
555 help="specify iterations for each website (default: once)")
556 subparsers["run"].add_argument(
557 "-k", "--refresh", type=int, metavar="<num>", default=0,
558 help="specify refreshes for each iteration (default: 0)")
559 subparsers["run"].add_argument(
560 "--replay-wpr", type=str, metavar="<path>",
561 help="use the specified web page replay (.wpr) archive")
562 subparsers["run"].add_argument(
563 "--replay-bin", type=str, metavar="<path>",
564 help="specify the replay.py script typically located in " \
565 "$CHROMIUM/src/third_party/webpagereplay/replay.py")
566 subparsers["run"].add_argument(
567 "-r", "--retries", type=int, metavar="<num>",
568 help="specify retries if website is down (default: forever)")
569 subparsers["run"].add_argument(
570 "-f", "--sites-file", type=str, metavar="<path>",
571 help="specify file containing benchmark websites")
572 subparsers["run"].add_argument(
573 "-t", "--timeout", type=int, metavar="<seconds>", default=60,
574 help="specify seconds before chrome is killed")
575 subparsers["run"].add_argument(
576 "-p", "--port-offset", type=int, metavar="<offset>", default=0,
577 help="specify the offset for the replay server's default ports")
578 subparsers["run"].add_argument(
579 "-u", "--user-data-dir", type=str, metavar="<path>", 573 "-u", "--user-data-dir", type=str, metavar="<path>",
580 help="specify user data dir (default is temporary)") 574 help="specify user data dir (default is temporary)")
581 subparsers["run"].add_argument( 575 subparsers["run"].add_argument(
582 "-c", "--with-chrome", type=str, metavar="<path>", 576 "-c", "--with-chrome", type=str, metavar="<path>",
583 default="/usr/bin/google-chrome", 577 default="/usr/bin/google-chrome",
584 help="specify chrome executable to use") 578 help="specify chrome executable to use")
585 subparsers["run"].add_argument( 579 subparsers["run"].add_argument(
586 "-l", "--log-stderr", type=str, metavar="<path>", 580 "-r", "--retries", type=int, metavar="<num>",
587 help="specify where chrome's stderr should go (default: /dev/null)") 581 help="specify retries if website is down (default: forever)")
588 subparsers["run"].add_argument( 582 subparsers["run"].add_argument(
589 "sites", type=str, metavar="<URL>", nargs="*", 583 "--no-url", dest="print_url", action="store_false", default=True,
590 help="specify benchmark website") 584 help="do not include url in statistics file")
585 subparsers["run"].add_argument(
586 "--domain", type=str, default="",
587 help="specify the output file domain name")
588 subparsers["run"].add_argument(
589 "-n", "--repeat", type=int, metavar="<num>",
590 help="specify iterations for each website (default: once)")
591
592 def add_replay_args(subparser):
593 subparser.add_argument(
594 "-k", "--refresh", type=int, metavar="<num>", default=0,
595 help="specify refreshes for each iteration (default: 0)")
596 subparser.add_argument(
597 "--replay-wpr", type=str, metavar="<path>",
598 help="use the specified web page replay (.wpr) archive")
599 subparser.add_argument(
600 "--replay-bin", type=str, metavar="<path>",
601 help="specify the replay.py script typically located in " \
602 "$CHROMIUM/src/third_party/webpagereplay/replay.py")
603 subparser.add_argument(
604 "-f", "--sites-file", type=str, metavar="<path>",
605 help="specify file containing benchmark websites")
606 subparser.add_argument(
607 "-t", "--timeout", type=int, metavar="<seconds>", default=60,
608 help="specify seconds before chrome is killed")
609 subparser.add_argument(
610 "-p", "--port-offset", type=int, metavar="<offset>", default=0,
611 help="specify the offset for the replay server's default ports")
612 subparser.add_argument(
613 "-l", "--log-stderr", type=str, metavar="<path>",
614 help="specify where chrome's stderr should go (default: /dev/null)")
615 subparser.add_argument(
616 "sites", type=str, metavar="<URL>", nargs="*",
617 help="specify benchmark website")
618 add_replay_args(subparsers["run"])
619
620 # Command: replay-server
621 subparsers["replay"] = subparser_adder.add_parser(
622 "replay", help="Run the replay server for debugging purposes")
623 subparsers["replay"].set_defaults(
624 func=do_run_replay_server, error=subparsers["replay"].error)
625 add_replay_args(subparsers["replay"])
626
591 # Command: stats. 627 # Command: stats.
592 subparsers["stats"] = subparser_adder.add_parser( 628 subparsers["stats"] = subparser_adder.add_parser(
593 "stats", help="stats --help") 629 "stats", help="Analize the results file create by the 'run' command.")
594 subparsers["stats"].set_defaults( 630 subparsers["stats"].set_defaults(
595 func=do_stats, error=subparsers["stats"].error) 631 func=do_stats, error=subparsers["stats"].error)
596 subparsers["stats"].add_argument( 632 subparsers["stats"].add_argument(
597 "-l", "--limit", type=int, metavar="<num>", default=0, 633 "-l", "--limit", type=int, metavar="<num>", default=0,
598 help="limit how many items to print (default: none)") 634 help="limit how many items to print (default: none)")
599 subparsers["stats"].add_argument( 635 subparsers["stats"].add_argument(
600 "-s", "--sort", choices=["asc", "desc"], default="asc", 636 "-s", "--sort", choices=["asc", "desc"], default="asc",
601 help="specify sorting order (default: ascending)") 637 help="specify sorting order (default: ascending)")
602 subparsers["stats"].add_argument( 638 subparsers["stats"].add_argument(
603 "-n", "--no-total", dest="totals", action="store_false", default=True, 639 "-n", "--no-total", dest="totals", action="store_false", default=True,
604 help="do not print totals") 640 help="do not print totals")
605 subparsers["stats"].add_argument( 641 subparsers["stats"].add_argument(
606 "logfiles", type=str, metavar="<logfile>", nargs="*", 642 "logfiles", type=str, metavar="<logfile>", nargs="*",
607 help="specify log files to parse") 643 help="specify log files to parse")
608 subparsers["stats"].add_argument( 644 subparsers["stats"].add_argument(
609 "--aggregate", dest="aggregate", action="store_true", default=False, 645 "--aggregate", dest="aggregate", action="store_true", default=False,
610 help="Create aggregated entries. Adds Group-* entries at the toplevel. " + 646 help="Create aggregated entries. Adds Group-* entries at the toplevel. " \
611 "Additionally creates a Total page with all entries.") 647 "Additionally creates a Total page with all entries.")
648
612 # Command: json. 649 # Command: json.
613 subparsers["json"] = subparser_adder.add_parser( 650 subparsers["json"] = subparser_adder.add_parser(
614 "json", help="json --help") 651 "json", help="Collect results file created by the 'run' command into" \
652 "a single json file.")
615 subparsers["json"].set_defaults( 653 subparsers["json"].set_defaults(
616 func=do_json, error=subparsers["json"].error) 654 func=do_json, error=subparsers["json"].error)
617 subparsers["json"].add_argument( 655 subparsers["json"].add_argument(
618 "logdirs", type=str, metavar="<logdir>", nargs="*", 656 "logdirs", type=str, metavar="<logdir>", nargs="*",
619 help="specify directories with log files to parse") 657 help="specify directories with log files to parse")
620 subparsers["json"].add_argument( 658 subparsers["json"].add_argument(
621 "--aggregate", dest="aggregate", action="store_true", default=False, 659 "--aggregate", dest="aggregate", action="store_true", default=False,
622 help="Create aggregated entries. Adds Group-* entries at the toplevel. " + 660 help="Create aggregated entries. Adds Group-* entries at the toplevel. " \
623 "Additionally creates a Total page with all entries.") 661 "Additionally creates a Total page with all entries.")
662
624 # Command: help. 663 # Command: help.
625 subparsers["help"] = subparser_adder.add_parser( 664 subparsers["help"] = subparser_adder.add_parser(
626 "help", help="help information") 665 "help", help="help information")
627 subparsers["help"].set_defaults( 666 subparsers["help"].set_defaults(
628 func=lambda args: do_help(parser, subparsers, args), 667 func=lambda args: do_help(parser, subparsers, args),
629 error=subparsers["help"].error) 668 error=subparsers["help"].error)
630 subparsers["help"].add_argument( 669 subparsers["help"].add_argument(
631 "help_cmd", type=str, metavar="<command>", nargs="?", 670 "help_cmd", type=str, metavar="<command>", nargs="?",
632 help="command for which to display help") 671 help="command for which to display help")
672
633 # Execute the command. 673 # Execute the command.
634 args = parser.parse_args() 674 args = parser.parse_args()
635 setattr(args, 'script_path', os.path.dirname(sys.argv[0])) 675 setattr(args, 'script_path', os.path.dirname(sys.argv[0]))
636 if args.command == "run" and coexist(args.sites_file, args.sites): 676 if args.command == "run" and coexist(args.sites_file, args.sites):
637 args.error("use either option --sites-file or site URLs") 677 args.error("use either option --sites-file or site URLs")
638 sys.exit(1) 678 sys.exit(1)
639 elif args.command == "run" and not coexist(args.replay_wpr, args.replay_bin): 679 elif args.command == "run" and not coexist(args.replay_wpr, args.replay_bin):
640 args.error("options --replay-wpr and --replay-bin must be used together") 680 args.error("options --replay-wpr and --replay-bin must be used together")
641 sys.exit(1) 681 sys.exit(1)
642 else: 682 else:
643 args.func(args) 683 args.func(args)
644 684
645 if __name__ == "__main__": 685 if __name__ == "__main__":
646 sys.exit(main()) 686 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698