OLD | NEW |
---|---|
1 ''' | 1 ''' |
2 Created on May 16, 2011 | 2 Created on May 16, 2011 |
3 | 3 |
4 @author: bungeman | 4 @author: bungeman |
5 ''' | 5 ''' |
6 import sys | 6 import sys |
7 import getopt | 7 import getopt |
8 import re | 8 import re |
9 import os | 9 import os |
10 import bench_util | 10 import bench_util |
11 import json | 11 import json |
12 import httplib | |
13 import urllib | |
14 import urllib2 | |
12 import xml.sax.saxutils | 15 import xml.sax.saxutils |
13 | 16 |
14 # We throw out any measurement outside this range, and log a warning. | 17 # We throw out any measurement outside this range, and log a warning. |
15 MIN_REASONABLE_TIME = 0 | 18 MIN_REASONABLE_TIME = 0 |
16 MAX_REASONABLE_TIME = 99999 | 19 MAX_REASONABLE_TIME = 99999 |
17 | 20 |
18 # Constants for prefixes in output title used in buildbot. | 21 # Constants for prefixes in output title used in buildbot. |
19 TITLE_PREAMBLE = 'Bench_Performance_for_Skia_' | 22 TITLE_PREAMBLE = 'Bench_Performance_for_Skia_' |
20 TITLE_PREAMBLE_LENGTH = len(TITLE_PREAMBLE) | 23 TITLE_PREAMBLE_LENGTH = len(TITLE_PREAMBLE) |
21 | 24 |
25 # Number of data points to send to appengine at once. | |
26 DATA_SIZE = 100 | |
borenet
2013/03/04 21:32:15
Maybe this could be more descriptive? Like DATA_P
benchen
2013/03/04 21:51:15
Done.
| |
27 | |
22 def usage(): | 28 def usage(): |
23 """Prints simple usage information.""" | 29 """Prints simple usage information.""" |
24 | 30 |
31 print '-a <url> the url to use for adding bench values to app engine app.' | |
32 print ' Example: "https://skiadash.appspot.com/add_point".' | |
rmistry
2013/03/04 21:49:35
This is going to upload to our instance of chromiu
benchen
2013/03/04 21:59:18
The SQL DB solution is through a separate script t
| |
33 print ' If not set, will skip this step.' | |
25 print '-b <bench> the bench to show.' | 34 print '-b <bench> the bench to show.' |
26 print '-c <config> the config to show (GPU, 8888, 565, etc).' | 35 print '-c <config> the config to show (GPU, 8888, 565, etc).' |
27 print '-d <dir> a directory containing bench_r<revision>_<scalar> files.' | 36 print '-d <dir> a directory containing bench_r<revision>_<scalar> files.' |
28 print '-e <file> file containing expected bench values/ranges.' | 37 print '-e <file> file containing expected bench values/ranges.' |
29 print ' Will raise exception if actual bench values are out of range.' | 38 print ' Will raise exception if actual bench values are out of range.' |
30 print ' See bench_expectations.txt for data format and examples.' | 39 print ' See bench_expectations.txt for data format and examples.' |
31 print '-f <revision>[:<revision>] the revisions to use for fitting.' | 40 print '-f <revision>[:<revision>] the revisions to use for fitting.' |
32 print ' Negative <revision> is taken as offset from most recent revision.' | 41 print ' Negative <revision> is taken as offset from most recent revision.' |
33 print '-i <time> the time to ignore (w, c, g, etc).' | 42 print '-i <time> the time to ignore (w, c, g, etc).' |
34 print ' The flag is ignored when -t is set; otherwise we plot all the' | 43 print ' The flag is ignored when -t is set; otherwise we plot all the' |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
279 max_up_slope = max(max_up_slope, min_slope) | 288 max_up_slope = max(max_up_slope, min_slope) |
280 min_down_slope = min(min_down_slope, min_slope) | 289 min_down_slope = min(min_down_slope, min_slope) |
281 | 290 |
282 return (max_up_slope, min_down_slope) | 291 return (max_up_slope, min_down_slope) |
283 | 292 |
284 def main(): | 293 def main(): |
285 """Parses command line and writes output.""" | 294 """Parses command line and writes output.""" |
286 | 295 |
287 try: | 296 try: |
288 opts, _ = getopt.getopt(sys.argv[1:] | 297 opts, _ = getopt.getopt(sys.argv[1:] |
289 , "b:c:d:e:f:i:l:m:o:r:s:t:x:y:" | 298 , "a:b:c:d:e:f:i:l:m:o:r:s:t:x:y:" |
290 , "default-setting=") | 299 , "default-setting=") |
291 except getopt.GetoptError, err: | 300 except getopt.GetoptError, err: |
292 print str(err) | 301 print str(err) |
293 usage() | 302 usage() |
294 sys.exit(2) | 303 sys.exit(2) |
295 | 304 |
296 directory = None | 305 directory = None |
297 config_of_interest = None | 306 config_of_interest = None |
298 bench_of_interest = None | 307 bench_of_interest = None |
299 time_of_interest = None | 308 time_of_interest = None |
300 time_to_ignore = None | 309 time_to_ignore = None |
301 bench_expectations = {} | 310 bench_expectations = {} |
311 appengine_url = None # used for adding data to appengine datastore | |
302 rep = None # bench representation algorithm | 312 rep = None # bench representation algorithm |
303 revision_range = '0:' | 313 revision_range = '0:' |
304 regression_range = '0:' | 314 regression_range = '0:' |
305 latest_revision = None | 315 latest_revision = None |
306 requested_height = None | 316 requested_height = None |
307 requested_width = None | 317 requested_width = None |
308 title = 'Bench graph' | 318 title = 'Bench graph' |
309 settings = {} | 319 settings = {} |
310 default_settings = {} | 320 default_settings = {} |
311 | 321 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
362 bench_platform_key not in expectations): | 372 bench_platform_key not in expectations): |
363 # Skip benches without value for latest revision. | 373 # Skip benches without value for latest revision. |
364 continue | 374 continue |
365 this_min, this_max = expectations[bench_platform_key] | 375 this_min, this_max = expectations[bench_platform_key] |
366 if this_bench_value < this_min or this_bench_value > this_max: | 376 if this_bench_value < this_min or this_bench_value > this_max: |
367 exceptions.append('Bench %s value %s out of range [%s, %s].' % | 377 exceptions.append('Bench %s value %s out of range [%s, %s].' % |
368 (bench_platform_key, this_bench_value, this_min, this_max)) | 378 (bench_platform_key, this_bench_value, this_min, this_max)) |
369 if exceptions: | 379 if exceptions: |
370 raise Exception('Bench values out of range:\n' + | 380 raise Exception('Bench values out of range:\n' + |
371 '\n'.join(exceptions)) | 381 '\n'.join(exceptions)) |
382 def write_to_appengine(lines, url, newest_revision, platform_and_alg): | |
383 """Writes latest bench values to appengine datastore.""" | |
384 data = [] | |
385 for line in lines: | |
386 bot = platform_and_alg[ : platform_and_alg.rfind('-')] | |
387 line_str = str(line)[ : str(line).find('_{')] | |
388 if line_str.find('.skp') < 0 or not line_str.endswith('_'): | |
389 # filter out non-picture and non-walltime benches | |
390 continue | |
391 bench, config = line_str.split('.skp', 1) | |
392 config = config [1 : -1] # remove leading and trailing '_' | |
borenet
2013/03/04 21:32:15
Can use config.strip('_')
benchen
2013/03/04 21:51:15
Done.
| |
393 rev, val = lines[line][-1] | |
394 if rev != newest_revision: | |
395 continue | |
396 data.append({'master': 'Skia', 'bot': bot, | |
397 'test': config + '/' + bench, | |
398 'revision': rev, 'value': val, 'error': 0}) | |
399 while data: | |
400 curr_data = data[ : DATA_SIZE] | |
401 data = data[DATA_SIZE : ] | |
402 req = urllib2.Request( | |
403 appengine_url, urllib.urlencode({'data': json.dumps(curr_data)})) | |
borenet
2013/03/04 21:32:15
Do we need a password? I think we *should* need a
benchen
2013/03/04 21:51:15
That's under development. We'll implement an IP fi
| |
404 try: | |
405 urllib2.urlopen(req) | |
406 except urllib2.HTTPError, e: | |
407 sys.stderr.write("HTTPError: %d for JSON %s\n" % (e.code, data)) | |
408 except urllib2.URLError, e: | |
409 sys.stderr.write("URLError: %s for JSON %s\n" % ( | |
410 str(e.reason), data)) | |
411 except httplib.HTTPException, e: | |
412 sys.stderr.write("HTTPException for JSON %s\n" % lines) | |
borenet
2013/03/04 21:32:15
Should we collect errors so that we can exit non-z
benchen
2013/03/04 21:51:15
Don't want this to block any other steps on the bo
| |
372 | 413 |
373 try: | 414 try: |
374 for option, value in opts: | 415 for option, value in opts: |
375 if option == "-b": | 416 if option == "-a": |
417 appengine_url = value | |
418 elif option == "-b": | |
376 bench_of_interest = value | 419 bench_of_interest = value |
377 elif option == "-c": | 420 elif option == "-c": |
378 config_of_interest = value | 421 config_of_interest = value |
379 elif option == "-d": | 422 elif option == "-d": |
380 directory = value | 423 directory = value |
381 elif option == "-e": | 424 elif option == "-e": |
382 read_expectations(bench_expectations, value) | 425 read_expectations(bench_expectations, value) |
383 elif option == "-f": | 426 elif option == "-f": |
384 regression_range = value | 427 regression_range = value |
385 elif option == "-i": | 428 elif option == "-i": |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
454 , time_of_interest | 497 , time_of_interest |
455 , time_to_ignore) | 498 , time_to_ignore) |
456 | 499 |
457 regressions = create_regressions(lines | 500 regressions = create_regressions(lines |
458 , oldest_regression | 501 , oldest_regression |
459 , newest_regression) | 502 , newest_regression) |
460 | 503 |
461 output_xhtml(lines, oldest_revision, newest_revision, ignored_revision_data_ points, | 504 output_xhtml(lines, oldest_revision, newest_revision, ignored_revision_data_ points, |
462 regressions, requested_width, requested_height, title) | 505 regressions, requested_width, requested_height, title) |
463 | 506 |
507 if appengine_url: | |
508 write_to_appengine(lines, appengine_url, newest_revision, | |
509 platform_and_alg) | |
510 | |
464 check_expectations(lines, bench_expectations, newest_revision, | 511 check_expectations(lines, bench_expectations, newest_revision, |
465 platform_and_alg) | 512 platform_and_alg) |
466 | 513 |
467 def qa(out): | 514 def qa(out): |
468 """Stringify input and quote as an xml attribute.""" | 515 """Stringify input and quote as an xml attribute.""" |
469 return xml.sax.saxutils.quoteattr(str(out)) | 516 return xml.sax.saxutils.quoteattr(str(out)) |
470 def qe(out): | 517 def qe(out): |
471 """Stringify input and escape as xml data.""" | 518 """Stringify input and escape as xml data.""" |
472 return xml.sax.saxutils.escape(str(out)) | 519 return xml.sax.saxutils.escape(str(out)) |
473 | 520 |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
955 print '<a id="rev_link" xlink:href="" target="_top">' | 1002 print '<a id="rev_link" xlink:href="" target="_top">' |
956 print '<text id="revision" x="0" y=%s style="' % qa(font_size*2) | 1003 print '<text id="revision" x="0" y=%s style="' % qa(font_size*2) |
957 print 'font-size: %s; ' % qe(font_size) | 1004 print 'font-size: %s; ' % qe(font_size) |
958 print 'stroke: #0000dd; text-decoration: underline; ' | 1005 print 'stroke: #0000dd; text-decoration: underline; ' |
959 print '"> </text></a>' | 1006 print '"> </text></a>' |
960 | 1007 |
961 print '</svg>' | 1008 print '</svg>' |
962 | 1009 |
963 if __name__ == "__main__": | 1010 if __name__ == "__main__": |
964 main() | 1011 main() |
OLD | NEW |