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

Side by Side Diff: tools/callstats.py

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