1ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh# tko/nightly.py code shared by various tko/*.cgi graphing scripts 24bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 34bfe361ad3ac94fcd9f95637b540e6627ac2f155mblighimport cgi, cgitb 45b380beed60f3d00df3449c6d92f599bde304d33mblighimport os, sys 55b380beed60f3d00df3449c6d92f599bde304d33mblighimport common 64bfe361ad3ac94fcd9f95637b540e6627ac2f155mblighfrom autotest_lib.tko import db, plotgraph, perf 75b380beed60f3d00df3449c6d92f599bde304d33mblighfrom autotest_lib.client.common_lib import kernel_versions 84bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 94bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 10ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef add_kernel_jobs(label_pattern): 11eab66ce582bfe05076ff096c3a044d8f0497bbcashoward cmd = "select job_idx from tko_jobs where label like '%s'" % label_pattern 12ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh nrows = perf.db_cur.execute(cmd) 13ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return [row[0] for row in perf.db_cur.fetchall()] 14ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 15ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 16ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef is_filtered_platform(platform, platforms_filter): 17ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not platforms_filter: 18ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return True 19ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for p in platforms_filter: 20ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if platform.startswith(p): 21ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return True 22ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return False 23ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 24ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 25ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef get_test_attributes(testrunx): 26eab66ce582bfe05076ff096c3a044d8f0497bbcashoward cmd = ( "select attribute, value from tko_test_attributes" 27ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh " where test_idx = %d" % testrunx ) 28ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh nrows = perf.db_cur.execute(cmd) 29ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return dict(perf.db_cur.fetchall()) 30ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 31ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 32ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef get_antag(testrunx): 33ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh attrs = get_test_attributes(testrunx) 34ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return attrs.get('antag', None) 35ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 36ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 37ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef matching_test_attributes(attrs, required_test_attributes): 38ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not required_test_attributes: 39ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return True 40ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh matches = [attrs[key] == required_test_attributes[key] 41ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for key in attrs if key in required_test_attributes] 42ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return min(matches+[True]) # True if all jointly-existing keys matched 43ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 44ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 45ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef collect_testruns(jobs, test, test_attributes, 46ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platforms_filter, by_hosts, no_antag): 47ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # get test_runs run #s for 1 test on 1 kernel and some platforms 48ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # TODO: Is jobs list short enough to use directly in 1 sql cmd? 49ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # TODO: add filtering on test series? 50ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh runs = {} # platform --> list of test runs 51ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for jobx in jobs: 52eab66ce582bfe05076ff096c3a044d8f0497bbcashoward cmd = ( "select test_idx, machine_idx from tko_tests" 53ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh " where job_idx = %s and test = %s" ) 54ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh args = [jobx, test] 55ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh nrows = perf.db_cur.execute(cmd, args) 56ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for testrunx, machx in perf.db_cur.fetchall(): 57ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platform, host = perf.machine_idx_to_platform_host(machx) 58ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if by_hosts: 59ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platform += '.'+host 60ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if ( is_filtered_platform(platform, platforms_filter) and 61ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh matching_test_attributes(get_test_attributes(testrunx), 62ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test_attributes) and 63ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh (not no_antag or get_antag(testrunx) == '') ): 64ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh runs.setdefault(platform, []).append(testrunx) 65ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return runs 66ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 67ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 68ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef all_tested_platforms(test_runs): 69ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # extract list of all tested platforms from test_runs table 70ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platforms = set() 71ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for kernel in test_runs: 72ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platforms.update(set(test_runs[kernel].keys())) 73ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return sorted(platforms) 74ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 75ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 76ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef divide_twoway_testruns(test_runs, platform): 77ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # partition all twoway runs based on name of antagonist progs 78ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh twoway_runs = {} 79ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh antagonists = set() 80ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for kernel in test_runs: 81ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh runs = {} 82ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for testrunx in test_runs[kernel].get(platform, []): 83ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh antag = get_antag(testrunx) 84ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if antag is not None: 85ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh runs.setdefault(antag, []).append(testrunx) 86ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh antagonists.add(antag) 87ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh twoway_runs[kernel] = runs 88ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return twoway_runs, sorted(antagonists) 89ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 90ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 91ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef collect_raw_scores(runs, metric): 92ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # get unscaled scores of test runs for 1 test on certain jobs 93ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # arrange them by platform type 94ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platform_scores = {} # platform --> list of perf scores 95ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for platform in runs: 96ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = perf.get_metric_at_point(runs[platform], metric) 97ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if vals: 98ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platform_scores[platform] = vals 99ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return platform_scores 100ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 101ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 102ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef collect_scaled_scores(metric, test_runs, regressed_platforms, relative): 103ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # get scores of test runs for 1 test on some kernels and platforms 104ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # optionally make relative to oldest (?) kernel on that platform 105ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # arrange by plotline (ie platform) for gnuplot 106ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh plot_data = {} # platform --> (kernel --> list of perf scores) 107ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh baseline = {} 108ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for kernel in sorted(test_runs.keys()): 109ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for platform in test_runs[kernel]: 110ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not (regressed_platforms is None or 111ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platform in regressed_platforms): 112ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh continue # delete results for uninteresting platforms 113ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = perf.get_metric_at_point(test_runs[kernel][platform], 114ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh metric) 115ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if vals: 116ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if relative: 117ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if platform not in baseline: 118ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh baseline[platform], std = plotgraph.avg_dev(vals) 119ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = [v/baseline[platform] for v in vals] 120ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh pdp = plot_data.setdefault(platform, {}) 121ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh pdp.setdefault(kernel, []).extend(vals) 122ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return plot_data 123ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 124ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 125ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef collect_twoway_scores(metric, antagonists, twoway_runs, relative): 126ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh alone = '' 127ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh plot_data = {} 128ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for kernel in twoway_runs: 129ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for test2 in antagonists: 130ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh runs = twoway_runs[kernel].get(test2, []) 131ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = perf.get_metric_at_point(runs, metric) 132ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh plot_data.setdefault(test2, {}) 133ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if vals: 134ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh plot_data[test2][kernel] = vals 135ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if relative: 136ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = plot_data[alone].get(kernel, []) 137ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if vals: 138ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh baseline = perf.average(vals) 139ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for test2 in antagonists: 140ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = plot_data[test2].get(kernel, []) 141ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = [val/baseline for val in vals] 142ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if vals: 143ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh plot_data[test2][kernel] = vals 144ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 145ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for test2 in antagonists: 146ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if kernel in plot_data[test2]: 147ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh del plot_data[test2][kernel] 148ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return plot_data 149ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 150ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 151ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef find_regressions(kernels, test_runs, metric): 152ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # A test is regressed on some platform if its latest results are 153ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # definitely lower than on the reference kernel. 154ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # Runs for the latest kernel may be underway and incomplete. 155ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # In that case, selectively use next-latest kernel. 156ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # TODO: the next-latest method hurts if latest run is not sorted last, 157ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # or if there are several dev threads 158ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ref = kernels[0] 159ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh latest = kernels[-1] 160ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh prev = kernels[-2:][0] 161ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh scores = {} # kernel --> (platform --> list of perf scores) 162ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for k in [ref, prev, latest]: 163ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if k in test_runs: 164ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh scores[k] = collect_raw_scores(test_runs[k], metric) 165ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh regressed_platforms = [] 166ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for platform in scores[ref]: 167ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if latest in scores and platform in scores[latest]: 168ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh k = latest 169ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh elif prev in scores and platform in scores[prev]: 170ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh k = prev 171ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: # perhaps due to decay of test machines 172ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh k = ref # no regression info avail 173ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ref_avg, ref_std = plotgraph.avg_dev(scores[ref][platform]) 174ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh avg, std = plotgraph.avg_dev(scores[ k ][platform]) 175ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if avg+std < ref_avg-ref_std: 176ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh regressed_platforms.append(platform) 177ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return sorted(regressed_platforms) 178ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 179ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 180ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef get_testrun_context(testrun): 181eab66ce582bfe05076ff096c3a044d8f0497bbcashoward cmd = ( 'select tko_jobs.label, tko_jobs.tag, tko_tests.subdir,' 182eab66ce582bfe05076ff096c3a044d8f0497bbcashoward ' tko_tests.started_time' 183eab66ce582bfe05076ff096c3a044d8f0497bbcashoward ' from tko_jobs, tko_tests' 184eab66ce582bfe05076ff096c3a044d8f0497bbcashoward ' where tko_jobs.job_idx = tko_tests.job_idx' 185eab66ce582bfe05076ff096c3a044d8f0497bbcashoward ' and tko_tests.test_idx = %d' % testrun ) 186ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh nrows = perf.db_cur.execute(cmd) 187ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh assert nrows == 1 188ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh row = perf.db_cur.fetchone() 189ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh row = [row[0], row[1], row[2], row[3].strftime('%m/%d/%y %H:%M')] 190ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return row 191ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 192ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 193ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef html_top(): 194ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "Content-Type: text/html\n\n<html><body>" 195ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 196ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 197ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef abs_rel_link(myurl, passthru): 198ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # link redraws current page with opposite absolute/relative choice 199ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh mod_passthru = passthru[:] 200ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if 'absolute' in passthru: 201ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh mod_passthru.remove('absolute') 202ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh opposite = 'relative' 203ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 204ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh mod_passthru.append('absolute') 205ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh opposite = 'absolute' 206ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh url = '%s?%s' % (myurl, '&'.join(mod_passthru)) 207ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return "<a href='%s'> %s </a>" % (url, opposite) 208ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 209ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 210ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef table_1_metric_all_kernels(plot_data, columns, column_argname, 211ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh kernels, kernel_dates, 212ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh myurl, filtered_passthru): 213ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # generate html table of graph's numbers 214ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # for 1 benchmark metric over all kernels (rows), 215ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # over various platforms or various antagonists etc (cols). 216ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ref_thresholds = {} 217ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<table border=1 cellpadding=3 cellspacing=0>" 218ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<tr> <td><b> Kernel </b></td>", 219ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for label in columns: 220ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not label and column_argname == 'antag': 221ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh label = 'no antag' 222ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td><b>", label.replace('_', '<br>_'), "</b></td>" 223ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</tr>" 224ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for kernel in kernels: 225ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<tr> <td><b>", kernel, "</b>", 226ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if kernel in kernel_dates: 227ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<br><small>", kernel_dates[kernel], "</small>" 228ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</td>" 229ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for col in columns: 230ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td", 231ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = plot_data[col].get(kernel, []) 232ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not vals: 233ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "> ?", 234ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 235ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh (avg, std_dev) = plotgraph.avg_dev(vals) 236ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if col not in ref_thresholds: 237ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ref_thresholds[col] = avg - std_dev 238ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if avg+std_dev < ref_thresholds[col]: 239ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "bgcolor=pink", 240ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "> ", 241ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh args = filtered_passthru[:] 242ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh perf.append_cgi_args(args, 243ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh {column_argname:col, 'kernel':kernel}) 244ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<a href='%s?%s&runs&attrs'>" % (myurl, 245ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh '&'.join(args)) 246ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<b>%.4g</b>" % avg, "</a><br>", 247ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print " <small> %dr </small>" % len(vals), 248ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print " <small> %.3g </small>" % std_dev, 249ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</td>" 250ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</tr>\n" 251ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</table>" 252ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<p> <b>Bold value:</b> Average of this metric, then <br>" 253ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "number of good test runs, then standard deviation of those runs" 254ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<br> Pink if regressed from reference kernel" 255ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 256ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 257ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef table_all_metrics_1_platform(test_runs, platform, relative): 258ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # TODO: show std dev in cells 259ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # can't mark regressions, since some metrics improve downwards 260ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh kernels = perf.sort_kernels(test_runs.keys()) 261ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh scores = {} 262ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh attrs = set() 263ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for kernel in kernels: 264ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh testruns = test_runs[kernel].get(platform, []) 265ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if testruns: 266ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh d = perf.collect_all_metrics_scores(testruns) 267ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh scores[kernel] = d 268ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh attrs.update(set(d.keys())) 269ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 270ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "No runs completed on", kernel, "<br>" 271ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh attrs = sorted(list(attrs))[:100] 272ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 273ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<table border=1 cellpadding=4 cellspacing=0>" 274ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<tr><td> Metric </td>" 275ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for kernel in kernels: 276ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh kernel = kernel.replace("_", "_<br>") 277ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td>", kernel, "</td>" 278ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</tr>" 279ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for attr in attrs: 280ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<tr>" 281ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td>", attr, "</td>" 282ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh baseline = None 283ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for kernel in kernels: 284ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td>", 285ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if kernel in scores and attr in scores[kernel]: 286ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh (avg, dev) = plotgraph.avg_dev(scores[kernel][attr]) 287ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if baseline and relative: 288ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh percent = (avg/baseline - 1)*100 289ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "%+.1f%%" % percent, 290ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 291ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh baseline = avg 292ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "%.4g" % avg, 293ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 294ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "?" 295ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</td>" 296ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</tr>" 297ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</table>" 298ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 299ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 300ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef table_variants_all_tests(plot_data, columns, colkeys, benchmarks, 301ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh myurl, filtered_passthru): 302ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # generate html table of graph's numbers 303ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # for primary metric over all benchmarks (rows), 304ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # on one platform and one kernel, 305ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # over various combos of test run attribute constraints (cols). 306ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ref_thresholds = {} 307ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<table border=1 cellpadding=3 cellspacing=0>" 308ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<tr> <td><b> Benchmark </b></td>", 309ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for col in columns: 310ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td><b>", colkeys[col].replace(',', ',<br>'), "</b></td>" 311ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</tr>" 312ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for benchmark in benchmarks: 313ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<tr> <td><b>", benchmark, "</b></td>" 314ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for col in columns: 315ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td>", 316ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = plot_data[col].get(benchmark, []) 317ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not vals: 318ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "?", 319ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 320ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh (avg, std_dev) = plotgraph.avg_dev(vals) 321ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh args = filtered_passthru[:] 322ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh perf.append_cgi_args(args, {'test':benchmark}) 323ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for keyval in colkeys[col].split(','): 324ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh key, val = keyval.split('=', 1) 325ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh perf.append_cgi_args(args, {key:val}) 326ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<a href='%s?%s&runs&attrs'>" % (myurl, 327ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh '&'.join(args)) 328ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<b>%.4g</b>" % avg, "</a><br>", 329ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print " <small> %dr </small>" % len(vals), 330ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print " <small> %.3g </small>" % std_dev, 331ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</td>" 332ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</tr>\n" 333ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</table>" 334ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<p> <b>Bold value:</b> Average of this metric, then <br>" 335ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "number of good test runs, then standard deviation of those runs" 336ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 337ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 338ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef table_testrun_details(runs, metric, tko_server, show_attrs): 339ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<table border=1 cellpadding=4 cellspacing=0>" 340ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<tr><td> %s metric </td>" % metric 341ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td> Job label </td> <td> Job tag </td> <td> Run results </td>" 342ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td> Started_time </td>" 343ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if show_attrs: 344ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td> Test attributes </td>" 345ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</tr>\n" 346ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 347ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for testrunx in runs: 348ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<tr> <td>", 349ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = perf.get_metric_at_point([testrunx], metric) 350ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for v in vals: 351ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "%.4g " % v, 352ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</td>" 353ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh row = get_testrun_context(testrunx) 354ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh row[2] = ( "<a href='//%s/results/%s/%s/results/keyval'> %s </a>" 355ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh % (tko_server, row[1], row[2], row[2]) ) 356ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for v in row: 357ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td> %s </td>" % v 358ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if show_attrs: 359ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh attrs = get_test_attributes(testrunx) 360ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<td>", 361ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for attr in sorted(attrs.keys()): 362ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if attr == "sysinfo-cmdline": continue 363ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if attr[:4] == "svs-": continue 364ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh val = attrs[attr] 365ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if len(val) > 40: 366ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh val = val[:40-3] + "..." 367ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "%s=%s " % (attr, val) 368ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</td>" 369ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</tr>\n" 370ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</table>" 371ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 372ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 373ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef overview_thumb(test, metric, myurl, passthru): 374ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh pass_ = passthru + ['test=%s' % test] 375ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if metric: 376ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh pass_ += ['metric=%s' % metric] 377ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh pass_ = '&'.join(pass_) 378ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<a href='%s?%s&table'>" % (myurl, pass_) 379ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print " <img src='%s?%s&size=450,500'> </a>" % (myurl, pass_) 380ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # embedded graphs fit 3 across on 1400x1050 laptop 381ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 382ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 383ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef graph_1_test(title, metric, plot_data, line_argname, lines, 384ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh kernel_legend, relative, size, dark=False): 385ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # generate graph image for one benchmark, showing avg and 386ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # std dev of one metric, over various kernels (X columns), 387ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # over various platforms or antagonists etc (graphed lines) 388ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh xlegend = kernel_legend 389ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ylegend = metric.capitalize() 390ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if relative: 391ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ylegend += ', Relative' 392ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ymin = 0.8 393ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 394ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ymin = None 395ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if len(lines) > 1: 396ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh keytitle = line_argname.capitalize() + ':' 397ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 398ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh keytitle = '' 399ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh graph = plotgraph.gnuplot(title, xlegend, ylegend, size=size, 400ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh xsort=perf.sort_kernels, keytitle=keytitle) 401ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for line in lines: 402ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh label = line 403ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not label and line_argname == 'antag': 404ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh label = 'no antag' 405ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh graph.add_dataset(label, plot_data[line]) 406ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh graph.plot(cgi_header=True, ymin=ymin, dark=dark) 407ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 408ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 409ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighdef graph_variants_all_tests(title, plot_data, linekeys, size, dark): 410ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # generate graph image showing all benchmarks 411ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # on one platform and one kernel, 412ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # over various combos of test run attribute constraints (lines). 413ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh xlegend = "Benchmark" 414ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ylegend = "Relative Perf" 415ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh graph = plotgraph.gnuplot(title, xlegend, ylegend, size=size) 416ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for i in linekeys: 417ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh graph.add_dataset(linekeys[i], plot_data[i]) 418ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh graph.plot(cgi_header=True, dark=dark, ymin=0.8) 419ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 420ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 421ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmblighclass generate_views(object): 422ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 423ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 424ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def __init__(self, kernel_legend, benchmarks, test_group, 425ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh site_benchmark_metrics, tko_server, 426ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh jobs_selector, no_antag): 427ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.kernel_legend = kernel_legend 428ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.benchmarks = benchmarks 429ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.test_group = test_group 430ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.tko_server = tko_server 431ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.jobs_selector = jobs_selector 432ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.no_antag = no_antag 433ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 434ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh cgitb.enable() 435ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test, antagonists = self.parse_most_cgi_args() 436ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 437ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh perf.init(tko_server=tko_server) 438ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for b in site_benchmark_metrics: 439ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh perf.add_benchmark_main_metric(b, site_benchmark_metrics[b]) 440ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 441ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.test_runs = {} # kernel --> (platform --> list of test runs) 442ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.job_table = {} # kernel id --> list of job idxs 443ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.kernel_dates = {} # kernel id --> date of nightly test 444ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 445ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vary = self.cgiform.getlist('vary') 446ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if vary: 447ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platform = self.platforms_filter[0] 448ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.analyze_variants_all_tests_1_platform(platform, vary) 449ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh elif test: 450ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.analyze_1_test(test, antagonists) 451ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 452ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.overview_page_all_tests(self.benchmarks, antagonists) 453ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 454ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 455ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def collect_all_testruns(self, trimmed_kernels, test): 456ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # get test_runs run #s for 1 test on some kernels and platforms 4574bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh for kernel in trimmed_kernels: 458ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh runs = collect_testruns(self.job_table[kernel], test, 459ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.test_attributes, self.platforms_filter, 460ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 'by_hosts' in self.toggles, self.no_antag) 4614bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh if runs: 462ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.test_runs[kernel] = runs 4634bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 4644bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 465ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def table_for_graph_1_test(self, title, metric, plot_data, 466ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh column_argname, columns, filtered_passthru): 467ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # generate detailed html page with 1 graph and corresp numbers 468ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # for 1 benchmark metric over all kernels (rows), 469ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # over various platforms or various antagonists etc (cols). 470ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh html_top() 471ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print '<h3> %s </h3>' % title 472ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print ('%s, machine group %s on //%s server <br>' % 473ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh (self.kernel_legend, self.test_group, self.tko_server)) 474ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if self.test_tag: 475ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print '%s test script series <br>' % self.test_tag[1:] 476ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 477ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<img src='%s?%s'>" % (self.myurl, '&'.join(self.passthru)) 478ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 479ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh link = abs_rel_link(self.myurl, self.passthru+['table']) 480ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<p><p> <h4> Redraw this with %s performance? </h4>" % link 4814bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 482ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh heading = "%s, %s metric" % (title, metric) 483ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if self.relative: 484ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh heading += ", relative" 4854bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh print "<p><p> <h3> %s: </h3>" % heading 486ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh table_1_metric_all_kernels(plot_data, columns, column_argname, 487ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.kernels, self.kernel_dates, 488ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.myurl, filtered_passthru) 489ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</body></html>" 4904bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 491ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 492ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def graph_1_test_all_platforms(self, test, metric, platforms, plot_data): 493ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # generate graph image for one benchmark 494ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh title = test.capitalize() 495ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if 'regress' in self.toggles: 496ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh title += ' Regressions' 497ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if 'table' in self.cgiform: 498ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.table_for_graph_1_test(title, metric, plot_data, 499ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 'platforms', platforms, 500ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh filtered_passthru=self.passthru) 501ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 502ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh graph_1_test(title, metric, plot_data, 'platforms', platforms, 503ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.kernel_legend, self.relative, 504ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.size, 'dark' in self.toggles) 505ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 506ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 507ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def testrun_details(self, title, runs, metric): 508ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh html_top() 509ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print '<h3> %s </h3>' % title 510ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print ('%s, machine group %s on //%s server' % 511ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh (self.kernel_legend, self.test_group, self.tko_server)) 512ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if self.test_tag: 513ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print '<br> %s test script series' % self.test_tag[1:] 514ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print '<p>' 515ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh table_testrun_details(runs, metric, 516ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.tko_server, 'attrs' in self.cgiform) 5174bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh print "</body></html>" 5184bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 5194bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 520ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def testrun_details_for_1_test_kernel_platform(self, test, 521ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh metric, platform): 522ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh default_kernel = min(self.test_runs.keys()) 523ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh kernel = self.cgiform.getvalue('kernel', default_kernel) 524ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh title = '%s on %s using %s' % (test.capitalize(), platform, kernel) 525ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh runs = self.test_runs[kernel].get(platform, []) 526ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.testrun_details(title, runs, metric) 5274bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 528ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 529ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def analyze_1_metric_all_platforms(self, test, metric): 530ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if 'regress' in self.toggles: 531ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh regressed_platforms = find_regressions(self.kernels, self.test_runs, 532ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh metric) 533ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 534ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh regressed_platforms = None 535ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh plot_data = collect_scaled_scores(metric, self.test_runs, 536ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh regressed_platforms, self.relative) 537ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platforms = sorted(plot_data.keys()) 538ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not plot_data: 539ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh html_top() 540ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print 'No runs' 541ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh elif 'runs' in self.cgiform: 542ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.testrun_details_for_1_test_kernel_platform(test, metric, 543ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platforms[0]) 544ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 545ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.graph_1_test_all_platforms(test, metric, platforms, plot_data) 546ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 547ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 548ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def analyze_all_metrics_1_platform(self, test, platform): 549ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # TODO: show #runs in header 550ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh html_top() 551ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh heading = "%s %s:  %s" % (self.test_group, self.kernel_legend, 552ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test.capitalize()) 553ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<h2> %s </h2>" % heading 554ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "platform=%s <br>" % platform 555ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for attr in self.test_attributes: 556ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "%s=%s " % (attr, self.test_attributes[attr]) 557ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<p>" 558ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh table_all_metrics_1_platform(self.test_runs, platform, self.relative) 5594bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh print "</body></html>" 5604bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 5614bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 562ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def table_for_variants_all_tests(self, title, plot_data, colkeys, columns, 563ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh filtered_passthru, test_tag): 564ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # generate detailed html page with 1 graph and corresp numbers 565ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # for primary metric over all benchmarks (rows), 566ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # on one platform and one kernel, 567ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # over various combos of test run attribute constraints (cols). 568ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh html_top() 569ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print '<h3> %s </h3>' % title 570ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print ('%s, machine group %s on //%s server <br>' % 571ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh (self.kernel_legend, self.test_group, self.tko_server)) 572ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if test_tag: 573ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print '%s test script series <br>' % test_tag[1:] 574ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 575ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh varies = ['vary='+colkeys[col] for col in columns] 576ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<img src='%s?%s'>" % (self.myurl, '&'.join(self.passthru+varies)) 577ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 578ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<p><p> <h3> %s: </h3>" % title 579ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh table_variants_all_tests(plot_data, columns, colkeys, self.benchmarks, 580ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.myurl, filtered_passthru) 581ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "</body></html>" 582ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 583ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 584ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def analyze_variants_all_tests_1_platform(self, platform, vary): 585ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # generate one graph image for results of all benchmarks 586ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # on one platform and one kernel, comparing effects of 587ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # two or more combos of kernel options (test run attributes) 588ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # (numa_fake,stale_page,kswapd_merge,sched_idle, etc) 589ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh kernel = self.cgiform.getvalue('kernel', 'some_kernel') 590ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.passthru.append('kernel=%s' % kernel) 591ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 592ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # two or more vary_groups, one for each plotted line, 593ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # each group begins with vary= and ends with next & 594ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # each group has comma-separated list of test attribute key=val pairs 595ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # eg vary=keyval1,keyval2&vary=keyval3,keyval4 596ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vary_groups = [dict(pair.split('=',1) for pair 597ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh in vary_group.split(',')) 598ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for vary_group in vary] 599ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 600ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test = self.benchmarks[0] # pick any test in all jobs 601ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh kernels, test_tag = self.jobs_selector(test, self.job_table, 602ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.kernel_dates) 603ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 604ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh linekeys = {} 605ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh plot_data = {} 606ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh baselines = {} 607ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for i, vary_group in enumerate(vary_groups): 608ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh group_attributes = self.test_attributes.copy() 609ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh group_attributes.update(vary_group) 610ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh linekey = ','.join('%s=%s' % (attr, vary_group[attr]) 611ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for attr in vary_group) 612ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh linekeys[i] = linekey 613ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh data = {} 614ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for benchmark in self.benchmarks: 615ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh metric = perf.benchmark_main_metric(benchmark) 616ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh runs = collect_testruns(self.job_table[kernel], 617ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh benchmark+test_tag, 618ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh group_attributes, 619ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.platforms_filter, 620ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 'by_hosts' in self.toggles, 621ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.no_antag) 622ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = [] 623ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for testrunx in runs[platform]: 624ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals += perf.get_metric_at_point([testrunx], metric) 625ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if vals: 626ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if benchmark not in baselines: 627ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh baselines[benchmark], stddev = plotgraph.avg_dev(vals) 628ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh vals = [val/baselines[benchmark] for val in vals] 629ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh data[benchmark] = vals 630ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh plot_data[i] = data 631ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 632ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh title = "%s on %s" % (kernel, platform) 633ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh for attr in self.test_attributes: 634ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh title += ', %s=%s' % (attr, self.test_attributes[attr]) 635ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if 'table' in self.cgiform: 636ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.table_for_variants_all_tests(title, plot_data, linekeys, 637ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh range(len(linekeys)), 638ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh filtered_passthru=self.passthru, 639ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test_tag=test_tag) 640ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 641ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh graph_variants_all_tests(title, plot_data, linekeys, 642ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.size, 'dark' in self.toggles) 643ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 644ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 645ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def graph_twoway_antagonists_1_test_1_platform( 646ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self, test, metric, platform, antagonists, twoway_runs): 647ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # generate graph of one benchmark's performance paired with 648ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # various antagonists, with one plotted line per antagonist, 649ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # over most kernels (X axis), all on one machine type 650ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # performance is relative to the no-antag baseline case 651ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh plot_data = collect_twoway_scores(metric, antagonists, 652ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh twoway_runs, self.relative) 653ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh title = "%s vs. an Antagonist on %s:" % (test.capitalize(), platform) 654ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if 'table' in self.cgiform: 655ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh filtered_passthru = [arg for arg in self.passthru 656ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not arg.startswith('antag=')] 657ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.table_for_graph_1_test(title, metric, plot_data, 658ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 'antag', antagonists, 659ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh filtered_passthru=filtered_passthru) 660ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 661ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh graph_1_test(title, metric, plot_data, 'antag', antagonists, 662ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.kernel_legend, self.relative, 663ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.size, 'dark' in self.toggles) 664ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 665ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 666ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def testrun_details_for_twoway_test(self, test, metric, platform, 667ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh antagonist, twoway_runs): 668ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh default_kernel = min(twoway_runs.keys()) 669ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh kernel = self.cgiform.getvalue('kernel', default_kernel) 670ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh title = '%s vs. Antagonist %s on %s using %s' % ( 671ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test.capitalize(), antagonist.capitalize(), platform, kernel) 672ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh runs = twoway_runs[kernel].get(antagonist, []) 673ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.testrun_details(title, runs, metric) 674ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 675ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 676ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def analyze_twoway_antagonists_1_test_1_platform( 677ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self, test, metric, platform, antagonists): 678ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh twoway_runs, all_antagonists = divide_twoway_testruns(self.test_runs, 679ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platform) 680ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if antagonists == ['*']: 681ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh antagonists = all_antagonists 682ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not twoway_runs: 683ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh html_top() 684ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print 'No runs' 685ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh elif 'runs' in self.cgiform: 686ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.testrun_details_for_twoway_test( 687ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test, metric, platform, antagonists[0], twoway_runs) 688ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 689ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.graph_twoway_antagonists_1_test_1_platform( 690ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test, metric, platform, antagonists, twoway_runs) 691ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 6924bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 693ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def get_twoway_default_platform(self): 694ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if self.platforms_filter: 695ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return self.platforms_filter[0] 696ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test = 'unixbench' 697ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh kernels, test_tag = self.jobs_selector(test, self.job_table, 698ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.kernel_dates) 699ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.collect_all_testruns(kernels, test+test_tag) 700ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return all_tested_platforms(self.test_runs)[0] 7014bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 702ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 703ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def overview_page_all_tests(self, benchmarks, antagonists): 7044bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh # generate overview html page with small graphs for each benchmark 7054bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh # linking to detailed html page for that benchmark 7064bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh # recursively link to this same cgi to generate each image 707ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh html_top() 708ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if antagonists is not None: 709ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh heading = ('Twoway Container Isolation using %s on %s' % 710ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh (self.kernel_legend, self.get_twoway_default_platform())) 711ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 712ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh heading = '%s, %s Benchmarks' % (self.kernel_legend, 713ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.test_group) 714ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if 'regress' in self.toggles: 7154bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh heading += ", Regressions Only" 716ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<h3> %s </h3>" % heading 7174bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh for test in benchmarks: 718ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh overview_thumb(test, '', self.myurl, self.passthru) 7199b2cd046f49d801d7889707e3a7250ac545ac3ebmbligh if test == 'unixbench': 720ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh overview_thumb('unixbench', 'Process_creation', 721ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.myurl, self.passthru) 722ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 723ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh link = abs_rel_link(self.myurl, self.passthru) 724ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh print "<p><p> <h4> Redraw this with %s performance? </h4>" % link 7254bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh print "</body></html>" 7264bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 7274bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh 728ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def analyze_1_test(self, test, antagonists): 729ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.passthru.append('test=%s' % test) 730ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh metric = self.cgiform.getvalue('metric', '') 7314bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh if metric: 732ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.passthru.append('metric=%s' % metric) 7334bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh else: 7344bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh metric = perf.benchmark_main_metric(test) 7354bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh assert metric, "no default metric for test %s" % test 736ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.kernels, self.test_tag = self.jobs_selector(test, self.job_table, 737ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.kernel_dates) 738ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.collect_all_testruns(self.kernels, test+self.test_tag) 739ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if not self.platforms_filter and (metric == '*' or 740ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh antagonists is not None): 741ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # choose default platform 742ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.platforms_filter = all_tested_platforms(self.test_runs)[0:1] 743ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.passthru.append('platforms=%s' % 744ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh ','.join(self.platforms_filter)) 745ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if antagonists is not None: 746ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh antagonists = antagonists.split(',') 747ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if len(antagonists) == 1 and antagonists != ['*']: 748ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.relative = False 749ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.analyze_twoway_antagonists_1_test_1_platform( 750ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test, metric, self.platforms_filter[0], antagonists) 751ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh elif metric == '*': 752ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platform = self.platforms_filter[0] 753ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.analyze_all_metrics_1_platform(test, platform) 7544bfe361ad3ac94fcd9f95637b540e6627ac2f155mbligh else: 755ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.analyze_1_metric_all_platforms(test, metric) 756ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 757ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh 758ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh def parse_most_cgi_args(self): 759ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.myurl = os.path.basename(sys.argv[0]) 760ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.cgiform = cgi.FieldStorage(keep_blank_values=True) 761ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.size = self.cgiform.getvalue('size', '1200,850') 762ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh all_toggles = set(('absolute', 'regress', 'dark', 'by_hosts')) 763ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.toggles = set(tog for tog in all_toggles if tog in self.cgiform) 764ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh platforms = self.cgiform.getvalue('platforms', '') 765ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if '.' in platforms: 766ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.toggles.add('by_hosts') 767ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.passthru = list(self.toggles) 768ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.relative = 'absolute' not in self.toggles 769ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if platforms: 770ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.passthru.append('platforms=%s' % platforms) 771ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.platforms_filter = platforms.split(',') 772ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 773ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.platforms_filter = [] 774ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.test_attributes = perf.parse_test_attr_args(self.cgiform) 775ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh perf.append_cgi_args(self.passthru, self.test_attributes) 776ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh test = self.cgiform.getvalue('test', '') 777ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh if 'antag' in self.cgiform: 778ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh antagonists = ','.join(self.cgiform.getlist('antag')) 779ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # antag=* 780ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # or antag=test1,test2,test3,... 781ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # or antag=test1&antag=test2&... 782ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh # testN is empty for solo case of no antagonist 783ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh self.passthru.append('antag=%s' % antagonists) 784ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh else: 785ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh antagonists = None # not same as '' 786ef8fd9cf99d6a161fbbcf1a7de6475e74e3ddf3dmbligh return test, antagonists 787