1*dbb99499SAndroid Build Coastguard Worker# type: ignore 2*dbb99499SAndroid Build Coastguard Worker 3*dbb99499SAndroid Build Coastguard Worker""" 4*dbb99499SAndroid Build Coastguard Workerreport.py - Utilities for reporting statistics about benchmark results 5*dbb99499SAndroid Build Coastguard Worker""" 6*dbb99499SAndroid Build Coastguard Worker 7*dbb99499SAndroid Build Coastguard Workerimport copy 8*dbb99499SAndroid Build Coastguard Workerimport os 9*dbb99499SAndroid Build Coastguard Workerimport random 10*dbb99499SAndroid Build Coastguard Workerimport re 11*dbb99499SAndroid Build Coastguard Workerimport unittest 12*dbb99499SAndroid Build Coastguard Worker 13*dbb99499SAndroid Build Coastguard Workerfrom numpy import array 14*dbb99499SAndroid Build Coastguard Workerfrom scipy.stats import gmean, mannwhitneyu 15*dbb99499SAndroid Build Coastguard Worker 16*dbb99499SAndroid Build Coastguard Worker 17*dbb99499SAndroid Build Coastguard Workerclass BenchmarkColor(object): 18*dbb99499SAndroid Build Coastguard Worker def __init__(self, name, code): 19*dbb99499SAndroid Build Coastguard Worker self.name = name 20*dbb99499SAndroid Build Coastguard Worker self.code = code 21*dbb99499SAndroid Build Coastguard Worker 22*dbb99499SAndroid Build Coastguard Worker def __repr__(self): 23*dbb99499SAndroid Build Coastguard Worker return "%s%r" % (self.__class__.__name__, (self.name, self.code)) 24*dbb99499SAndroid Build Coastguard Worker 25*dbb99499SAndroid Build Coastguard Worker def __format__(self, format): 26*dbb99499SAndroid Build Coastguard Worker return self.code 27*dbb99499SAndroid Build Coastguard Worker 28*dbb99499SAndroid Build Coastguard Worker 29*dbb99499SAndroid Build Coastguard Worker# Benchmark Colors Enumeration 30*dbb99499SAndroid Build Coastguard WorkerBC_NONE = BenchmarkColor("NONE", "") 31*dbb99499SAndroid Build Coastguard WorkerBC_MAGENTA = BenchmarkColor("MAGENTA", "\033[95m") 32*dbb99499SAndroid Build Coastguard WorkerBC_CYAN = BenchmarkColor("CYAN", "\033[96m") 33*dbb99499SAndroid Build Coastguard WorkerBC_OKBLUE = BenchmarkColor("OKBLUE", "\033[94m") 34*dbb99499SAndroid Build Coastguard WorkerBC_OKGREEN = BenchmarkColor("OKGREEN", "\033[32m") 35*dbb99499SAndroid Build Coastguard WorkerBC_HEADER = BenchmarkColor("HEADER", "\033[92m") 36*dbb99499SAndroid Build Coastguard WorkerBC_WARNING = BenchmarkColor("WARNING", "\033[93m") 37*dbb99499SAndroid Build Coastguard WorkerBC_WHITE = BenchmarkColor("WHITE", "\033[97m") 38*dbb99499SAndroid Build Coastguard WorkerBC_FAIL = BenchmarkColor("FAIL", "\033[91m") 39*dbb99499SAndroid Build Coastguard WorkerBC_ENDC = BenchmarkColor("ENDC", "\033[0m") 40*dbb99499SAndroid Build Coastguard WorkerBC_BOLD = BenchmarkColor("BOLD", "\033[1m") 41*dbb99499SAndroid Build Coastguard WorkerBC_UNDERLINE = BenchmarkColor("UNDERLINE", "\033[4m") 42*dbb99499SAndroid Build Coastguard Worker 43*dbb99499SAndroid Build Coastguard WorkerUTEST_MIN_REPETITIONS = 2 44*dbb99499SAndroid Build Coastguard WorkerUTEST_OPTIMAL_REPETITIONS = 9 # Lowest reasonable number, More is better. 45*dbb99499SAndroid Build Coastguard WorkerUTEST_COL_NAME = "_pvalue" 46*dbb99499SAndroid Build Coastguard Worker 47*dbb99499SAndroid Build Coastguard Worker_TIME_UNIT_TO_SECONDS_MULTIPLIER = { 48*dbb99499SAndroid Build Coastguard Worker "s": 1.0, 49*dbb99499SAndroid Build Coastguard Worker "ms": 1e-3, 50*dbb99499SAndroid Build Coastguard Worker "us": 1e-6, 51*dbb99499SAndroid Build Coastguard Worker "ns": 1e-9, 52*dbb99499SAndroid Build Coastguard Worker} 53*dbb99499SAndroid Build Coastguard Worker 54*dbb99499SAndroid Build Coastguard Worker 55*dbb99499SAndroid Build Coastguard Workerdef color_format(use_color, fmt_str, *args, **kwargs): 56*dbb99499SAndroid Build Coastguard Worker """ 57*dbb99499SAndroid Build Coastguard Worker Return the result of 'fmt_str.format(*args, **kwargs)' after transforming 58*dbb99499SAndroid Build Coastguard Worker 'args' and 'kwargs' according to the value of 'use_color'. If 'use_color' 59*dbb99499SAndroid Build Coastguard Worker is False then all color codes in 'args' and 'kwargs' are replaced with 60*dbb99499SAndroid Build Coastguard Worker the empty string. 61*dbb99499SAndroid Build Coastguard Worker """ 62*dbb99499SAndroid Build Coastguard Worker assert use_color is True or use_color is False 63*dbb99499SAndroid Build Coastguard Worker if not use_color: 64*dbb99499SAndroid Build Coastguard Worker args = [ 65*dbb99499SAndroid Build Coastguard Worker arg if not isinstance(arg, BenchmarkColor) else BC_NONE 66*dbb99499SAndroid Build Coastguard Worker for arg in args 67*dbb99499SAndroid Build Coastguard Worker ] 68*dbb99499SAndroid Build Coastguard Worker kwargs = { 69*dbb99499SAndroid Build Coastguard Worker key: arg if not isinstance(arg, BenchmarkColor) else BC_NONE 70*dbb99499SAndroid Build Coastguard Worker for key, arg in kwargs.items() 71*dbb99499SAndroid Build Coastguard Worker } 72*dbb99499SAndroid Build Coastguard Worker return fmt_str.format(*args, **kwargs) 73*dbb99499SAndroid Build Coastguard Worker 74*dbb99499SAndroid Build Coastguard Worker 75*dbb99499SAndroid Build Coastguard Workerdef find_longest_name(benchmark_list): 76*dbb99499SAndroid Build Coastguard Worker """ 77*dbb99499SAndroid Build Coastguard Worker Return the length of the longest benchmark name in a given list of 78*dbb99499SAndroid Build Coastguard Worker benchmark JSON objects 79*dbb99499SAndroid Build Coastguard Worker """ 80*dbb99499SAndroid Build Coastguard Worker longest_name = 1 81*dbb99499SAndroid Build Coastguard Worker for bc in benchmark_list: 82*dbb99499SAndroid Build Coastguard Worker if len(bc["name"]) > longest_name: 83*dbb99499SAndroid Build Coastguard Worker longest_name = len(bc["name"]) 84*dbb99499SAndroid Build Coastguard Worker return longest_name 85*dbb99499SAndroid Build Coastguard Worker 86*dbb99499SAndroid Build Coastguard Worker 87*dbb99499SAndroid Build Coastguard Workerdef calculate_change(old_val, new_val): 88*dbb99499SAndroid Build Coastguard Worker """ 89*dbb99499SAndroid Build Coastguard Worker Return a float representing the decimal change between old_val and new_val. 90*dbb99499SAndroid Build Coastguard Worker """ 91*dbb99499SAndroid Build Coastguard Worker if old_val == 0 and new_val == 0: 92*dbb99499SAndroid Build Coastguard Worker return 0.0 93*dbb99499SAndroid Build Coastguard Worker if old_val == 0: 94*dbb99499SAndroid Build Coastguard Worker return float(new_val - old_val) / (float(old_val + new_val) / 2) 95*dbb99499SAndroid Build Coastguard Worker return float(new_val - old_val) / abs(old_val) 96*dbb99499SAndroid Build Coastguard Worker 97*dbb99499SAndroid Build Coastguard Worker 98*dbb99499SAndroid Build Coastguard Workerdef filter_benchmark(json_orig, family, replacement=""): 99*dbb99499SAndroid Build Coastguard Worker """ 100*dbb99499SAndroid Build Coastguard Worker Apply a filter to the json, and only leave the 'family' of benchmarks. 101*dbb99499SAndroid Build Coastguard Worker """ 102*dbb99499SAndroid Build Coastguard Worker regex = re.compile(family) 103*dbb99499SAndroid Build Coastguard Worker filtered = {} 104*dbb99499SAndroid Build Coastguard Worker filtered["benchmarks"] = [] 105*dbb99499SAndroid Build Coastguard Worker for be in json_orig["benchmarks"]: 106*dbb99499SAndroid Build Coastguard Worker if not regex.search(be["name"]): 107*dbb99499SAndroid Build Coastguard Worker continue 108*dbb99499SAndroid Build Coastguard Worker filteredbench = copy.deepcopy(be) # Do NOT modify the old name! 109*dbb99499SAndroid Build Coastguard Worker filteredbench["name"] = regex.sub(replacement, filteredbench["name"]) 110*dbb99499SAndroid Build Coastguard Worker filtered["benchmarks"].append(filteredbench) 111*dbb99499SAndroid Build Coastguard Worker return filtered 112*dbb99499SAndroid Build Coastguard Worker 113*dbb99499SAndroid Build Coastguard Worker 114*dbb99499SAndroid Build Coastguard Workerdef get_unique_benchmark_names(json): 115*dbb99499SAndroid Build Coastguard Worker """ 116*dbb99499SAndroid Build Coastguard Worker While *keeping* the order, give all the unique 'names' used for benchmarks. 117*dbb99499SAndroid Build Coastguard Worker """ 118*dbb99499SAndroid Build Coastguard Worker seen = set() 119*dbb99499SAndroid Build Coastguard Worker uniqued = [ 120*dbb99499SAndroid Build Coastguard Worker x["name"] 121*dbb99499SAndroid Build Coastguard Worker for x in json["benchmarks"] 122*dbb99499SAndroid Build Coastguard Worker if x["name"] not in seen and (seen.add(x["name"]) or True) 123*dbb99499SAndroid Build Coastguard Worker ] 124*dbb99499SAndroid Build Coastguard Worker return uniqued 125*dbb99499SAndroid Build Coastguard Worker 126*dbb99499SAndroid Build Coastguard Worker 127*dbb99499SAndroid Build Coastguard Workerdef intersect(list1, list2): 128*dbb99499SAndroid Build Coastguard Worker """ 129*dbb99499SAndroid Build Coastguard Worker Given two lists, get a new list consisting of the elements only contained 130*dbb99499SAndroid Build Coastguard Worker in *both of the input lists*, while preserving the ordering. 131*dbb99499SAndroid Build Coastguard Worker """ 132*dbb99499SAndroid Build Coastguard Worker return [x for x in list1 if x in list2] 133*dbb99499SAndroid Build Coastguard Worker 134*dbb99499SAndroid Build Coastguard Worker 135*dbb99499SAndroid Build Coastguard Workerdef is_potentially_comparable_benchmark(x): 136*dbb99499SAndroid Build Coastguard Worker return "time_unit" in x and "real_time" in x and "cpu_time" in x 137*dbb99499SAndroid Build Coastguard Worker 138*dbb99499SAndroid Build Coastguard Worker 139*dbb99499SAndroid Build Coastguard Workerdef partition_benchmarks(json1, json2): 140*dbb99499SAndroid Build Coastguard Worker """ 141*dbb99499SAndroid Build Coastguard Worker While preserving the ordering, find benchmarks with the same names in 142*dbb99499SAndroid Build Coastguard Worker both of the inputs, and group them. 143*dbb99499SAndroid Build Coastguard Worker (i.e. partition/filter into groups with common name) 144*dbb99499SAndroid Build Coastguard Worker """ 145*dbb99499SAndroid Build Coastguard Worker json1_unique_names = get_unique_benchmark_names(json1) 146*dbb99499SAndroid Build Coastguard Worker json2_unique_names = get_unique_benchmark_names(json2) 147*dbb99499SAndroid Build Coastguard Worker names = intersect(json1_unique_names, json2_unique_names) 148*dbb99499SAndroid Build Coastguard Worker partitions = [] 149*dbb99499SAndroid Build Coastguard Worker for name in names: 150*dbb99499SAndroid Build Coastguard Worker time_unit = None 151*dbb99499SAndroid Build Coastguard Worker # Pick the time unit from the first entry of the lhs benchmark. 152*dbb99499SAndroid Build Coastguard Worker # We should be careful not to crash with unexpected input. 153*dbb99499SAndroid Build Coastguard Worker for x in json1["benchmarks"]: 154*dbb99499SAndroid Build Coastguard Worker if x["name"] == name and is_potentially_comparable_benchmark(x): 155*dbb99499SAndroid Build Coastguard Worker time_unit = x["time_unit"] 156*dbb99499SAndroid Build Coastguard Worker break 157*dbb99499SAndroid Build Coastguard Worker if time_unit is None: 158*dbb99499SAndroid Build Coastguard Worker continue 159*dbb99499SAndroid Build Coastguard Worker # Filter by name and time unit. 160*dbb99499SAndroid Build Coastguard Worker # All the repetitions are assumed to be comparable. 161*dbb99499SAndroid Build Coastguard Worker lhs = [ 162*dbb99499SAndroid Build Coastguard Worker x 163*dbb99499SAndroid Build Coastguard Worker for x in json1["benchmarks"] 164*dbb99499SAndroid Build Coastguard Worker if x["name"] == name and x["time_unit"] == time_unit 165*dbb99499SAndroid Build Coastguard Worker ] 166*dbb99499SAndroid Build Coastguard Worker rhs = [ 167*dbb99499SAndroid Build Coastguard Worker x 168*dbb99499SAndroid Build Coastguard Worker for x in json2["benchmarks"] 169*dbb99499SAndroid Build Coastguard Worker if x["name"] == name and x["time_unit"] == time_unit 170*dbb99499SAndroid Build Coastguard Worker ] 171*dbb99499SAndroid Build Coastguard Worker partitions.append([lhs, rhs]) 172*dbb99499SAndroid Build Coastguard Worker return partitions 173*dbb99499SAndroid Build Coastguard Worker 174*dbb99499SAndroid Build Coastguard Worker 175*dbb99499SAndroid Build Coastguard Workerdef get_timedelta_field_as_seconds(benchmark, field_name): 176*dbb99499SAndroid Build Coastguard Worker """ 177*dbb99499SAndroid Build Coastguard Worker Get value of field_name field of benchmark, which is time with time unit 178*dbb99499SAndroid Build Coastguard Worker time_unit, as time in seconds. 179*dbb99499SAndroid Build Coastguard Worker """ 180*dbb99499SAndroid Build Coastguard Worker timedelta = benchmark[field_name] 181*dbb99499SAndroid Build Coastguard Worker time_unit = benchmark.get("time_unit", "s") 182*dbb99499SAndroid Build Coastguard Worker return timedelta * _TIME_UNIT_TO_SECONDS_MULTIPLIER.get(time_unit) 183*dbb99499SAndroid Build Coastguard Worker 184*dbb99499SAndroid Build Coastguard Worker 185*dbb99499SAndroid Build Coastguard Workerdef calculate_geomean(json): 186*dbb99499SAndroid Build Coastguard Worker """ 187*dbb99499SAndroid Build Coastguard Worker Extract all real/cpu times from all the benchmarks as seconds, 188*dbb99499SAndroid Build Coastguard Worker and calculate their geomean. 189*dbb99499SAndroid Build Coastguard Worker """ 190*dbb99499SAndroid Build Coastguard Worker times = [] 191*dbb99499SAndroid Build Coastguard Worker for benchmark in json["benchmarks"]: 192*dbb99499SAndroid Build Coastguard Worker if "run_type" in benchmark and benchmark["run_type"] == "aggregate": 193*dbb99499SAndroid Build Coastguard Worker continue 194*dbb99499SAndroid Build Coastguard Worker times.append( 195*dbb99499SAndroid Build Coastguard Worker [ 196*dbb99499SAndroid Build Coastguard Worker get_timedelta_field_as_seconds(benchmark, "real_time"), 197*dbb99499SAndroid Build Coastguard Worker get_timedelta_field_as_seconds(benchmark, "cpu_time"), 198*dbb99499SAndroid Build Coastguard Worker ] 199*dbb99499SAndroid Build Coastguard Worker ) 200*dbb99499SAndroid Build Coastguard Worker return gmean(times) if times else array([]) 201*dbb99499SAndroid Build Coastguard Worker 202*dbb99499SAndroid Build Coastguard Worker 203*dbb99499SAndroid Build Coastguard Workerdef extract_field(partition, field_name): 204*dbb99499SAndroid Build Coastguard Worker # The count of elements may be different. We want *all* of them. 205*dbb99499SAndroid Build Coastguard Worker lhs = [x[field_name] for x in partition[0]] 206*dbb99499SAndroid Build Coastguard Worker rhs = [x[field_name] for x in partition[1]] 207*dbb99499SAndroid Build Coastguard Worker return [lhs, rhs] 208*dbb99499SAndroid Build Coastguard Worker 209*dbb99499SAndroid Build Coastguard Worker 210*dbb99499SAndroid Build Coastguard Workerdef calc_utest(timings_cpu, timings_time): 211*dbb99499SAndroid Build Coastguard Worker min_rep_cnt = min( 212*dbb99499SAndroid Build Coastguard Worker len(timings_time[0]), 213*dbb99499SAndroid Build Coastguard Worker len(timings_time[1]), 214*dbb99499SAndroid Build Coastguard Worker len(timings_cpu[0]), 215*dbb99499SAndroid Build Coastguard Worker len(timings_cpu[1]), 216*dbb99499SAndroid Build Coastguard Worker ) 217*dbb99499SAndroid Build Coastguard Worker 218*dbb99499SAndroid Build Coastguard Worker # Does *everything* has at least UTEST_MIN_REPETITIONS repetitions? 219*dbb99499SAndroid Build Coastguard Worker if min_rep_cnt < UTEST_MIN_REPETITIONS: 220*dbb99499SAndroid Build Coastguard Worker return False, None, None 221*dbb99499SAndroid Build Coastguard Worker 222*dbb99499SAndroid Build Coastguard Worker time_pvalue = mannwhitneyu( 223*dbb99499SAndroid Build Coastguard Worker timings_time[0], timings_time[1], alternative="two-sided" 224*dbb99499SAndroid Build Coastguard Worker ).pvalue 225*dbb99499SAndroid Build Coastguard Worker cpu_pvalue = mannwhitneyu( 226*dbb99499SAndroid Build Coastguard Worker timings_cpu[0], timings_cpu[1], alternative="two-sided" 227*dbb99499SAndroid Build Coastguard Worker ).pvalue 228*dbb99499SAndroid Build Coastguard Worker 229*dbb99499SAndroid Build Coastguard Worker return (min_rep_cnt >= UTEST_OPTIMAL_REPETITIONS), cpu_pvalue, time_pvalue 230*dbb99499SAndroid Build Coastguard Worker 231*dbb99499SAndroid Build Coastguard Worker 232*dbb99499SAndroid Build Coastguard Workerdef print_utest(bc_name, utest, utest_alpha, first_col_width, use_color=True): 233*dbb99499SAndroid Build Coastguard Worker def get_utest_color(pval): 234*dbb99499SAndroid Build Coastguard Worker return BC_FAIL if pval >= utest_alpha else BC_OKGREEN 235*dbb99499SAndroid Build Coastguard Worker 236*dbb99499SAndroid Build Coastguard Worker # Check if we failed miserably with minimum required repetitions for utest 237*dbb99499SAndroid Build Coastguard Worker if ( 238*dbb99499SAndroid Build Coastguard Worker not utest["have_optimal_repetitions"] 239*dbb99499SAndroid Build Coastguard Worker and utest["cpu_pvalue"] is None 240*dbb99499SAndroid Build Coastguard Worker and utest["time_pvalue"] is None 241*dbb99499SAndroid Build Coastguard Worker ): 242*dbb99499SAndroid Build Coastguard Worker return [] 243*dbb99499SAndroid Build Coastguard Worker 244*dbb99499SAndroid Build Coastguard Worker dsc = "U Test, Repetitions: {} vs {}".format( 245*dbb99499SAndroid Build Coastguard Worker utest["nr_of_repetitions"], utest["nr_of_repetitions_other"] 246*dbb99499SAndroid Build Coastguard Worker ) 247*dbb99499SAndroid Build Coastguard Worker dsc_color = BC_OKGREEN 248*dbb99499SAndroid Build Coastguard Worker 249*dbb99499SAndroid Build Coastguard Worker # We still got some results to show but issue a warning about it. 250*dbb99499SAndroid Build Coastguard Worker if not utest["have_optimal_repetitions"]: 251*dbb99499SAndroid Build Coastguard Worker dsc_color = BC_WARNING 252*dbb99499SAndroid Build Coastguard Worker dsc += ". WARNING: Results unreliable! {}+ repetitions recommended.".format( 253*dbb99499SAndroid Build Coastguard Worker UTEST_OPTIMAL_REPETITIONS 254*dbb99499SAndroid Build Coastguard Worker ) 255*dbb99499SAndroid Build Coastguard Worker 256*dbb99499SAndroid Build Coastguard Worker special_str = "{}{:<{}s}{endc}{}{:16.4f}{endc}{}{:16.4f}{endc}{} {}" 257*dbb99499SAndroid Build Coastguard Worker 258*dbb99499SAndroid Build Coastguard Worker return [ 259*dbb99499SAndroid Build Coastguard Worker color_format( 260*dbb99499SAndroid Build Coastguard Worker use_color, 261*dbb99499SAndroid Build Coastguard Worker special_str, 262*dbb99499SAndroid Build Coastguard Worker BC_HEADER, 263*dbb99499SAndroid Build Coastguard Worker "{}{}".format(bc_name, UTEST_COL_NAME), 264*dbb99499SAndroid Build Coastguard Worker first_col_width, 265*dbb99499SAndroid Build Coastguard Worker get_utest_color(utest["time_pvalue"]), 266*dbb99499SAndroid Build Coastguard Worker utest["time_pvalue"], 267*dbb99499SAndroid Build Coastguard Worker get_utest_color(utest["cpu_pvalue"]), 268*dbb99499SAndroid Build Coastguard Worker utest["cpu_pvalue"], 269*dbb99499SAndroid Build Coastguard Worker dsc_color, 270*dbb99499SAndroid Build Coastguard Worker dsc, 271*dbb99499SAndroid Build Coastguard Worker endc=BC_ENDC, 272*dbb99499SAndroid Build Coastguard Worker ) 273*dbb99499SAndroid Build Coastguard Worker ] 274*dbb99499SAndroid Build Coastguard Worker 275*dbb99499SAndroid Build Coastguard Worker 276*dbb99499SAndroid Build Coastguard Workerdef get_difference_report(json1, json2, utest=False): 277*dbb99499SAndroid Build Coastguard Worker """ 278*dbb99499SAndroid Build Coastguard Worker Calculate and report the difference between each test of two benchmarks 279*dbb99499SAndroid Build Coastguard Worker runs specified as 'json1' and 'json2'. Output is another json containing 280*dbb99499SAndroid Build Coastguard Worker relevant details for each test run. 281*dbb99499SAndroid Build Coastguard Worker """ 282*dbb99499SAndroid Build Coastguard Worker assert utest is True or utest is False 283*dbb99499SAndroid Build Coastguard Worker 284*dbb99499SAndroid Build Coastguard Worker diff_report = [] 285*dbb99499SAndroid Build Coastguard Worker partitions = partition_benchmarks(json1, json2) 286*dbb99499SAndroid Build Coastguard Worker for partition in partitions: 287*dbb99499SAndroid Build Coastguard Worker benchmark_name = partition[0][0]["name"] 288*dbb99499SAndroid Build Coastguard Worker label = partition[0][0]["label"] if "label" in partition[0][0] else "" 289*dbb99499SAndroid Build Coastguard Worker time_unit = partition[0][0]["time_unit"] 290*dbb99499SAndroid Build Coastguard Worker measurements = [] 291*dbb99499SAndroid Build Coastguard Worker utest_results = {} 292*dbb99499SAndroid Build Coastguard Worker # Careful, we may have different repetition count. 293*dbb99499SAndroid Build Coastguard Worker for i in range(min(len(partition[0]), len(partition[1]))): 294*dbb99499SAndroid Build Coastguard Worker bn = partition[0][i] 295*dbb99499SAndroid Build Coastguard Worker other_bench = partition[1][i] 296*dbb99499SAndroid Build Coastguard Worker measurements.append( 297*dbb99499SAndroid Build Coastguard Worker { 298*dbb99499SAndroid Build Coastguard Worker "real_time": bn["real_time"], 299*dbb99499SAndroid Build Coastguard Worker "cpu_time": bn["cpu_time"], 300*dbb99499SAndroid Build Coastguard Worker "real_time_other": other_bench["real_time"], 301*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": other_bench["cpu_time"], 302*dbb99499SAndroid Build Coastguard Worker "time": calculate_change( 303*dbb99499SAndroid Build Coastguard Worker bn["real_time"], other_bench["real_time"] 304*dbb99499SAndroid Build Coastguard Worker ), 305*dbb99499SAndroid Build Coastguard Worker "cpu": calculate_change( 306*dbb99499SAndroid Build Coastguard Worker bn["cpu_time"], other_bench["cpu_time"] 307*dbb99499SAndroid Build Coastguard Worker ), 308*dbb99499SAndroid Build Coastguard Worker } 309*dbb99499SAndroid Build Coastguard Worker ) 310*dbb99499SAndroid Build Coastguard Worker 311*dbb99499SAndroid Build Coastguard Worker # After processing the whole partition, if requested, do the U test. 312*dbb99499SAndroid Build Coastguard Worker if utest: 313*dbb99499SAndroid Build Coastguard Worker timings_cpu = extract_field(partition, "cpu_time") 314*dbb99499SAndroid Build Coastguard Worker timings_time = extract_field(partition, "real_time") 315*dbb99499SAndroid Build Coastguard Worker have_optimal_repetitions, cpu_pvalue, time_pvalue = calc_utest( 316*dbb99499SAndroid Build Coastguard Worker timings_cpu, timings_time 317*dbb99499SAndroid Build Coastguard Worker ) 318*dbb99499SAndroid Build Coastguard Worker if cpu_pvalue is not None and time_pvalue is not None: 319*dbb99499SAndroid Build Coastguard Worker utest_results = { 320*dbb99499SAndroid Build Coastguard Worker "have_optimal_repetitions": have_optimal_repetitions, 321*dbb99499SAndroid Build Coastguard Worker "cpu_pvalue": cpu_pvalue, 322*dbb99499SAndroid Build Coastguard Worker "time_pvalue": time_pvalue, 323*dbb99499SAndroid Build Coastguard Worker "nr_of_repetitions": len(timings_cpu[0]), 324*dbb99499SAndroid Build Coastguard Worker "nr_of_repetitions_other": len(timings_cpu[1]), 325*dbb99499SAndroid Build Coastguard Worker } 326*dbb99499SAndroid Build Coastguard Worker 327*dbb99499SAndroid Build Coastguard Worker # Store only if we had any measurements for given benchmark. 328*dbb99499SAndroid Build Coastguard Worker # E.g. partition_benchmarks will filter out the benchmarks having 329*dbb99499SAndroid Build Coastguard Worker # time units which are not compatible with other time units in the 330*dbb99499SAndroid Build Coastguard Worker # benchmark suite. 331*dbb99499SAndroid Build Coastguard Worker if measurements: 332*dbb99499SAndroid Build Coastguard Worker run_type = ( 333*dbb99499SAndroid Build Coastguard Worker partition[0][0]["run_type"] 334*dbb99499SAndroid Build Coastguard Worker if "run_type" in partition[0][0] 335*dbb99499SAndroid Build Coastguard Worker else "" 336*dbb99499SAndroid Build Coastguard Worker ) 337*dbb99499SAndroid Build Coastguard Worker aggregate_name = ( 338*dbb99499SAndroid Build Coastguard Worker partition[0][0]["aggregate_name"] 339*dbb99499SAndroid Build Coastguard Worker if run_type == "aggregate" 340*dbb99499SAndroid Build Coastguard Worker and "aggregate_name" in partition[0][0] 341*dbb99499SAndroid Build Coastguard Worker else "" 342*dbb99499SAndroid Build Coastguard Worker ) 343*dbb99499SAndroid Build Coastguard Worker diff_report.append( 344*dbb99499SAndroid Build Coastguard Worker { 345*dbb99499SAndroid Build Coastguard Worker "name": benchmark_name, 346*dbb99499SAndroid Build Coastguard Worker "label": label, 347*dbb99499SAndroid Build Coastguard Worker "measurements": measurements, 348*dbb99499SAndroid Build Coastguard Worker "time_unit": time_unit, 349*dbb99499SAndroid Build Coastguard Worker "run_type": run_type, 350*dbb99499SAndroid Build Coastguard Worker "aggregate_name": aggregate_name, 351*dbb99499SAndroid Build Coastguard Worker "utest": utest_results, 352*dbb99499SAndroid Build Coastguard Worker } 353*dbb99499SAndroid Build Coastguard Worker ) 354*dbb99499SAndroid Build Coastguard Worker 355*dbb99499SAndroid Build Coastguard Worker lhs_gmean = calculate_geomean(json1) 356*dbb99499SAndroid Build Coastguard Worker rhs_gmean = calculate_geomean(json2) 357*dbb99499SAndroid Build Coastguard Worker if lhs_gmean.any() and rhs_gmean.any(): 358*dbb99499SAndroid Build Coastguard Worker diff_report.append( 359*dbb99499SAndroid Build Coastguard Worker { 360*dbb99499SAndroid Build Coastguard Worker "name": "OVERALL_GEOMEAN", 361*dbb99499SAndroid Build Coastguard Worker "label": "", 362*dbb99499SAndroid Build Coastguard Worker "measurements": [ 363*dbb99499SAndroid Build Coastguard Worker { 364*dbb99499SAndroid Build Coastguard Worker "real_time": lhs_gmean[0], 365*dbb99499SAndroid Build Coastguard Worker "cpu_time": lhs_gmean[1], 366*dbb99499SAndroid Build Coastguard Worker "real_time_other": rhs_gmean[0], 367*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": rhs_gmean[1], 368*dbb99499SAndroid Build Coastguard Worker "time": calculate_change(lhs_gmean[0], rhs_gmean[0]), 369*dbb99499SAndroid Build Coastguard Worker "cpu": calculate_change(lhs_gmean[1], rhs_gmean[1]), 370*dbb99499SAndroid Build Coastguard Worker } 371*dbb99499SAndroid Build Coastguard Worker ], 372*dbb99499SAndroid Build Coastguard Worker "time_unit": "s", 373*dbb99499SAndroid Build Coastguard Worker "run_type": "aggregate", 374*dbb99499SAndroid Build Coastguard Worker "aggregate_name": "geomean", 375*dbb99499SAndroid Build Coastguard Worker "utest": {}, 376*dbb99499SAndroid Build Coastguard Worker } 377*dbb99499SAndroid Build Coastguard Worker ) 378*dbb99499SAndroid Build Coastguard Worker 379*dbb99499SAndroid Build Coastguard Worker return diff_report 380*dbb99499SAndroid Build Coastguard Worker 381*dbb99499SAndroid Build Coastguard Worker 382*dbb99499SAndroid Build Coastguard Workerdef print_difference_report( 383*dbb99499SAndroid Build Coastguard Worker json_diff_report, 384*dbb99499SAndroid Build Coastguard Worker include_aggregates_only=False, 385*dbb99499SAndroid Build Coastguard Worker utest=False, 386*dbb99499SAndroid Build Coastguard Worker utest_alpha=0.05, 387*dbb99499SAndroid Build Coastguard Worker use_color=True, 388*dbb99499SAndroid Build Coastguard Worker): 389*dbb99499SAndroid Build Coastguard Worker """ 390*dbb99499SAndroid Build Coastguard Worker Calculate and report the difference between each test of two benchmarks 391*dbb99499SAndroid Build Coastguard Worker runs specified as 'json1' and 'json2'. 392*dbb99499SAndroid Build Coastguard Worker """ 393*dbb99499SAndroid Build Coastguard Worker assert utest is True or utest is False 394*dbb99499SAndroid Build Coastguard Worker 395*dbb99499SAndroid Build Coastguard Worker def get_color(res): 396*dbb99499SAndroid Build Coastguard Worker if res > 0.05: 397*dbb99499SAndroid Build Coastguard Worker return BC_FAIL 398*dbb99499SAndroid Build Coastguard Worker elif res > -0.07: 399*dbb99499SAndroid Build Coastguard Worker return BC_WHITE 400*dbb99499SAndroid Build Coastguard Worker else: 401*dbb99499SAndroid Build Coastguard Worker return BC_CYAN 402*dbb99499SAndroid Build Coastguard Worker 403*dbb99499SAndroid Build Coastguard Worker first_col_width = find_longest_name(json_diff_report) 404*dbb99499SAndroid Build Coastguard Worker first_col_width = max(first_col_width, len("Benchmark")) 405*dbb99499SAndroid Build Coastguard Worker first_col_width += len(UTEST_COL_NAME) 406*dbb99499SAndroid Build Coastguard Worker first_line = "{:<{}s}Time CPU Time Old Time New CPU Old CPU New".format( 407*dbb99499SAndroid Build Coastguard Worker "Benchmark", 12 + first_col_width 408*dbb99499SAndroid Build Coastguard Worker ) 409*dbb99499SAndroid Build Coastguard Worker output_strs = [first_line, "-" * len(first_line)] 410*dbb99499SAndroid Build Coastguard Worker 411*dbb99499SAndroid Build Coastguard Worker fmt_str = "{}{:<{}s}{endc}{}{:+16.4f}{endc}{}{:+16.4f}{endc}{:14.0f}{:14.0f}{endc}{:14.0f}{:14.0f}" 412*dbb99499SAndroid Build Coastguard Worker for benchmark in json_diff_report: 413*dbb99499SAndroid Build Coastguard Worker # *If* we were asked to only include aggregates, 414*dbb99499SAndroid Build Coastguard Worker # and if it is non-aggregate, then don't print it. 415*dbb99499SAndroid Build Coastguard Worker if ( 416*dbb99499SAndroid Build Coastguard Worker not include_aggregates_only 417*dbb99499SAndroid Build Coastguard Worker or "run_type" not in benchmark 418*dbb99499SAndroid Build Coastguard Worker or benchmark["run_type"] == "aggregate" 419*dbb99499SAndroid Build Coastguard Worker ): 420*dbb99499SAndroid Build Coastguard Worker for measurement in benchmark["measurements"]: 421*dbb99499SAndroid Build Coastguard Worker output_strs += [ 422*dbb99499SAndroid Build Coastguard Worker color_format( 423*dbb99499SAndroid Build Coastguard Worker use_color, 424*dbb99499SAndroid Build Coastguard Worker fmt_str, 425*dbb99499SAndroid Build Coastguard Worker BC_HEADER, 426*dbb99499SAndroid Build Coastguard Worker benchmark["name"], 427*dbb99499SAndroid Build Coastguard Worker first_col_width, 428*dbb99499SAndroid Build Coastguard Worker get_color(measurement["time"]), 429*dbb99499SAndroid Build Coastguard Worker measurement["time"], 430*dbb99499SAndroid Build Coastguard Worker get_color(measurement["cpu"]), 431*dbb99499SAndroid Build Coastguard Worker measurement["cpu"], 432*dbb99499SAndroid Build Coastguard Worker measurement["real_time"], 433*dbb99499SAndroid Build Coastguard Worker measurement["real_time_other"], 434*dbb99499SAndroid Build Coastguard Worker measurement["cpu_time"], 435*dbb99499SAndroid Build Coastguard Worker measurement["cpu_time_other"], 436*dbb99499SAndroid Build Coastguard Worker endc=BC_ENDC, 437*dbb99499SAndroid Build Coastguard Worker ) 438*dbb99499SAndroid Build Coastguard Worker ] 439*dbb99499SAndroid Build Coastguard Worker 440*dbb99499SAndroid Build Coastguard Worker # After processing the measurements, if requested and 441*dbb99499SAndroid Build Coastguard Worker # if applicable (e.g. u-test exists for given benchmark), 442*dbb99499SAndroid Build Coastguard Worker # print the U test. 443*dbb99499SAndroid Build Coastguard Worker if utest and benchmark["utest"]: 444*dbb99499SAndroid Build Coastguard Worker output_strs += print_utest( 445*dbb99499SAndroid Build Coastguard Worker benchmark["name"], 446*dbb99499SAndroid Build Coastguard Worker benchmark["utest"], 447*dbb99499SAndroid Build Coastguard Worker utest_alpha=utest_alpha, 448*dbb99499SAndroid Build Coastguard Worker first_col_width=first_col_width, 449*dbb99499SAndroid Build Coastguard Worker use_color=use_color, 450*dbb99499SAndroid Build Coastguard Worker ) 451*dbb99499SAndroid Build Coastguard Worker 452*dbb99499SAndroid Build Coastguard Worker return output_strs 453*dbb99499SAndroid Build Coastguard Worker 454*dbb99499SAndroid Build Coastguard Worker 455*dbb99499SAndroid Build Coastguard Worker############################################################################### 456*dbb99499SAndroid Build Coastguard Worker# Unit tests 457*dbb99499SAndroid Build Coastguard Worker 458*dbb99499SAndroid Build Coastguard Worker 459*dbb99499SAndroid Build Coastguard Workerclass TestGetUniqueBenchmarkNames(unittest.TestCase): 460*dbb99499SAndroid Build Coastguard Worker def load_results(self): 461*dbb99499SAndroid Build Coastguard Worker import json 462*dbb99499SAndroid Build Coastguard Worker 463*dbb99499SAndroid Build Coastguard Worker testInputs = os.path.join( 464*dbb99499SAndroid Build Coastguard Worker os.path.dirname(os.path.realpath(__file__)), "Inputs" 465*dbb99499SAndroid Build Coastguard Worker ) 466*dbb99499SAndroid Build Coastguard Worker testOutput = os.path.join(testInputs, "test3_run0.json") 467*dbb99499SAndroid Build Coastguard Worker with open(testOutput, "r") as f: 468*dbb99499SAndroid Build Coastguard Worker json = json.load(f) 469*dbb99499SAndroid Build Coastguard Worker return json 470*dbb99499SAndroid Build Coastguard Worker 471*dbb99499SAndroid Build Coastguard Worker def test_basic(self): 472*dbb99499SAndroid Build Coastguard Worker expect_lines = [ 473*dbb99499SAndroid Build Coastguard Worker "BM_One", 474*dbb99499SAndroid Build Coastguard Worker "BM_Two", 475*dbb99499SAndroid Build Coastguard Worker "short", # These two are not sorted 476*dbb99499SAndroid Build Coastguard Worker "medium", # These two are not sorted 477*dbb99499SAndroid Build Coastguard Worker ] 478*dbb99499SAndroid Build Coastguard Worker json = self.load_results() 479*dbb99499SAndroid Build Coastguard Worker output_lines = get_unique_benchmark_names(json) 480*dbb99499SAndroid Build Coastguard Worker print("\n") 481*dbb99499SAndroid Build Coastguard Worker print("\n".join(output_lines)) 482*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(output_lines), len(expect_lines)) 483*dbb99499SAndroid Build Coastguard Worker for i in range(0, len(output_lines)): 484*dbb99499SAndroid Build Coastguard Worker self.assertEqual(expect_lines[i], output_lines[i]) 485*dbb99499SAndroid Build Coastguard Worker 486*dbb99499SAndroid Build Coastguard Worker 487*dbb99499SAndroid Build Coastguard Workerclass TestReportDifference(unittest.TestCase): 488*dbb99499SAndroid Build Coastguard Worker @classmethod 489*dbb99499SAndroid Build Coastguard Worker def setUpClass(cls): 490*dbb99499SAndroid Build Coastguard Worker def load_results(): 491*dbb99499SAndroid Build Coastguard Worker import json 492*dbb99499SAndroid Build Coastguard Worker 493*dbb99499SAndroid Build Coastguard Worker testInputs = os.path.join( 494*dbb99499SAndroid Build Coastguard Worker os.path.dirname(os.path.realpath(__file__)), "Inputs" 495*dbb99499SAndroid Build Coastguard Worker ) 496*dbb99499SAndroid Build Coastguard Worker testOutput1 = os.path.join(testInputs, "test1_run1.json") 497*dbb99499SAndroid Build Coastguard Worker testOutput2 = os.path.join(testInputs, "test1_run2.json") 498*dbb99499SAndroid Build Coastguard Worker with open(testOutput1, "r") as f: 499*dbb99499SAndroid Build Coastguard Worker json1 = json.load(f) 500*dbb99499SAndroid Build Coastguard Worker with open(testOutput2, "r") as f: 501*dbb99499SAndroid Build Coastguard Worker json2 = json.load(f) 502*dbb99499SAndroid Build Coastguard Worker return json1, json2 503*dbb99499SAndroid Build Coastguard Worker 504*dbb99499SAndroid Build Coastguard Worker json1, json2 = load_results() 505*dbb99499SAndroid Build Coastguard Worker cls.json_diff_report = get_difference_report(json1, json2) 506*dbb99499SAndroid Build Coastguard Worker 507*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report_pretty_printing(self): 508*dbb99499SAndroid Build Coastguard Worker expect_lines = [ 509*dbb99499SAndroid Build Coastguard Worker ["BM_SameTimes", "+0.0000", "+0.0000", "10", "10", "10", "10"], 510*dbb99499SAndroid Build Coastguard Worker ["BM_2xFaster", "-0.5000", "-0.5000", "50", "25", "50", "25"], 511*dbb99499SAndroid Build Coastguard Worker ["BM_2xSlower", "+1.0000", "+1.0000", "50", "100", "50", "100"], 512*dbb99499SAndroid Build Coastguard Worker [ 513*dbb99499SAndroid Build Coastguard Worker "BM_1PercentFaster", 514*dbb99499SAndroid Build Coastguard Worker "-0.0100", 515*dbb99499SAndroid Build Coastguard Worker "-0.0100", 516*dbb99499SAndroid Build Coastguard Worker "100", 517*dbb99499SAndroid Build Coastguard Worker "99", 518*dbb99499SAndroid Build Coastguard Worker "100", 519*dbb99499SAndroid Build Coastguard Worker "99", 520*dbb99499SAndroid Build Coastguard Worker ], 521*dbb99499SAndroid Build Coastguard Worker [ 522*dbb99499SAndroid Build Coastguard Worker "BM_1PercentSlower", 523*dbb99499SAndroid Build Coastguard Worker "+0.0100", 524*dbb99499SAndroid Build Coastguard Worker "+0.0100", 525*dbb99499SAndroid Build Coastguard Worker "100", 526*dbb99499SAndroid Build Coastguard Worker "101", 527*dbb99499SAndroid Build Coastguard Worker "100", 528*dbb99499SAndroid Build Coastguard Worker "101", 529*dbb99499SAndroid Build Coastguard Worker ], 530*dbb99499SAndroid Build Coastguard Worker [ 531*dbb99499SAndroid Build Coastguard Worker "BM_10PercentFaster", 532*dbb99499SAndroid Build Coastguard Worker "-0.1000", 533*dbb99499SAndroid Build Coastguard Worker "-0.1000", 534*dbb99499SAndroid Build Coastguard Worker "100", 535*dbb99499SAndroid Build Coastguard Worker "90", 536*dbb99499SAndroid Build Coastguard Worker "100", 537*dbb99499SAndroid Build Coastguard Worker "90", 538*dbb99499SAndroid Build Coastguard Worker ], 539*dbb99499SAndroid Build Coastguard Worker [ 540*dbb99499SAndroid Build Coastguard Worker "BM_10PercentSlower", 541*dbb99499SAndroid Build Coastguard Worker "+0.1000", 542*dbb99499SAndroid Build Coastguard Worker "+0.1000", 543*dbb99499SAndroid Build Coastguard Worker "100", 544*dbb99499SAndroid Build Coastguard Worker "110", 545*dbb99499SAndroid Build Coastguard Worker "100", 546*dbb99499SAndroid Build Coastguard Worker "110", 547*dbb99499SAndroid Build Coastguard Worker ], 548*dbb99499SAndroid Build Coastguard Worker [ 549*dbb99499SAndroid Build Coastguard Worker "BM_100xSlower", 550*dbb99499SAndroid Build Coastguard Worker "+99.0000", 551*dbb99499SAndroid Build Coastguard Worker "+99.0000", 552*dbb99499SAndroid Build Coastguard Worker "100", 553*dbb99499SAndroid Build Coastguard Worker "10000", 554*dbb99499SAndroid Build Coastguard Worker "100", 555*dbb99499SAndroid Build Coastguard Worker "10000", 556*dbb99499SAndroid Build Coastguard Worker ], 557*dbb99499SAndroid Build Coastguard Worker [ 558*dbb99499SAndroid Build Coastguard Worker "BM_100xFaster", 559*dbb99499SAndroid Build Coastguard Worker "-0.9900", 560*dbb99499SAndroid Build Coastguard Worker "-0.9900", 561*dbb99499SAndroid Build Coastguard Worker "10000", 562*dbb99499SAndroid Build Coastguard Worker "100", 563*dbb99499SAndroid Build Coastguard Worker "10000", 564*dbb99499SAndroid Build Coastguard Worker "100", 565*dbb99499SAndroid Build Coastguard Worker ], 566*dbb99499SAndroid Build Coastguard Worker [ 567*dbb99499SAndroid Build Coastguard Worker "BM_10PercentCPUToTime", 568*dbb99499SAndroid Build Coastguard Worker "+0.1000", 569*dbb99499SAndroid Build Coastguard Worker "-0.1000", 570*dbb99499SAndroid Build Coastguard Worker "100", 571*dbb99499SAndroid Build Coastguard Worker "110", 572*dbb99499SAndroid Build Coastguard Worker "100", 573*dbb99499SAndroid Build Coastguard Worker "90", 574*dbb99499SAndroid Build Coastguard Worker ], 575*dbb99499SAndroid Build Coastguard Worker ["BM_ThirdFaster", "-0.3333", "-0.3334", "100", "67", "100", "67"], 576*dbb99499SAndroid Build Coastguard Worker ["BM_NotBadTimeUnit", "-0.9000", "+0.2000", "0", "0", "0", "1"], 577*dbb99499SAndroid Build Coastguard Worker ["BM_hasLabel", "+0.0000", "+0.0000", "1", "1", "1", "1"], 578*dbb99499SAndroid Build Coastguard Worker ["OVERALL_GEOMEAN", "-0.8113", "-0.7779", "0", "0", "0", "0"], 579*dbb99499SAndroid Build Coastguard Worker ] 580*dbb99499SAndroid Build Coastguard Worker output_lines_with_header = print_difference_report( 581*dbb99499SAndroid Build Coastguard Worker self.json_diff_report, use_color=False 582*dbb99499SAndroid Build Coastguard Worker ) 583*dbb99499SAndroid Build Coastguard Worker output_lines = output_lines_with_header[2:] 584*dbb99499SAndroid Build Coastguard Worker print("\n") 585*dbb99499SAndroid Build Coastguard Worker print("\n".join(output_lines_with_header)) 586*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(output_lines), len(expect_lines)) 587*dbb99499SAndroid Build Coastguard Worker for i in range(0, len(output_lines)): 588*dbb99499SAndroid Build Coastguard Worker parts = [x for x in output_lines[i].split(" ") if x] 589*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(parts), 7) 590*dbb99499SAndroid Build Coastguard Worker self.assertEqual(expect_lines[i], parts) 591*dbb99499SAndroid Build Coastguard Worker 592*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report_output(self): 593*dbb99499SAndroid Build Coastguard Worker expected_output = [ 594*dbb99499SAndroid Build Coastguard Worker { 595*dbb99499SAndroid Build Coastguard Worker "name": "BM_SameTimes", 596*dbb99499SAndroid Build Coastguard Worker "label": "", 597*dbb99499SAndroid Build Coastguard Worker "measurements": [ 598*dbb99499SAndroid Build Coastguard Worker { 599*dbb99499SAndroid Build Coastguard Worker "time": 0.0000, 600*dbb99499SAndroid Build Coastguard Worker "cpu": 0.0000, 601*dbb99499SAndroid Build Coastguard Worker "real_time": 10, 602*dbb99499SAndroid Build Coastguard Worker "real_time_other": 10, 603*dbb99499SAndroid Build Coastguard Worker "cpu_time": 10, 604*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 10, 605*dbb99499SAndroid Build Coastguard Worker } 606*dbb99499SAndroid Build Coastguard Worker ], 607*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 608*dbb99499SAndroid Build Coastguard Worker "utest": {}, 609*dbb99499SAndroid Build Coastguard Worker }, 610*dbb99499SAndroid Build Coastguard Worker { 611*dbb99499SAndroid Build Coastguard Worker "name": "BM_2xFaster", 612*dbb99499SAndroid Build Coastguard Worker "label": "", 613*dbb99499SAndroid Build Coastguard Worker "measurements": [ 614*dbb99499SAndroid Build Coastguard Worker { 615*dbb99499SAndroid Build Coastguard Worker "time": -0.5000, 616*dbb99499SAndroid Build Coastguard Worker "cpu": -0.5000, 617*dbb99499SAndroid Build Coastguard Worker "real_time": 50, 618*dbb99499SAndroid Build Coastguard Worker "real_time_other": 25, 619*dbb99499SAndroid Build Coastguard Worker "cpu_time": 50, 620*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 25, 621*dbb99499SAndroid Build Coastguard Worker } 622*dbb99499SAndroid Build Coastguard Worker ], 623*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 624*dbb99499SAndroid Build Coastguard Worker "utest": {}, 625*dbb99499SAndroid Build Coastguard Worker }, 626*dbb99499SAndroid Build Coastguard Worker { 627*dbb99499SAndroid Build Coastguard Worker "name": "BM_2xSlower", 628*dbb99499SAndroid Build Coastguard Worker "label": "", 629*dbb99499SAndroid Build Coastguard Worker "measurements": [ 630*dbb99499SAndroid Build Coastguard Worker { 631*dbb99499SAndroid Build Coastguard Worker "time": 1.0000, 632*dbb99499SAndroid Build Coastguard Worker "cpu": 1.0000, 633*dbb99499SAndroid Build Coastguard Worker "real_time": 50, 634*dbb99499SAndroid Build Coastguard Worker "real_time_other": 100, 635*dbb99499SAndroid Build Coastguard Worker "cpu_time": 50, 636*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 100, 637*dbb99499SAndroid Build Coastguard Worker } 638*dbb99499SAndroid Build Coastguard Worker ], 639*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 640*dbb99499SAndroid Build Coastguard Worker "utest": {}, 641*dbb99499SAndroid Build Coastguard Worker }, 642*dbb99499SAndroid Build Coastguard Worker { 643*dbb99499SAndroid Build Coastguard Worker "name": "BM_1PercentFaster", 644*dbb99499SAndroid Build Coastguard Worker "label": "", 645*dbb99499SAndroid Build Coastguard Worker "measurements": [ 646*dbb99499SAndroid Build Coastguard Worker { 647*dbb99499SAndroid Build Coastguard Worker "time": -0.0100, 648*dbb99499SAndroid Build Coastguard Worker "cpu": -0.0100, 649*dbb99499SAndroid Build Coastguard Worker "real_time": 100, 650*dbb99499SAndroid Build Coastguard Worker "real_time_other": 98.9999999, 651*dbb99499SAndroid Build Coastguard Worker "cpu_time": 100, 652*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 98.9999999, 653*dbb99499SAndroid Build Coastguard Worker } 654*dbb99499SAndroid Build Coastguard Worker ], 655*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 656*dbb99499SAndroid Build Coastguard Worker "utest": {}, 657*dbb99499SAndroid Build Coastguard Worker }, 658*dbb99499SAndroid Build Coastguard Worker { 659*dbb99499SAndroid Build Coastguard Worker "name": "BM_1PercentSlower", 660*dbb99499SAndroid Build Coastguard Worker "label": "", 661*dbb99499SAndroid Build Coastguard Worker "measurements": [ 662*dbb99499SAndroid Build Coastguard Worker { 663*dbb99499SAndroid Build Coastguard Worker "time": 0.0100, 664*dbb99499SAndroid Build Coastguard Worker "cpu": 0.0100, 665*dbb99499SAndroid Build Coastguard Worker "real_time": 100, 666*dbb99499SAndroid Build Coastguard Worker "real_time_other": 101, 667*dbb99499SAndroid Build Coastguard Worker "cpu_time": 100, 668*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 101, 669*dbb99499SAndroid Build Coastguard Worker } 670*dbb99499SAndroid Build Coastguard Worker ], 671*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 672*dbb99499SAndroid Build Coastguard Worker "utest": {}, 673*dbb99499SAndroid Build Coastguard Worker }, 674*dbb99499SAndroid Build Coastguard Worker { 675*dbb99499SAndroid Build Coastguard Worker "name": "BM_10PercentFaster", 676*dbb99499SAndroid Build Coastguard Worker "label": "", 677*dbb99499SAndroid Build Coastguard Worker "measurements": [ 678*dbb99499SAndroid Build Coastguard Worker { 679*dbb99499SAndroid Build Coastguard Worker "time": -0.1000, 680*dbb99499SAndroid Build Coastguard Worker "cpu": -0.1000, 681*dbb99499SAndroid Build Coastguard Worker "real_time": 100, 682*dbb99499SAndroid Build Coastguard Worker "real_time_other": 90, 683*dbb99499SAndroid Build Coastguard Worker "cpu_time": 100, 684*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 90, 685*dbb99499SAndroid Build Coastguard Worker } 686*dbb99499SAndroid Build Coastguard Worker ], 687*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 688*dbb99499SAndroid Build Coastguard Worker "utest": {}, 689*dbb99499SAndroid Build Coastguard Worker }, 690*dbb99499SAndroid Build Coastguard Worker { 691*dbb99499SAndroid Build Coastguard Worker "name": "BM_10PercentSlower", 692*dbb99499SAndroid Build Coastguard Worker "label": "", 693*dbb99499SAndroid Build Coastguard Worker "measurements": [ 694*dbb99499SAndroid Build Coastguard Worker { 695*dbb99499SAndroid Build Coastguard Worker "time": 0.1000, 696*dbb99499SAndroid Build Coastguard Worker "cpu": 0.1000, 697*dbb99499SAndroid Build Coastguard Worker "real_time": 100, 698*dbb99499SAndroid Build Coastguard Worker "real_time_other": 110, 699*dbb99499SAndroid Build Coastguard Worker "cpu_time": 100, 700*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 110, 701*dbb99499SAndroid Build Coastguard Worker } 702*dbb99499SAndroid Build Coastguard Worker ], 703*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 704*dbb99499SAndroid Build Coastguard Worker "utest": {}, 705*dbb99499SAndroid Build Coastguard Worker }, 706*dbb99499SAndroid Build Coastguard Worker { 707*dbb99499SAndroid Build Coastguard Worker "name": "BM_100xSlower", 708*dbb99499SAndroid Build Coastguard Worker "label": "", 709*dbb99499SAndroid Build Coastguard Worker "measurements": [ 710*dbb99499SAndroid Build Coastguard Worker { 711*dbb99499SAndroid Build Coastguard Worker "time": 99.0000, 712*dbb99499SAndroid Build Coastguard Worker "cpu": 99.0000, 713*dbb99499SAndroid Build Coastguard Worker "real_time": 100, 714*dbb99499SAndroid Build Coastguard Worker "real_time_other": 10000, 715*dbb99499SAndroid Build Coastguard Worker "cpu_time": 100, 716*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 10000, 717*dbb99499SAndroid Build Coastguard Worker } 718*dbb99499SAndroid Build Coastguard Worker ], 719*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 720*dbb99499SAndroid Build Coastguard Worker "utest": {}, 721*dbb99499SAndroid Build Coastguard Worker }, 722*dbb99499SAndroid Build Coastguard Worker { 723*dbb99499SAndroid Build Coastguard Worker "name": "BM_100xFaster", 724*dbb99499SAndroid Build Coastguard Worker "label": "", 725*dbb99499SAndroid Build Coastguard Worker "measurements": [ 726*dbb99499SAndroid Build Coastguard Worker { 727*dbb99499SAndroid Build Coastguard Worker "time": -0.9900, 728*dbb99499SAndroid Build Coastguard Worker "cpu": -0.9900, 729*dbb99499SAndroid Build Coastguard Worker "real_time": 10000, 730*dbb99499SAndroid Build Coastguard Worker "real_time_other": 100, 731*dbb99499SAndroid Build Coastguard Worker "cpu_time": 10000, 732*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 100, 733*dbb99499SAndroid Build Coastguard Worker } 734*dbb99499SAndroid Build Coastguard Worker ], 735*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 736*dbb99499SAndroid Build Coastguard Worker "utest": {}, 737*dbb99499SAndroid Build Coastguard Worker }, 738*dbb99499SAndroid Build Coastguard Worker { 739*dbb99499SAndroid Build Coastguard Worker "name": "BM_10PercentCPUToTime", 740*dbb99499SAndroid Build Coastguard Worker "label": "", 741*dbb99499SAndroid Build Coastguard Worker "measurements": [ 742*dbb99499SAndroid Build Coastguard Worker { 743*dbb99499SAndroid Build Coastguard Worker "time": 0.1000, 744*dbb99499SAndroid Build Coastguard Worker "cpu": -0.1000, 745*dbb99499SAndroid Build Coastguard Worker "real_time": 100, 746*dbb99499SAndroid Build Coastguard Worker "real_time_other": 110, 747*dbb99499SAndroid Build Coastguard Worker "cpu_time": 100, 748*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 90, 749*dbb99499SAndroid Build Coastguard Worker } 750*dbb99499SAndroid Build Coastguard Worker ], 751*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 752*dbb99499SAndroid Build Coastguard Worker "utest": {}, 753*dbb99499SAndroid Build Coastguard Worker }, 754*dbb99499SAndroid Build Coastguard Worker { 755*dbb99499SAndroid Build Coastguard Worker "name": "BM_ThirdFaster", 756*dbb99499SAndroid Build Coastguard Worker "label": "", 757*dbb99499SAndroid Build Coastguard Worker "measurements": [ 758*dbb99499SAndroid Build Coastguard Worker { 759*dbb99499SAndroid Build Coastguard Worker "time": -0.3333, 760*dbb99499SAndroid Build Coastguard Worker "cpu": -0.3334, 761*dbb99499SAndroid Build Coastguard Worker "real_time": 100, 762*dbb99499SAndroid Build Coastguard Worker "real_time_other": 67, 763*dbb99499SAndroid Build Coastguard Worker "cpu_time": 100, 764*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 67, 765*dbb99499SAndroid Build Coastguard Worker } 766*dbb99499SAndroid Build Coastguard Worker ], 767*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 768*dbb99499SAndroid Build Coastguard Worker "utest": {}, 769*dbb99499SAndroid Build Coastguard Worker }, 770*dbb99499SAndroid Build Coastguard Worker { 771*dbb99499SAndroid Build Coastguard Worker "name": "BM_NotBadTimeUnit", 772*dbb99499SAndroid Build Coastguard Worker "label": "", 773*dbb99499SAndroid Build Coastguard Worker "measurements": [ 774*dbb99499SAndroid Build Coastguard Worker { 775*dbb99499SAndroid Build Coastguard Worker "time": -0.9000, 776*dbb99499SAndroid Build Coastguard Worker "cpu": 0.2000, 777*dbb99499SAndroid Build Coastguard Worker "real_time": 0.4, 778*dbb99499SAndroid Build Coastguard Worker "real_time_other": 0.04, 779*dbb99499SAndroid Build Coastguard Worker "cpu_time": 0.5, 780*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 0.6, 781*dbb99499SAndroid Build Coastguard Worker } 782*dbb99499SAndroid Build Coastguard Worker ], 783*dbb99499SAndroid Build Coastguard Worker "time_unit": "s", 784*dbb99499SAndroid Build Coastguard Worker "utest": {}, 785*dbb99499SAndroid Build Coastguard Worker }, 786*dbb99499SAndroid Build Coastguard Worker { 787*dbb99499SAndroid Build Coastguard Worker "name": "BM_hasLabel", 788*dbb99499SAndroid Build Coastguard Worker "label": "a label", 789*dbb99499SAndroid Build Coastguard Worker "measurements": [ 790*dbb99499SAndroid Build Coastguard Worker { 791*dbb99499SAndroid Build Coastguard Worker "time": 0.0000, 792*dbb99499SAndroid Build Coastguard Worker "cpu": 0.0000, 793*dbb99499SAndroid Build Coastguard Worker "real_time": 1, 794*dbb99499SAndroid Build Coastguard Worker "real_time_other": 1, 795*dbb99499SAndroid Build Coastguard Worker "cpu_time": 1, 796*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 1, 797*dbb99499SAndroid Build Coastguard Worker } 798*dbb99499SAndroid Build Coastguard Worker ], 799*dbb99499SAndroid Build Coastguard Worker "time_unit": "s", 800*dbb99499SAndroid Build Coastguard Worker "utest": {}, 801*dbb99499SAndroid Build Coastguard Worker }, 802*dbb99499SAndroid Build Coastguard Worker { 803*dbb99499SAndroid Build Coastguard Worker "name": "OVERALL_GEOMEAN", 804*dbb99499SAndroid Build Coastguard Worker "label": "", 805*dbb99499SAndroid Build Coastguard Worker "measurements": [ 806*dbb99499SAndroid Build Coastguard Worker { 807*dbb99499SAndroid Build Coastguard Worker "real_time": 3.1622776601683826e-06, 808*dbb99499SAndroid Build Coastguard Worker "cpu_time": 3.2130844755623912e-06, 809*dbb99499SAndroid Build Coastguard Worker "real_time_other": 1.9768988699420897e-07, 810*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 2.397447755209533e-07, 811*dbb99499SAndroid Build Coastguard Worker "time": -0.8112976497120911, 812*dbb99499SAndroid Build Coastguard Worker "cpu": -0.7778551721181174, 813*dbb99499SAndroid Build Coastguard Worker } 814*dbb99499SAndroid Build Coastguard Worker ], 815*dbb99499SAndroid Build Coastguard Worker "time_unit": "s", 816*dbb99499SAndroid Build Coastguard Worker "run_type": "aggregate", 817*dbb99499SAndroid Build Coastguard Worker "aggregate_name": "geomean", 818*dbb99499SAndroid Build Coastguard Worker "utest": {}, 819*dbb99499SAndroid Build Coastguard Worker }, 820*dbb99499SAndroid Build Coastguard Worker ] 821*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(self.json_diff_report), len(expected_output)) 822*dbb99499SAndroid Build Coastguard Worker for out, expected in zip(self.json_diff_report, expected_output): 823*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["name"], expected["name"]) 824*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["label"], expected["label"]) 825*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["time_unit"], expected["time_unit"]) 826*dbb99499SAndroid Build Coastguard Worker assert_utest(self, out, expected) 827*dbb99499SAndroid Build Coastguard Worker assert_measurements(self, out, expected) 828*dbb99499SAndroid Build Coastguard Worker 829*dbb99499SAndroid Build Coastguard Worker 830*dbb99499SAndroid Build Coastguard Workerclass TestReportDifferenceBetweenFamilies(unittest.TestCase): 831*dbb99499SAndroid Build Coastguard Worker @classmethod 832*dbb99499SAndroid Build Coastguard Worker def setUpClass(cls): 833*dbb99499SAndroid Build Coastguard Worker def load_result(): 834*dbb99499SAndroid Build Coastguard Worker import json 835*dbb99499SAndroid Build Coastguard Worker 836*dbb99499SAndroid Build Coastguard Worker testInputs = os.path.join( 837*dbb99499SAndroid Build Coastguard Worker os.path.dirname(os.path.realpath(__file__)), "Inputs" 838*dbb99499SAndroid Build Coastguard Worker ) 839*dbb99499SAndroid Build Coastguard Worker testOutput = os.path.join(testInputs, "test2_run.json") 840*dbb99499SAndroid Build Coastguard Worker with open(testOutput, "r") as f: 841*dbb99499SAndroid Build Coastguard Worker json = json.load(f) 842*dbb99499SAndroid Build Coastguard Worker return json 843*dbb99499SAndroid Build Coastguard Worker 844*dbb99499SAndroid Build Coastguard Worker json = load_result() 845*dbb99499SAndroid Build Coastguard Worker json1 = filter_benchmark(json, "BM_Z.ro", ".") 846*dbb99499SAndroid Build Coastguard Worker json2 = filter_benchmark(json, "BM_O.e", ".") 847*dbb99499SAndroid Build Coastguard Worker cls.json_diff_report = get_difference_report(json1, json2) 848*dbb99499SAndroid Build Coastguard Worker 849*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report_pretty_printing(self): 850*dbb99499SAndroid Build Coastguard Worker expect_lines = [ 851*dbb99499SAndroid Build Coastguard Worker [".", "-0.5000", "-0.5000", "10", "5", "10", "5"], 852*dbb99499SAndroid Build Coastguard Worker ["./4", "-0.5000", "-0.5000", "40", "20", "40", "20"], 853*dbb99499SAndroid Build Coastguard Worker ["Prefix/.", "-0.5000", "-0.5000", "20", "10", "20", "10"], 854*dbb99499SAndroid Build Coastguard Worker ["Prefix/./3", "-0.5000", "-0.5000", "30", "15", "30", "15"], 855*dbb99499SAndroid Build Coastguard Worker ["OVERALL_GEOMEAN", "-0.5000", "-0.5000", "0", "0", "0", "0"], 856*dbb99499SAndroid Build Coastguard Worker ] 857*dbb99499SAndroid Build Coastguard Worker output_lines_with_header = print_difference_report( 858*dbb99499SAndroid Build Coastguard Worker self.json_diff_report, use_color=False 859*dbb99499SAndroid Build Coastguard Worker ) 860*dbb99499SAndroid Build Coastguard Worker output_lines = output_lines_with_header[2:] 861*dbb99499SAndroid Build Coastguard Worker print("\n") 862*dbb99499SAndroid Build Coastguard Worker print("\n".join(output_lines_with_header)) 863*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(output_lines), len(expect_lines)) 864*dbb99499SAndroid Build Coastguard Worker for i in range(0, len(output_lines)): 865*dbb99499SAndroid Build Coastguard Worker parts = [x for x in output_lines[i].split(" ") if x] 866*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(parts), 7) 867*dbb99499SAndroid Build Coastguard Worker self.assertEqual(expect_lines[i], parts) 868*dbb99499SAndroid Build Coastguard Worker 869*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report(self): 870*dbb99499SAndroid Build Coastguard Worker expected_output = [ 871*dbb99499SAndroid Build Coastguard Worker { 872*dbb99499SAndroid Build Coastguard Worker "name": ".", 873*dbb99499SAndroid Build Coastguard Worker "measurements": [ 874*dbb99499SAndroid Build Coastguard Worker { 875*dbb99499SAndroid Build Coastguard Worker "time": -0.5, 876*dbb99499SAndroid Build Coastguard Worker "cpu": -0.5, 877*dbb99499SAndroid Build Coastguard Worker "real_time": 10, 878*dbb99499SAndroid Build Coastguard Worker "real_time_other": 5, 879*dbb99499SAndroid Build Coastguard Worker "cpu_time": 10, 880*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 5, 881*dbb99499SAndroid Build Coastguard Worker } 882*dbb99499SAndroid Build Coastguard Worker ], 883*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 884*dbb99499SAndroid Build Coastguard Worker "utest": {}, 885*dbb99499SAndroid Build Coastguard Worker }, 886*dbb99499SAndroid Build Coastguard Worker { 887*dbb99499SAndroid Build Coastguard Worker "name": "./4", 888*dbb99499SAndroid Build Coastguard Worker "measurements": [ 889*dbb99499SAndroid Build Coastguard Worker { 890*dbb99499SAndroid Build Coastguard Worker "time": -0.5, 891*dbb99499SAndroid Build Coastguard Worker "cpu": -0.5, 892*dbb99499SAndroid Build Coastguard Worker "real_time": 40, 893*dbb99499SAndroid Build Coastguard Worker "real_time_other": 20, 894*dbb99499SAndroid Build Coastguard Worker "cpu_time": 40, 895*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 20, 896*dbb99499SAndroid Build Coastguard Worker } 897*dbb99499SAndroid Build Coastguard Worker ], 898*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 899*dbb99499SAndroid Build Coastguard Worker "utest": {}, 900*dbb99499SAndroid Build Coastguard Worker }, 901*dbb99499SAndroid Build Coastguard Worker { 902*dbb99499SAndroid Build Coastguard Worker "name": "Prefix/.", 903*dbb99499SAndroid Build Coastguard Worker "measurements": [ 904*dbb99499SAndroid Build Coastguard Worker { 905*dbb99499SAndroid Build Coastguard Worker "time": -0.5, 906*dbb99499SAndroid Build Coastguard Worker "cpu": -0.5, 907*dbb99499SAndroid Build Coastguard Worker "real_time": 20, 908*dbb99499SAndroid Build Coastguard Worker "real_time_other": 10, 909*dbb99499SAndroid Build Coastguard Worker "cpu_time": 20, 910*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 10, 911*dbb99499SAndroid Build Coastguard Worker } 912*dbb99499SAndroid Build Coastguard Worker ], 913*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 914*dbb99499SAndroid Build Coastguard Worker "utest": {}, 915*dbb99499SAndroid Build Coastguard Worker }, 916*dbb99499SAndroid Build Coastguard Worker { 917*dbb99499SAndroid Build Coastguard Worker "name": "Prefix/./3", 918*dbb99499SAndroid Build Coastguard Worker "measurements": [ 919*dbb99499SAndroid Build Coastguard Worker { 920*dbb99499SAndroid Build Coastguard Worker "time": -0.5, 921*dbb99499SAndroid Build Coastguard Worker "cpu": -0.5, 922*dbb99499SAndroid Build Coastguard Worker "real_time": 30, 923*dbb99499SAndroid Build Coastguard Worker "real_time_other": 15, 924*dbb99499SAndroid Build Coastguard Worker "cpu_time": 30, 925*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 15, 926*dbb99499SAndroid Build Coastguard Worker } 927*dbb99499SAndroid Build Coastguard Worker ], 928*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 929*dbb99499SAndroid Build Coastguard Worker "utest": {}, 930*dbb99499SAndroid Build Coastguard Worker }, 931*dbb99499SAndroid Build Coastguard Worker { 932*dbb99499SAndroid Build Coastguard Worker "name": "OVERALL_GEOMEAN", 933*dbb99499SAndroid Build Coastguard Worker "measurements": [ 934*dbb99499SAndroid Build Coastguard Worker { 935*dbb99499SAndroid Build Coastguard Worker "real_time": 2.213363839400641e-08, 936*dbb99499SAndroid Build Coastguard Worker "cpu_time": 2.213363839400641e-08, 937*dbb99499SAndroid Build Coastguard Worker "real_time_other": 1.1066819197003185e-08, 938*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 1.1066819197003185e-08, 939*dbb99499SAndroid Build Coastguard Worker "time": -0.5000000000000009, 940*dbb99499SAndroid Build Coastguard Worker "cpu": -0.5000000000000009, 941*dbb99499SAndroid Build Coastguard Worker } 942*dbb99499SAndroid Build Coastguard Worker ], 943*dbb99499SAndroid Build Coastguard Worker "time_unit": "s", 944*dbb99499SAndroid Build Coastguard Worker "run_type": "aggregate", 945*dbb99499SAndroid Build Coastguard Worker "aggregate_name": "geomean", 946*dbb99499SAndroid Build Coastguard Worker "utest": {}, 947*dbb99499SAndroid Build Coastguard Worker }, 948*dbb99499SAndroid Build Coastguard Worker ] 949*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(self.json_diff_report), len(expected_output)) 950*dbb99499SAndroid Build Coastguard Worker for out, expected in zip(self.json_diff_report, expected_output): 951*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["name"], expected["name"]) 952*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["time_unit"], expected["time_unit"]) 953*dbb99499SAndroid Build Coastguard Worker assert_utest(self, out, expected) 954*dbb99499SAndroid Build Coastguard Worker assert_measurements(self, out, expected) 955*dbb99499SAndroid Build Coastguard Worker 956*dbb99499SAndroid Build Coastguard Worker 957*dbb99499SAndroid Build Coastguard Workerclass TestReportDifferenceWithUTest(unittest.TestCase): 958*dbb99499SAndroid Build Coastguard Worker @classmethod 959*dbb99499SAndroid Build Coastguard Worker def setUpClass(cls): 960*dbb99499SAndroid Build Coastguard Worker def load_results(): 961*dbb99499SAndroid Build Coastguard Worker import json 962*dbb99499SAndroid Build Coastguard Worker 963*dbb99499SAndroid Build Coastguard Worker testInputs = os.path.join( 964*dbb99499SAndroid Build Coastguard Worker os.path.dirname(os.path.realpath(__file__)), "Inputs" 965*dbb99499SAndroid Build Coastguard Worker ) 966*dbb99499SAndroid Build Coastguard Worker testOutput1 = os.path.join(testInputs, "test3_run0.json") 967*dbb99499SAndroid Build Coastguard Worker testOutput2 = os.path.join(testInputs, "test3_run1.json") 968*dbb99499SAndroid Build Coastguard Worker with open(testOutput1, "r") as f: 969*dbb99499SAndroid Build Coastguard Worker json1 = json.load(f) 970*dbb99499SAndroid Build Coastguard Worker with open(testOutput2, "r") as f: 971*dbb99499SAndroid Build Coastguard Worker json2 = json.load(f) 972*dbb99499SAndroid Build Coastguard Worker return json1, json2 973*dbb99499SAndroid Build Coastguard Worker 974*dbb99499SAndroid Build Coastguard Worker json1, json2 = load_results() 975*dbb99499SAndroid Build Coastguard Worker cls.json_diff_report = get_difference_report(json1, json2, utest=True) 976*dbb99499SAndroid Build Coastguard Worker 977*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report_pretty_printing(self): 978*dbb99499SAndroid Build Coastguard Worker expect_lines = [ 979*dbb99499SAndroid Build Coastguard Worker ["BM_One", "-0.1000", "+0.1000", "10", "9", "100", "110"], 980*dbb99499SAndroid Build Coastguard Worker ["BM_Two", "+0.1111", "-0.0111", "9", "10", "90", "89"], 981*dbb99499SAndroid Build Coastguard Worker ["BM_Two", "-0.1250", "-0.1628", "8", "7", "86", "72"], 982*dbb99499SAndroid Build Coastguard Worker [ 983*dbb99499SAndroid Build Coastguard Worker "BM_Two_pvalue", 984*dbb99499SAndroid Build Coastguard Worker "1.0000", 985*dbb99499SAndroid Build Coastguard Worker "0.6667", 986*dbb99499SAndroid Build Coastguard Worker "U", 987*dbb99499SAndroid Build Coastguard Worker "Test,", 988*dbb99499SAndroid Build Coastguard Worker "Repetitions:", 989*dbb99499SAndroid Build Coastguard Worker "2", 990*dbb99499SAndroid Build Coastguard Worker "vs", 991*dbb99499SAndroid Build Coastguard Worker "2.", 992*dbb99499SAndroid Build Coastguard Worker "WARNING:", 993*dbb99499SAndroid Build Coastguard Worker "Results", 994*dbb99499SAndroid Build Coastguard Worker "unreliable!", 995*dbb99499SAndroid Build Coastguard Worker "9+", 996*dbb99499SAndroid Build Coastguard Worker "repetitions", 997*dbb99499SAndroid Build Coastguard Worker "recommended.", 998*dbb99499SAndroid Build Coastguard Worker ], 999*dbb99499SAndroid Build Coastguard Worker ["short", "-0.1250", "-0.0625", "8", "7", "80", "75"], 1000*dbb99499SAndroid Build Coastguard Worker ["short", "-0.4325", "-0.1351", "8", "5", "77", "67"], 1001*dbb99499SAndroid Build Coastguard Worker [ 1002*dbb99499SAndroid Build Coastguard Worker "short_pvalue", 1003*dbb99499SAndroid Build Coastguard Worker "0.7671", 1004*dbb99499SAndroid Build Coastguard Worker "0.2000", 1005*dbb99499SAndroid Build Coastguard Worker "U", 1006*dbb99499SAndroid Build Coastguard Worker "Test,", 1007*dbb99499SAndroid Build Coastguard Worker "Repetitions:", 1008*dbb99499SAndroid Build Coastguard Worker "2", 1009*dbb99499SAndroid Build Coastguard Worker "vs", 1010*dbb99499SAndroid Build Coastguard Worker "3.", 1011*dbb99499SAndroid Build Coastguard Worker "WARNING:", 1012*dbb99499SAndroid Build Coastguard Worker "Results", 1013*dbb99499SAndroid Build Coastguard Worker "unreliable!", 1014*dbb99499SAndroid Build Coastguard Worker "9+", 1015*dbb99499SAndroid Build Coastguard Worker "repetitions", 1016*dbb99499SAndroid Build Coastguard Worker "recommended.", 1017*dbb99499SAndroid Build Coastguard Worker ], 1018*dbb99499SAndroid Build Coastguard Worker ["medium", "-0.3750", "-0.3375", "8", "5", "80", "53"], 1019*dbb99499SAndroid Build Coastguard Worker ["OVERALL_GEOMEAN", "+1.6405", "-0.6985", "0", "0", "0", "0"], 1020*dbb99499SAndroid Build Coastguard Worker ] 1021*dbb99499SAndroid Build Coastguard Worker output_lines_with_header = print_difference_report( 1022*dbb99499SAndroid Build Coastguard Worker self.json_diff_report, utest=True, utest_alpha=0.05, use_color=False 1023*dbb99499SAndroid Build Coastguard Worker ) 1024*dbb99499SAndroid Build Coastguard Worker output_lines = output_lines_with_header[2:] 1025*dbb99499SAndroid Build Coastguard Worker print("\n") 1026*dbb99499SAndroid Build Coastguard Worker print("\n".join(output_lines_with_header)) 1027*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(output_lines), len(expect_lines)) 1028*dbb99499SAndroid Build Coastguard Worker for i in range(0, len(output_lines)): 1029*dbb99499SAndroid Build Coastguard Worker parts = [x for x in output_lines[i].split(" ") if x] 1030*dbb99499SAndroid Build Coastguard Worker self.assertEqual(expect_lines[i], parts) 1031*dbb99499SAndroid Build Coastguard Worker 1032*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report_pretty_printing_aggregates_only(self): 1033*dbb99499SAndroid Build Coastguard Worker expect_lines = [ 1034*dbb99499SAndroid Build Coastguard Worker ["BM_One", "-0.1000", "+0.1000", "10", "9", "100", "110"], 1035*dbb99499SAndroid Build Coastguard Worker [ 1036*dbb99499SAndroid Build Coastguard Worker "BM_Two_pvalue", 1037*dbb99499SAndroid Build Coastguard Worker "1.0000", 1038*dbb99499SAndroid Build Coastguard Worker "0.6667", 1039*dbb99499SAndroid Build Coastguard Worker "U", 1040*dbb99499SAndroid Build Coastguard Worker "Test,", 1041*dbb99499SAndroid Build Coastguard Worker "Repetitions:", 1042*dbb99499SAndroid Build Coastguard Worker "2", 1043*dbb99499SAndroid Build Coastguard Worker "vs", 1044*dbb99499SAndroid Build Coastguard Worker "2.", 1045*dbb99499SAndroid Build Coastguard Worker "WARNING:", 1046*dbb99499SAndroid Build Coastguard Worker "Results", 1047*dbb99499SAndroid Build Coastguard Worker "unreliable!", 1048*dbb99499SAndroid Build Coastguard Worker "9+", 1049*dbb99499SAndroid Build Coastguard Worker "repetitions", 1050*dbb99499SAndroid Build Coastguard Worker "recommended.", 1051*dbb99499SAndroid Build Coastguard Worker ], 1052*dbb99499SAndroid Build Coastguard Worker ["short", "-0.1250", "-0.0625", "8", "7", "80", "75"], 1053*dbb99499SAndroid Build Coastguard Worker ["short", "-0.4325", "-0.1351", "8", "5", "77", "67"], 1054*dbb99499SAndroid Build Coastguard Worker [ 1055*dbb99499SAndroid Build Coastguard Worker "short_pvalue", 1056*dbb99499SAndroid Build Coastguard Worker "0.7671", 1057*dbb99499SAndroid Build Coastguard Worker "0.2000", 1058*dbb99499SAndroid Build Coastguard Worker "U", 1059*dbb99499SAndroid Build Coastguard Worker "Test,", 1060*dbb99499SAndroid Build Coastguard Worker "Repetitions:", 1061*dbb99499SAndroid Build Coastguard Worker "2", 1062*dbb99499SAndroid Build Coastguard Worker "vs", 1063*dbb99499SAndroid Build Coastguard Worker "3.", 1064*dbb99499SAndroid Build Coastguard Worker "WARNING:", 1065*dbb99499SAndroid Build Coastguard Worker "Results", 1066*dbb99499SAndroid Build Coastguard Worker "unreliable!", 1067*dbb99499SAndroid Build Coastguard Worker "9+", 1068*dbb99499SAndroid Build Coastguard Worker "repetitions", 1069*dbb99499SAndroid Build Coastguard Worker "recommended.", 1070*dbb99499SAndroid Build Coastguard Worker ], 1071*dbb99499SAndroid Build Coastguard Worker ["OVERALL_GEOMEAN", "+1.6405", "-0.6985", "0", "0", "0", "0"], 1072*dbb99499SAndroid Build Coastguard Worker ] 1073*dbb99499SAndroid Build Coastguard Worker output_lines_with_header = print_difference_report( 1074*dbb99499SAndroid Build Coastguard Worker self.json_diff_report, 1075*dbb99499SAndroid Build Coastguard Worker include_aggregates_only=True, 1076*dbb99499SAndroid Build Coastguard Worker utest=True, 1077*dbb99499SAndroid Build Coastguard Worker utest_alpha=0.05, 1078*dbb99499SAndroid Build Coastguard Worker use_color=False, 1079*dbb99499SAndroid Build Coastguard Worker ) 1080*dbb99499SAndroid Build Coastguard Worker output_lines = output_lines_with_header[2:] 1081*dbb99499SAndroid Build Coastguard Worker print("\n") 1082*dbb99499SAndroid Build Coastguard Worker print("\n".join(output_lines_with_header)) 1083*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(output_lines), len(expect_lines)) 1084*dbb99499SAndroid Build Coastguard Worker for i in range(0, len(output_lines)): 1085*dbb99499SAndroid Build Coastguard Worker parts = [x for x in output_lines[i].split(" ") if x] 1086*dbb99499SAndroid Build Coastguard Worker self.assertEqual(expect_lines[i], parts) 1087*dbb99499SAndroid Build Coastguard Worker 1088*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report(self): 1089*dbb99499SAndroid Build Coastguard Worker expected_output = [ 1090*dbb99499SAndroid Build Coastguard Worker { 1091*dbb99499SAndroid Build Coastguard Worker "name": "BM_One", 1092*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1093*dbb99499SAndroid Build Coastguard Worker { 1094*dbb99499SAndroid Build Coastguard Worker "time": -0.1, 1095*dbb99499SAndroid Build Coastguard Worker "cpu": 0.1, 1096*dbb99499SAndroid Build Coastguard Worker "real_time": 10, 1097*dbb99499SAndroid Build Coastguard Worker "real_time_other": 9, 1098*dbb99499SAndroid Build Coastguard Worker "cpu_time": 100, 1099*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 110, 1100*dbb99499SAndroid Build Coastguard Worker } 1101*dbb99499SAndroid Build Coastguard Worker ], 1102*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 1103*dbb99499SAndroid Build Coastguard Worker "utest": {}, 1104*dbb99499SAndroid Build Coastguard Worker }, 1105*dbb99499SAndroid Build Coastguard Worker { 1106*dbb99499SAndroid Build Coastguard Worker "name": "BM_Two", 1107*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1108*dbb99499SAndroid Build Coastguard Worker { 1109*dbb99499SAndroid Build Coastguard Worker "time": 0.1111111111111111, 1110*dbb99499SAndroid Build Coastguard Worker "cpu": -0.011111111111111112, 1111*dbb99499SAndroid Build Coastguard Worker "real_time": 9, 1112*dbb99499SAndroid Build Coastguard Worker "real_time_other": 10, 1113*dbb99499SAndroid Build Coastguard Worker "cpu_time": 90, 1114*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 89, 1115*dbb99499SAndroid Build Coastguard Worker }, 1116*dbb99499SAndroid Build Coastguard Worker { 1117*dbb99499SAndroid Build Coastguard Worker "time": -0.125, 1118*dbb99499SAndroid Build Coastguard Worker "cpu": -0.16279069767441862, 1119*dbb99499SAndroid Build Coastguard Worker "real_time": 8, 1120*dbb99499SAndroid Build Coastguard Worker "real_time_other": 7, 1121*dbb99499SAndroid Build Coastguard Worker "cpu_time": 86, 1122*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 72, 1123*dbb99499SAndroid Build Coastguard Worker }, 1124*dbb99499SAndroid Build Coastguard Worker ], 1125*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 1126*dbb99499SAndroid Build Coastguard Worker "utest": { 1127*dbb99499SAndroid Build Coastguard Worker "have_optimal_repetitions": False, 1128*dbb99499SAndroid Build Coastguard Worker "cpu_pvalue": 0.6666666666666666, 1129*dbb99499SAndroid Build Coastguard Worker "time_pvalue": 1.0, 1130*dbb99499SAndroid Build Coastguard Worker }, 1131*dbb99499SAndroid Build Coastguard Worker }, 1132*dbb99499SAndroid Build Coastguard Worker { 1133*dbb99499SAndroid Build Coastguard Worker "name": "short", 1134*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1135*dbb99499SAndroid Build Coastguard Worker { 1136*dbb99499SAndroid Build Coastguard Worker "time": -0.125, 1137*dbb99499SAndroid Build Coastguard Worker "cpu": -0.0625, 1138*dbb99499SAndroid Build Coastguard Worker "real_time": 8, 1139*dbb99499SAndroid Build Coastguard Worker "real_time_other": 7, 1140*dbb99499SAndroid Build Coastguard Worker "cpu_time": 80, 1141*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 75, 1142*dbb99499SAndroid Build Coastguard Worker }, 1143*dbb99499SAndroid Build Coastguard Worker { 1144*dbb99499SAndroid Build Coastguard Worker "time": -0.4325, 1145*dbb99499SAndroid Build Coastguard Worker "cpu": -0.13506493506493514, 1146*dbb99499SAndroid Build Coastguard Worker "real_time": 8, 1147*dbb99499SAndroid Build Coastguard Worker "real_time_other": 4.54, 1148*dbb99499SAndroid Build Coastguard Worker "cpu_time": 77, 1149*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 66.6, 1150*dbb99499SAndroid Build Coastguard Worker }, 1151*dbb99499SAndroid Build Coastguard Worker ], 1152*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 1153*dbb99499SAndroid Build Coastguard Worker "utest": { 1154*dbb99499SAndroid Build Coastguard Worker "have_optimal_repetitions": False, 1155*dbb99499SAndroid Build Coastguard Worker "cpu_pvalue": 0.2, 1156*dbb99499SAndroid Build Coastguard Worker "time_pvalue": 0.7670968684102772, 1157*dbb99499SAndroid Build Coastguard Worker }, 1158*dbb99499SAndroid Build Coastguard Worker }, 1159*dbb99499SAndroid Build Coastguard Worker { 1160*dbb99499SAndroid Build Coastguard Worker "name": "medium", 1161*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1162*dbb99499SAndroid Build Coastguard Worker { 1163*dbb99499SAndroid Build Coastguard Worker "time": -0.375, 1164*dbb99499SAndroid Build Coastguard Worker "cpu": -0.3375, 1165*dbb99499SAndroid Build Coastguard Worker "real_time": 8, 1166*dbb99499SAndroid Build Coastguard Worker "real_time_other": 5, 1167*dbb99499SAndroid Build Coastguard Worker "cpu_time": 80, 1168*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 53, 1169*dbb99499SAndroid Build Coastguard Worker } 1170*dbb99499SAndroid Build Coastguard Worker ], 1171*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 1172*dbb99499SAndroid Build Coastguard Worker "utest": {}, 1173*dbb99499SAndroid Build Coastguard Worker }, 1174*dbb99499SAndroid Build Coastguard Worker { 1175*dbb99499SAndroid Build Coastguard Worker "name": "OVERALL_GEOMEAN", 1176*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1177*dbb99499SAndroid Build Coastguard Worker { 1178*dbb99499SAndroid Build Coastguard Worker "real_time": 8.48528137423858e-09, 1179*dbb99499SAndroid Build Coastguard Worker "cpu_time": 8.441336246629233e-08, 1180*dbb99499SAndroid Build Coastguard Worker "real_time_other": 2.2405267593145244e-08, 1181*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 2.5453661413660466e-08, 1182*dbb99499SAndroid Build Coastguard Worker "time": 1.6404861082353634, 1183*dbb99499SAndroid Build Coastguard Worker "cpu": -0.6984640740519662, 1184*dbb99499SAndroid Build Coastguard Worker } 1185*dbb99499SAndroid Build Coastguard Worker ], 1186*dbb99499SAndroid Build Coastguard Worker "time_unit": "s", 1187*dbb99499SAndroid Build Coastguard Worker "run_type": "aggregate", 1188*dbb99499SAndroid Build Coastguard Worker "aggregate_name": "geomean", 1189*dbb99499SAndroid Build Coastguard Worker "utest": {}, 1190*dbb99499SAndroid Build Coastguard Worker }, 1191*dbb99499SAndroid Build Coastguard Worker ] 1192*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(self.json_diff_report), len(expected_output)) 1193*dbb99499SAndroid Build Coastguard Worker for out, expected in zip(self.json_diff_report, expected_output): 1194*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["name"], expected["name"]) 1195*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["time_unit"], expected["time_unit"]) 1196*dbb99499SAndroid Build Coastguard Worker assert_utest(self, out, expected) 1197*dbb99499SAndroid Build Coastguard Worker assert_measurements(self, out, expected) 1198*dbb99499SAndroid Build Coastguard Worker 1199*dbb99499SAndroid Build Coastguard Worker 1200*dbb99499SAndroid Build Coastguard Workerclass TestReportDifferenceWithUTestWhileDisplayingAggregatesOnly( 1201*dbb99499SAndroid Build Coastguard Worker unittest.TestCase 1202*dbb99499SAndroid Build Coastguard Worker): 1203*dbb99499SAndroid Build Coastguard Worker @classmethod 1204*dbb99499SAndroid Build Coastguard Worker def setUpClass(cls): 1205*dbb99499SAndroid Build Coastguard Worker def load_results(): 1206*dbb99499SAndroid Build Coastguard Worker import json 1207*dbb99499SAndroid Build Coastguard Worker 1208*dbb99499SAndroid Build Coastguard Worker testInputs = os.path.join( 1209*dbb99499SAndroid Build Coastguard Worker os.path.dirname(os.path.realpath(__file__)), "Inputs" 1210*dbb99499SAndroid Build Coastguard Worker ) 1211*dbb99499SAndroid Build Coastguard Worker testOutput1 = os.path.join(testInputs, "test3_run0.json") 1212*dbb99499SAndroid Build Coastguard Worker testOutput2 = os.path.join(testInputs, "test3_run1.json") 1213*dbb99499SAndroid Build Coastguard Worker with open(testOutput1, "r") as f: 1214*dbb99499SAndroid Build Coastguard Worker json1 = json.load(f) 1215*dbb99499SAndroid Build Coastguard Worker with open(testOutput2, "r") as f: 1216*dbb99499SAndroid Build Coastguard Worker json2 = json.load(f) 1217*dbb99499SAndroid Build Coastguard Worker return json1, json2 1218*dbb99499SAndroid Build Coastguard Worker 1219*dbb99499SAndroid Build Coastguard Worker json1, json2 = load_results() 1220*dbb99499SAndroid Build Coastguard Worker cls.json_diff_report = get_difference_report(json1, json2, utest=True) 1221*dbb99499SAndroid Build Coastguard Worker 1222*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report_pretty_printing(self): 1223*dbb99499SAndroid Build Coastguard Worker expect_lines = [ 1224*dbb99499SAndroid Build Coastguard Worker ["BM_One", "-0.1000", "+0.1000", "10", "9", "100", "110"], 1225*dbb99499SAndroid Build Coastguard Worker ["BM_Two", "+0.1111", "-0.0111", "9", "10", "90", "89"], 1226*dbb99499SAndroid Build Coastguard Worker ["BM_Two", "-0.1250", "-0.1628", "8", "7", "86", "72"], 1227*dbb99499SAndroid Build Coastguard Worker [ 1228*dbb99499SAndroid Build Coastguard Worker "BM_Two_pvalue", 1229*dbb99499SAndroid Build Coastguard Worker "1.0000", 1230*dbb99499SAndroid Build Coastguard Worker "0.6667", 1231*dbb99499SAndroid Build Coastguard Worker "U", 1232*dbb99499SAndroid Build Coastguard Worker "Test,", 1233*dbb99499SAndroid Build Coastguard Worker "Repetitions:", 1234*dbb99499SAndroid Build Coastguard Worker "2", 1235*dbb99499SAndroid Build Coastguard Worker "vs", 1236*dbb99499SAndroid Build Coastguard Worker "2.", 1237*dbb99499SAndroid Build Coastguard Worker "WARNING:", 1238*dbb99499SAndroid Build Coastguard Worker "Results", 1239*dbb99499SAndroid Build Coastguard Worker "unreliable!", 1240*dbb99499SAndroid Build Coastguard Worker "9+", 1241*dbb99499SAndroid Build Coastguard Worker "repetitions", 1242*dbb99499SAndroid Build Coastguard Worker "recommended.", 1243*dbb99499SAndroid Build Coastguard Worker ], 1244*dbb99499SAndroid Build Coastguard Worker ["short", "-0.1250", "-0.0625", "8", "7", "80", "75"], 1245*dbb99499SAndroid Build Coastguard Worker ["short", "-0.4325", "-0.1351", "8", "5", "77", "67"], 1246*dbb99499SAndroid Build Coastguard Worker [ 1247*dbb99499SAndroid Build Coastguard Worker "short_pvalue", 1248*dbb99499SAndroid Build Coastguard Worker "0.7671", 1249*dbb99499SAndroid Build Coastguard Worker "0.2000", 1250*dbb99499SAndroid Build Coastguard Worker "U", 1251*dbb99499SAndroid Build Coastguard Worker "Test,", 1252*dbb99499SAndroid Build Coastguard Worker "Repetitions:", 1253*dbb99499SAndroid Build Coastguard Worker "2", 1254*dbb99499SAndroid Build Coastguard Worker "vs", 1255*dbb99499SAndroid Build Coastguard Worker "3.", 1256*dbb99499SAndroid Build Coastguard Worker "WARNING:", 1257*dbb99499SAndroid Build Coastguard Worker "Results", 1258*dbb99499SAndroid Build Coastguard Worker "unreliable!", 1259*dbb99499SAndroid Build Coastguard Worker "9+", 1260*dbb99499SAndroid Build Coastguard Worker "repetitions", 1261*dbb99499SAndroid Build Coastguard Worker "recommended.", 1262*dbb99499SAndroid Build Coastguard Worker ], 1263*dbb99499SAndroid Build Coastguard Worker ["medium", "-0.3750", "-0.3375", "8", "5", "80", "53"], 1264*dbb99499SAndroid Build Coastguard Worker ["OVERALL_GEOMEAN", "+1.6405", "-0.6985", "0", "0", "0", "0"], 1265*dbb99499SAndroid Build Coastguard Worker ] 1266*dbb99499SAndroid Build Coastguard Worker output_lines_with_header = print_difference_report( 1267*dbb99499SAndroid Build Coastguard Worker self.json_diff_report, utest=True, utest_alpha=0.05, use_color=False 1268*dbb99499SAndroid Build Coastguard Worker ) 1269*dbb99499SAndroid Build Coastguard Worker output_lines = output_lines_with_header[2:] 1270*dbb99499SAndroid Build Coastguard Worker print("\n") 1271*dbb99499SAndroid Build Coastguard Worker print("\n".join(output_lines_with_header)) 1272*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(output_lines), len(expect_lines)) 1273*dbb99499SAndroid Build Coastguard Worker for i in range(0, len(output_lines)): 1274*dbb99499SAndroid Build Coastguard Worker parts = [x for x in output_lines[i].split(" ") if x] 1275*dbb99499SAndroid Build Coastguard Worker self.assertEqual(expect_lines[i], parts) 1276*dbb99499SAndroid Build Coastguard Worker 1277*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report(self): 1278*dbb99499SAndroid Build Coastguard Worker expected_output = [ 1279*dbb99499SAndroid Build Coastguard Worker { 1280*dbb99499SAndroid Build Coastguard Worker "name": "BM_One", 1281*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1282*dbb99499SAndroid Build Coastguard Worker { 1283*dbb99499SAndroid Build Coastguard Worker "time": -0.1, 1284*dbb99499SAndroid Build Coastguard Worker "cpu": 0.1, 1285*dbb99499SAndroid Build Coastguard Worker "real_time": 10, 1286*dbb99499SAndroid Build Coastguard Worker "real_time_other": 9, 1287*dbb99499SAndroid Build Coastguard Worker "cpu_time": 100, 1288*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 110, 1289*dbb99499SAndroid Build Coastguard Worker } 1290*dbb99499SAndroid Build Coastguard Worker ], 1291*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 1292*dbb99499SAndroid Build Coastguard Worker "utest": {}, 1293*dbb99499SAndroid Build Coastguard Worker }, 1294*dbb99499SAndroid Build Coastguard Worker { 1295*dbb99499SAndroid Build Coastguard Worker "name": "BM_Two", 1296*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1297*dbb99499SAndroid Build Coastguard Worker { 1298*dbb99499SAndroid Build Coastguard Worker "time": 0.1111111111111111, 1299*dbb99499SAndroid Build Coastguard Worker "cpu": -0.011111111111111112, 1300*dbb99499SAndroid Build Coastguard Worker "real_time": 9, 1301*dbb99499SAndroid Build Coastguard Worker "real_time_other": 10, 1302*dbb99499SAndroid Build Coastguard Worker "cpu_time": 90, 1303*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 89, 1304*dbb99499SAndroid Build Coastguard Worker }, 1305*dbb99499SAndroid Build Coastguard Worker { 1306*dbb99499SAndroid Build Coastguard Worker "time": -0.125, 1307*dbb99499SAndroid Build Coastguard Worker "cpu": -0.16279069767441862, 1308*dbb99499SAndroid Build Coastguard Worker "real_time": 8, 1309*dbb99499SAndroid Build Coastguard Worker "real_time_other": 7, 1310*dbb99499SAndroid Build Coastguard Worker "cpu_time": 86, 1311*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 72, 1312*dbb99499SAndroid Build Coastguard Worker }, 1313*dbb99499SAndroid Build Coastguard Worker ], 1314*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 1315*dbb99499SAndroid Build Coastguard Worker "utest": { 1316*dbb99499SAndroid Build Coastguard Worker "have_optimal_repetitions": False, 1317*dbb99499SAndroid Build Coastguard Worker "cpu_pvalue": 0.6666666666666666, 1318*dbb99499SAndroid Build Coastguard Worker "time_pvalue": 1.0, 1319*dbb99499SAndroid Build Coastguard Worker }, 1320*dbb99499SAndroid Build Coastguard Worker }, 1321*dbb99499SAndroid Build Coastguard Worker { 1322*dbb99499SAndroid Build Coastguard Worker "name": "short", 1323*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1324*dbb99499SAndroid Build Coastguard Worker { 1325*dbb99499SAndroid Build Coastguard Worker "time": -0.125, 1326*dbb99499SAndroid Build Coastguard Worker "cpu": -0.0625, 1327*dbb99499SAndroid Build Coastguard Worker "real_time": 8, 1328*dbb99499SAndroid Build Coastguard Worker "real_time_other": 7, 1329*dbb99499SAndroid Build Coastguard Worker "cpu_time": 80, 1330*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 75, 1331*dbb99499SAndroid Build Coastguard Worker }, 1332*dbb99499SAndroid Build Coastguard Worker { 1333*dbb99499SAndroid Build Coastguard Worker "time": -0.4325, 1334*dbb99499SAndroid Build Coastguard Worker "cpu": -0.13506493506493514, 1335*dbb99499SAndroid Build Coastguard Worker "real_time": 8, 1336*dbb99499SAndroid Build Coastguard Worker "real_time_other": 4.54, 1337*dbb99499SAndroid Build Coastguard Worker "cpu_time": 77, 1338*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 66.6, 1339*dbb99499SAndroid Build Coastguard Worker }, 1340*dbb99499SAndroid Build Coastguard Worker ], 1341*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 1342*dbb99499SAndroid Build Coastguard Worker "utest": { 1343*dbb99499SAndroid Build Coastguard Worker "have_optimal_repetitions": False, 1344*dbb99499SAndroid Build Coastguard Worker "cpu_pvalue": 0.2, 1345*dbb99499SAndroid Build Coastguard Worker "time_pvalue": 0.7670968684102772, 1346*dbb99499SAndroid Build Coastguard Worker }, 1347*dbb99499SAndroid Build Coastguard Worker }, 1348*dbb99499SAndroid Build Coastguard Worker { 1349*dbb99499SAndroid Build Coastguard Worker "name": "medium", 1350*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1351*dbb99499SAndroid Build Coastguard Worker { 1352*dbb99499SAndroid Build Coastguard Worker "real_time_other": 5, 1353*dbb99499SAndroid Build Coastguard Worker "cpu_time": 80, 1354*dbb99499SAndroid Build Coastguard Worker "time": -0.375, 1355*dbb99499SAndroid Build Coastguard Worker "real_time": 8, 1356*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 53, 1357*dbb99499SAndroid Build Coastguard Worker "cpu": -0.3375, 1358*dbb99499SAndroid Build Coastguard Worker } 1359*dbb99499SAndroid Build Coastguard Worker ], 1360*dbb99499SAndroid Build Coastguard Worker "utest": {}, 1361*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 1362*dbb99499SAndroid Build Coastguard Worker "aggregate_name": "", 1363*dbb99499SAndroid Build Coastguard Worker }, 1364*dbb99499SAndroid Build Coastguard Worker { 1365*dbb99499SAndroid Build Coastguard Worker "name": "OVERALL_GEOMEAN", 1366*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1367*dbb99499SAndroid Build Coastguard Worker { 1368*dbb99499SAndroid Build Coastguard Worker "real_time": 8.48528137423858e-09, 1369*dbb99499SAndroid Build Coastguard Worker "cpu_time": 8.441336246629233e-08, 1370*dbb99499SAndroid Build Coastguard Worker "real_time_other": 2.2405267593145244e-08, 1371*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 2.5453661413660466e-08, 1372*dbb99499SAndroid Build Coastguard Worker "time": 1.6404861082353634, 1373*dbb99499SAndroid Build Coastguard Worker "cpu": -0.6984640740519662, 1374*dbb99499SAndroid Build Coastguard Worker } 1375*dbb99499SAndroid Build Coastguard Worker ], 1376*dbb99499SAndroid Build Coastguard Worker "time_unit": "s", 1377*dbb99499SAndroid Build Coastguard Worker "run_type": "aggregate", 1378*dbb99499SAndroid Build Coastguard Worker "aggregate_name": "geomean", 1379*dbb99499SAndroid Build Coastguard Worker "utest": {}, 1380*dbb99499SAndroid Build Coastguard Worker }, 1381*dbb99499SAndroid Build Coastguard Worker ] 1382*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(self.json_diff_report), len(expected_output)) 1383*dbb99499SAndroid Build Coastguard Worker for out, expected in zip(self.json_diff_report, expected_output): 1384*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["name"], expected["name"]) 1385*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["time_unit"], expected["time_unit"]) 1386*dbb99499SAndroid Build Coastguard Worker assert_utest(self, out, expected) 1387*dbb99499SAndroid Build Coastguard Worker assert_measurements(self, out, expected) 1388*dbb99499SAndroid Build Coastguard Worker 1389*dbb99499SAndroid Build Coastguard Worker 1390*dbb99499SAndroid Build Coastguard Workerclass TestReportDifferenceForPercentageAggregates(unittest.TestCase): 1391*dbb99499SAndroid Build Coastguard Worker @classmethod 1392*dbb99499SAndroid Build Coastguard Worker def setUpClass(cls): 1393*dbb99499SAndroid Build Coastguard Worker def load_results(): 1394*dbb99499SAndroid Build Coastguard Worker import json 1395*dbb99499SAndroid Build Coastguard Worker 1396*dbb99499SAndroid Build Coastguard Worker testInputs = os.path.join( 1397*dbb99499SAndroid Build Coastguard Worker os.path.dirname(os.path.realpath(__file__)), "Inputs" 1398*dbb99499SAndroid Build Coastguard Worker ) 1399*dbb99499SAndroid Build Coastguard Worker testOutput1 = os.path.join(testInputs, "test4_run0.json") 1400*dbb99499SAndroid Build Coastguard Worker testOutput2 = os.path.join(testInputs, "test4_run1.json") 1401*dbb99499SAndroid Build Coastguard Worker with open(testOutput1, "r") as f: 1402*dbb99499SAndroid Build Coastguard Worker json1 = json.load(f) 1403*dbb99499SAndroid Build Coastguard Worker with open(testOutput2, "r") as f: 1404*dbb99499SAndroid Build Coastguard Worker json2 = json.load(f) 1405*dbb99499SAndroid Build Coastguard Worker return json1, json2 1406*dbb99499SAndroid Build Coastguard Worker 1407*dbb99499SAndroid Build Coastguard Worker json1, json2 = load_results() 1408*dbb99499SAndroid Build Coastguard Worker cls.json_diff_report = get_difference_report(json1, json2, utest=True) 1409*dbb99499SAndroid Build Coastguard Worker 1410*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report_pretty_printing(self): 1411*dbb99499SAndroid Build Coastguard Worker expect_lines = [["whocares", "-0.5000", "+0.5000", "0", "0", "0", "0"]] 1412*dbb99499SAndroid Build Coastguard Worker output_lines_with_header = print_difference_report( 1413*dbb99499SAndroid Build Coastguard Worker self.json_diff_report, utest=True, utest_alpha=0.05, use_color=False 1414*dbb99499SAndroid Build Coastguard Worker ) 1415*dbb99499SAndroid Build Coastguard Worker output_lines = output_lines_with_header[2:] 1416*dbb99499SAndroid Build Coastguard Worker print("\n") 1417*dbb99499SAndroid Build Coastguard Worker print("\n".join(output_lines_with_header)) 1418*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(output_lines), len(expect_lines)) 1419*dbb99499SAndroid Build Coastguard Worker for i in range(0, len(output_lines)): 1420*dbb99499SAndroid Build Coastguard Worker parts = [x for x in output_lines[i].split(" ") if x] 1421*dbb99499SAndroid Build Coastguard Worker self.assertEqual(expect_lines[i], parts) 1422*dbb99499SAndroid Build Coastguard Worker 1423*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report(self): 1424*dbb99499SAndroid Build Coastguard Worker expected_output = [ 1425*dbb99499SAndroid Build Coastguard Worker { 1426*dbb99499SAndroid Build Coastguard Worker "name": "whocares", 1427*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1428*dbb99499SAndroid Build Coastguard Worker { 1429*dbb99499SAndroid Build Coastguard Worker "time": -0.5, 1430*dbb99499SAndroid Build Coastguard Worker "cpu": 0.5, 1431*dbb99499SAndroid Build Coastguard Worker "real_time": 0.01, 1432*dbb99499SAndroid Build Coastguard Worker "real_time_other": 0.005, 1433*dbb99499SAndroid Build Coastguard Worker "cpu_time": 0.10, 1434*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 0.15, 1435*dbb99499SAndroid Build Coastguard Worker } 1436*dbb99499SAndroid Build Coastguard Worker ], 1437*dbb99499SAndroid Build Coastguard Worker "time_unit": "ns", 1438*dbb99499SAndroid Build Coastguard Worker "utest": {}, 1439*dbb99499SAndroid Build Coastguard Worker } 1440*dbb99499SAndroid Build Coastguard Worker ] 1441*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(self.json_diff_report), len(expected_output)) 1442*dbb99499SAndroid Build Coastguard Worker for out, expected in zip(self.json_diff_report, expected_output): 1443*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["name"], expected["name"]) 1444*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["time_unit"], expected["time_unit"]) 1445*dbb99499SAndroid Build Coastguard Worker assert_utest(self, out, expected) 1446*dbb99499SAndroid Build Coastguard Worker assert_measurements(self, out, expected) 1447*dbb99499SAndroid Build Coastguard Worker 1448*dbb99499SAndroid Build Coastguard Worker 1449*dbb99499SAndroid Build Coastguard Workerclass TestReportSorting(unittest.TestCase): 1450*dbb99499SAndroid Build Coastguard Worker @classmethod 1451*dbb99499SAndroid Build Coastguard Worker def setUpClass(cls): 1452*dbb99499SAndroid Build Coastguard Worker def load_result(): 1453*dbb99499SAndroid Build Coastguard Worker import json 1454*dbb99499SAndroid Build Coastguard Worker 1455*dbb99499SAndroid Build Coastguard Worker testInputs = os.path.join( 1456*dbb99499SAndroid Build Coastguard Worker os.path.dirname(os.path.realpath(__file__)), "Inputs" 1457*dbb99499SAndroid Build Coastguard Worker ) 1458*dbb99499SAndroid Build Coastguard Worker testOutput = os.path.join(testInputs, "test4_run.json") 1459*dbb99499SAndroid Build Coastguard Worker with open(testOutput, "r") as f: 1460*dbb99499SAndroid Build Coastguard Worker json = json.load(f) 1461*dbb99499SAndroid Build Coastguard Worker return json 1462*dbb99499SAndroid Build Coastguard Worker 1463*dbb99499SAndroid Build Coastguard Worker cls.json = load_result() 1464*dbb99499SAndroid Build Coastguard Worker 1465*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report_pretty_printing(self): 1466*dbb99499SAndroid Build Coastguard Worker import util 1467*dbb99499SAndroid Build Coastguard Worker 1468*dbb99499SAndroid Build Coastguard Worker expected_names = [ 1469*dbb99499SAndroid Build Coastguard Worker "99 family 0 instance 0 repetition 0", 1470*dbb99499SAndroid Build Coastguard Worker "98 family 0 instance 0 repetition 1", 1471*dbb99499SAndroid Build Coastguard Worker "97 family 0 instance 0 aggregate", 1472*dbb99499SAndroid Build Coastguard Worker "96 family 0 instance 1 repetition 0", 1473*dbb99499SAndroid Build Coastguard Worker "95 family 0 instance 1 repetition 1", 1474*dbb99499SAndroid Build Coastguard Worker "94 family 0 instance 1 aggregate", 1475*dbb99499SAndroid Build Coastguard Worker "93 family 1 instance 0 repetition 0", 1476*dbb99499SAndroid Build Coastguard Worker "92 family 1 instance 0 repetition 1", 1477*dbb99499SAndroid Build Coastguard Worker "91 family 1 instance 0 aggregate", 1478*dbb99499SAndroid Build Coastguard Worker "90 family 1 instance 1 repetition 0", 1479*dbb99499SAndroid Build Coastguard Worker "89 family 1 instance 1 repetition 1", 1480*dbb99499SAndroid Build Coastguard Worker "88 family 1 instance 1 aggregate", 1481*dbb99499SAndroid Build Coastguard Worker ] 1482*dbb99499SAndroid Build Coastguard Worker 1483*dbb99499SAndroid Build Coastguard Worker for n in range(len(self.json["benchmarks"]) ** 2): 1484*dbb99499SAndroid Build Coastguard Worker random.shuffle(self.json["benchmarks"]) 1485*dbb99499SAndroid Build Coastguard Worker sorted_benchmarks = util.sort_benchmark_results(self.json)[ 1486*dbb99499SAndroid Build Coastguard Worker "benchmarks" 1487*dbb99499SAndroid Build Coastguard Worker ] 1488*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(expected_names), len(sorted_benchmarks)) 1489*dbb99499SAndroid Build Coastguard Worker for out, expected in zip(sorted_benchmarks, expected_names): 1490*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["name"], expected) 1491*dbb99499SAndroid Build Coastguard Worker 1492*dbb99499SAndroid Build Coastguard Worker 1493*dbb99499SAndroid Build Coastguard Workerclass TestReportDifferenceWithUTestWhileDisplayingAggregatesOnly2( 1494*dbb99499SAndroid Build Coastguard Worker unittest.TestCase 1495*dbb99499SAndroid Build Coastguard Worker): 1496*dbb99499SAndroid Build Coastguard Worker @classmethod 1497*dbb99499SAndroid Build Coastguard Worker def setUpClass(cls): 1498*dbb99499SAndroid Build Coastguard Worker def load_results(): 1499*dbb99499SAndroid Build Coastguard Worker import json 1500*dbb99499SAndroid Build Coastguard Worker 1501*dbb99499SAndroid Build Coastguard Worker testInputs = os.path.join( 1502*dbb99499SAndroid Build Coastguard Worker os.path.dirname(os.path.realpath(__file__)), "Inputs" 1503*dbb99499SAndroid Build Coastguard Worker ) 1504*dbb99499SAndroid Build Coastguard Worker testOutput1 = os.path.join(testInputs, "test5_run0.json") 1505*dbb99499SAndroid Build Coastguard Worker testOutput2 = os.path.join(testInputs, "test5_run1.json") 1506*dbb99499SAndroid Build Coastguard Worker with open(testOutput1, "r") as f: 1507*dbb99499SAndroid Build Coastguard Worker json1 = json.load(f) 1508*dbb99499SAndroid Build Coastguard Worker json1["benchmarks"] = [ 1509*dbb99499SAndroid Build Coastguard Worker json1["benchmarks"][0] for i in range(1000) 1510*dbb99499SAndroid Build Coastguard Worker ] 1511*dbb99499SAndroid Build Coastguard Worker with open(testOutput2, "r") as f: 1512*dbb99499SAndroid Build Coastguard Worker json2 = json.load(f) 1513*dbb99499SAndroid Build Coastguard Worker json2["benchmarks"] = [ 1514*dbb99499SAndroid Build Coastguard Worker json2["benchmarks"][0] for i in range(1000) 1515*dbb99499SAndroid Build Coastguard Worker ] 1516*dbb99499SAndroid Build Coastguard Worker return json1, json2 1517*dbb99499SAndroid Build Coastguard Worker 1518*dbb99499SAndroid Build Coastguard Worker json1, json2 = load_results() 1519*dbb99499SAndroid Build Coastguard Worker cls.json_diff_report = get_difference_report(json1, json2, utest=True) 1520*dbb99499SAndroid Build Coastguard Worker 1521*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report_pretty_printing(self): 1522*dbb99499SAndroid Build Coastguard Worker expect_line = [ 1523*dbb99499SAndroid Build Coastguard Worker "BM_ManyRepetitions_pvalue", 1524*dbb99499SAndroid Build Coastguard Worker "0.0000", 1525*dbb99499SAndroid Build Coastguard Worker "0.0000", 1526*dbb99499SAndroid Build Coastguard Worker "U", 1527*dbb99499SAndroid Build Coastguard Worker "Test,", 1528*dbb99499SAndroid Build Coastguard Worker "Repetitions:", 1529*dbb99499SAndroid Build Coastguard Worker "1000", 1530*dbb99499SAndroid Build Coastguard Worker "vs", 1531*dbb99499SAndroid Build Coastguard Worker "1000", 1532*dbb99499SAndroid Build Coastguard Worker ] 1533*dbb99499SAndroid Build Coastguard Worker output_lines_with_header = print_difference_report( 1534*dbb99499SAndroid Build Coastguard Worker self.json_diff_report, utest=True, utest_alpha=0.05, use_color=False 1535*dbb99499SAndroid Build Coastguard Worker ) 1536*dbb99499SAndroid Build Coastguard Worker output_lines = output_lines_with_header[2:] 1537*dbb99499SAndroid Build Coastguard Worker found = False 1538*dbb99499SAndroid Build Coastguard Worker for i in range(0, len(output_lines)): 1539*dbb99499SAndroid Build Coastguard Worker parts = [x for x in output_lines[i].split(" ") if x] 1540*dbb99499SAndroid Build Coastguard Worker found = expect_line == parts 1541*dbb99499SAndroid Build Coastguard Worker if found: 1542*dbb99499SAndroid Build Coastguard Worker break 1543*dbb99499SAndroid Build Coastguard Worker self.assertTrue(found) 1544*dbb99499SAndroid Build Coastguard Worker 1545*dbb99499SAndroid Build Coastguard Worker def test_json_diff_report(self): 1546*dbb99499SAndroid Build Coastguard Worker expected_output = [ 1547*dbb99499SAndroid Build Coastguard Worker { 1548*dbb99499SAndroid Build Coastguard Worker "name": "BM_ManyRepetitions", 1549*dbb99499SAndroid Build Coastguard Worker "label": "", 1550*dbb99499SAndroid Build Coastguard Worker "time_unit": "s", 1551*dbb99499SAndroid Build Coastguard Worker "run_type": "", 1552*dbb99499SAndroid Build Coastguard Worker "aggregate_name": "", 1553*dbb99499SAndroid Build Coastguard Worker "utest": { 1554*dbb99499SAndroid Build Coastguard Worker "have_optimal_repetitions": True, 1555*dbb99499SAndroid Build Coastguard Worker "cpu_pvalue": 0.0, 1556*dbb99499SAndroid Build Coastguard Worker "time_pvalue": 0.0, 1557*dbb99499SAndroid Build Coastguard Worker "nr_of_repetitions": 1000, 1558*dbb99499SAndroid Build Coastguard Worker "nr_of_repetitions_other": 1000, 1559*dbb99499SAndroid Build Coastguard Worker }, 1560*dbb99499SAndroid Build Coastguard Worker }, 1561*dbb99499SAndroid Build Coastguard Worker { 1562*dbb99499SAndroid Build Coastguard Worker "name": "OVERALL_GEOMEAN", 1563*dbb99499SAndroid Build Coastguard Worker "label": "", 1564*dbb99499SAndroid Build Coastguard Worker "measurements": [ 1565*dbb99499SAndroid Build Coastguard Worker { 1566*dbb99499SAndroid Build Coastguard Worker "real_time": 1.0, 1567*dbb99499SAndroid Build Coastguard Worker "cpu_time": 1000.000000000069, 1568*dbb99499SAndroid Build Coastguard Worker "real_time_other": 1000.000000000069, 1569*dbb99499SAndroid Build Coastguard Worker "cpu_time_other": 1.0, 1570*dbb99499SAndroid Build Coastguard Worker "time": 999.000000000069, 1571*dbb99499SAndroid Build Coastguard Worker "cpu": -0.9990000000000001, 1572*dbb99499SAndroid Build Coastguard Worker } 1573*dbb99499SAndroid Build Coastguard Worker ], 1574*dbb99499SAndroid Build Coastguard Worker "time_unit": "s", 1575*dbb99499SAndroid Build Coastguard Worker "run_type": "aggregate", 1576*dbb99499SAndroid Build Coastguard Worker "aggregate_name": "geomean", 1577*dbb99499SAndroid Build Coastguard Worker "utest": {}, 1578*dbb99499SAndroid Build Coastguard Worker }, 1579*dbb99499SAndroid Build Coastguard Worker ] 1580*dbb99499SAndroid Build Coastguard Worker self.assertEqual(len(self.json_diff_report), len(expected_output)) 1581*dbb99499SAndroid Build Coastguard Worker for out, expected in zip(self.json_diff_report, expected_output): 1582*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["name"], expected["name"]) 1583*dbb99499SAndroid Build Coastguard Worker self.assertEqual(out["time_unit"], expected["time_unit"]) 1584*dbb99499SAndroid Build Coastguard Worker assert_utest(self, out, expected) 1585*dbb99499SAndroid Build Coastguard Worker 1586*dbb99499SAndroid Build Coastguard Worker 1587*dbb99499SAndroid Build Coastguard Workerdef assert_utest(unittest_instance, lhs, rhs): 1588*dbb99499SAndroid Build Coastguard Worker if lhs["utest"]: 1589*dbb99499SAndroid Build Coastguard Worker unittest_instance.assertAlmostEqual( 1590*dbb99499SAndroid Build Coastguard Worker lhs["utest"]["cpu_pvalue"], rhs["utest"]["cpu_pvalue"] 1591*dbb99499SAndroid Build Coastguard Worker ) 1592*dbb99499SAndroid Build Coastguard Worker unittest_instance.assertAlmostEqual( 1593*dbb99499SAndroid Build Coastguard Worker lhs["utest"]["time_pvalue"], rhs["utest"]["time_pvalue"] 1594*dbb99499SAndroid Build Coastguard Worker ) 1595*dbb99499SAndroid Build Coastguard Worker unittest_instance.assertEqual( 1596*dbb99499SAndroid Build Coastguard Worker lhs["utest"]["have_optimal_repetitions"], 1597*dbb99499SAndroid Build Coastguard Worker rhs["utest"]["have_optimal_repetitions"], 1598*dbb99499SAndroid Build Coastguard Worker ) 1599*dbb99499SAndroid Build Coastguard Worker else: 1600*dbb99499SAndroid Build Coastguard Worker # lhs is empty. assert if rhs is not. 1601*dbb99499SAndroid Build Coastguard Worker unittest_instance.assertEqual(lhs["utest"], rhs["utest"]) 1602*dbb99499SAndroid Build Coastguard Worker 1603*dbb99499SAndroid Build Coastguard Worker 1604*dbb99499SAndroid Build Coastguard Workerdef assert_measurements(unittest_instance, lhs, rhs): 1605*dbb99499SAndroid Build Coastguard Worker for m1, m2 in zip(lhs["measurements"], rhs["measurements"]): 1606*dbb99499SAndroid Build Coastguard Worker unittest_instance.assertEqual(m1["real_time"], m2["real_time"]) 1607*dbb99499SAndroid Build Coastguard Worker unittest_instance.assertEqual(m1["cpu_time"], m2["cpu_time"]) 1608*dbb99499SAndroid Build Coastguard Worker # m1['time'] and m1['cpu'] hold values which are being calculated, 1609*dbb99499SAndroid Build Coastguard Worker # and therefore we must use almost-equal pattern. 1610*dbb99499SAndroid Build Coastguard Worker unittest_instance.assertAlmostEqual(m1["time"], m2["time"], places=4) 1611*dbb99499SAndroid Build Coastguard Worker unittest_instance.assertAlmostEqual(m1["cpu"], m2["cpu"], places=4) 1612*dbb99499SAndroid Build Coastguard Worker 1613*dbb99499SAndroid Build Coastguard Worker 1614*dbb99499SAndroid Build Coastguard Workerif __name__ == "__main__": 1615*dbb99499SAndroid Build Coastguard Worker unittest.main() 1616*dbb99499SAndroid Build Coastguard Worker 1617*dbb99499SAndroid Build Coastguard Worker# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 1618*dbb99499SAndroid Build Coastguard Worker# kate: tab-width: 4; replace-tabs on; indent-width 4; tab-indents: off; 1619*dbb99499SAndroid Build Coastguard Worker# kate: indent-mode python; remove-trailing-spaces modified; 1620