1eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes#!/usr/bin/python 2eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 3eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# steadystate_tests.py 4eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 5eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# Test option parsing and functonality for fio's steady state detection feature. 6eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 7eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# steadystate_tests.py ./fio file-for-read-testing file-for-write-testing 8eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 9eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# REQUIREMENTS 10eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# Python 2.6+ 11eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# SciPy 12eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 13eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# KNOWN ISSUES 14eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# only option parsing and read tests are carried out 15eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# On Windows this script works under Cygwin but not from cmd.exe 16eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# On Windows I encounter frequent fio problems generating JSON output (nothing to decode) 17eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# min runtime: 18eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# if ss attained: min runtime = ss_dur + ss_ramp 19eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# if not attained: runtime = timeout 20eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 21eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesimport os 22eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesimport sys 23eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesimport json 24eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesimport uuid 25eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesimport pprint 26eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesimport argparse 27eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesimport subprocess 28eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesfrom scipy import stats 29eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 30eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesdef parse_args(): 31eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes parser = argparse.ArgumentParser() 32eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes parser.add_argument('fio', 33eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes help='path to fio executable'); 34eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes parser.add_argument('--read', 35eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes help='target for read testing') 36eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes parser.add_argument('--write', 37eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes help='target for write testing') 38eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes args = parser.parse_args() 39eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 40eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes return args 41eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 42eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 43eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesdef check(data, iops, slope, pct, limit, dur, criterion): 44eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes measurement = 'iops' if iops else 'bw' 45eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes data = data[measurement] 46eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes mean = sum(data) / len(data) 47eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if slope: 48eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes x = range(len(data)) 49eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes m, intercept, r_value, p_value, std_err = stats.linregress(x,data) 50eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes m = abs(m) 51eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if pct: 52eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes target = m / mean * 100 53eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes criterion = criterion[:-1] 54eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 55eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes target = m 56eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 57eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes maxdev = 0 58eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes for x in data: 59eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes maxdev = max(abs(mean-x), maxdev) 60eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if pct: 61eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes target = maxdev / mean * 100 62eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes criterion = criterion[:-1] 63eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 64eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes target = maxdev 65eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 66eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes criterion = float(criterion) 67eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes return (abs(target - criterion) / criterion < 0.005), target < limit, mean, target 68eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 69eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 70eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughesif __name__ == '__main__': 71eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes args = parse_args() 72eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 73eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes pp = pprint.PrettyPrinter(indent=4) 74eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 75eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 76eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# test option parsing 77eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 78eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes parsing = [ { 'args': ["--parse-only", "--debug=parse", "--ss_dur=10s", "--ss=iops:10", "--ss_ramp=5"], 79eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 'output': "set steady state IOPS threshold to 10.000000" }, 80eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes { 'args': ["--parse-only", "--debug=parse", "--ss_dur=10s", "--ss=iops:10%", "--ss_ramp=5"], 81eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 'output': "set steady state threshold to 10.000000%" }, 82eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes { 'args': ["--parse-only", "--debug=parse", "--ss_dur=10s", "--ss=iops:.1%", "--ss_ramp=5"], 83eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 'output': "set steady state threshold to 0.100000%" }, 84eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes { 'args': ["--parse-only", "--debug=parse", "--ss_dur=10s", "--ss=bw:10%", "--ss_ramp=5"], 85eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 'output': "set steady state threshold to 10.000000%" }, 86eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes { 'args': ["--parse-only", "--debug=parse", "--ss_dur=10s", "--ss=bw:.1%", "--ss_ramp=5"], 87eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 'output': "set steady state threshold to 0.100000%" }, 88eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes { 'args': ["--parse-only", "--debug=parse", "--ss_dur=10s", "--ss=bw:12", "--ss_ramp=5"], 89eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 'output': "set steady state BW threshold to 12" }, 90eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes ] 91eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes for test in parsing: 92eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes output = subprocess.check_output([args.fio] + test['args']); 93eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if test['output'] in output: 94eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes print "PASSED '{0}' found with arguments {1}".format(test['output'], test['args']) 95eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 96eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes print "FAILED '{0}' NOT found with arguments {1}".format(test['output'], test['args']) 97eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 98eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 99eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# test some read workloads 100eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 101eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# if ss active and attained, 102eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# check that runtime is less than job time 103eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# check criteria 104eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# how to check ramp time? 105eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 106eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# if ss inactive 107eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# check that runtime is what was specified 108eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes# 109eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes reads = [ {'s': True, 'timeout': 100, 'numjobs': 1, 'ss_dur': 5, 'ss_ramp': 3, 'iops': True, 'slope': True, 'ss_limit': 0.1, 'pct': True}, 110eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes {'s': False, 'timeout': 20, 'numjobs': 2}, 111eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes {'s': True, 'timeout': 100, 'numjobs': 3, 'ss_dur': 10, 'ss_ramp': 5, 'iops': False, 'slope': True, 'ss_limit': 0.1, 'pct': True}, 112eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes {'s': True, 'timeout': 10, 'numjobs': 3, 'ss_dur': 10, 'ss_ramp': 500, 'iops': False, 'slope': True, 'ss_limit': 0.1, 'pct': True}, 113eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes ] 114eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 115eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if args.read == None: 116eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if os.name == 'posix': 117eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes args.read = '/dev/zero' 118eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes extra = [ "--size=134217728" ] # 128 MiB 119eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 120eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes print "ERROR: file for read testing must be specified on non-posix systems" 121eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes sys.exit(1) 122eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 123eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes extra = [] 124eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 125eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes jobnum = 0 126eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes for job in reads: 127eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 128eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes tf = uuid.uuid4().hex 129eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes parameters = [ "--name=job{0}".format(jobnum) ] 130eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes parameters.extend(extra) 131eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes parameters.extend([ "--thread", 132eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes "--output-format=json", 133eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes "--output={0}".format(tf), 134eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes "--filename={0}".format(args.read), 135eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes "--rw=randrw", 136eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes "--rwmixread=100", 137eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes "--stonewall", 138eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes "--group_reporting", 139eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes "--numjobs={0}".format(job['numjobs']), 140eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes "--time_based", 141eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes "--runtime={0}".format(job['timeout']) ]) 142eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if job['s']: 143eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if job['iops']: 144eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes ss = 'iops' 145eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 146eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes ss = 'bw' 147eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if job['slope']: 148eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes ss += "_slope" 149eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes ss += ":" + str(job['ss_limit']) 150eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if job['pct']: 151eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes ss += '%' 152eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes parameters.extend([ '--ss_dur={0}'.format(job['ss_dur']), 153eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes '--ss={0}'.format(ss), 154eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes '--ss_ramp={0}'.format(job['ss_ramp']) ]) 155eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 156eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes output = subprocess.call([args.fio] + parameters) 157eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes with open(tf, 'r') as source: 158eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes jsondata = json.loads(source.read()) 159eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes os.remove(tf) 160eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes 161eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes for jsonjob in jsondata['jobs']: 162eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = "job {0}".format(jsonjob['job options']['name']) 163eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if job['s']: 164eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if jsonjob['steadystate']['attained'] == 1: 165eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes # check runtime >= ss_dur + ss_ramp, check criterion, check criterion < limit 166eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes mintime = (job['ss_dur'] + job['ss_ramp']) * 1000 167eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes actual = jsonjob['read']['runtime'] 168eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if mintime > actual: 169eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = 'FAILED ' + line + ' ss attained, runtime {0} < ss_dur {1} + ss_ramp {2}'.format(actual, job['ss_dur'], job['ss_ramp']) 170eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 171eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = line + ' ss attained, runtime {0} > ss_dur {1} + ss_ramp {2},'.format(actual, job['ss_dur'], job['ss_ramp']) 172eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes objsame, met, mean, target = check(data=jsonjob['steadystate']['data'], 173eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes iops=job['iops'], 174eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes slope=job['slope'], 175eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes pct=job['pct'], 176eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes limit=job['ss_limit'], 177eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes dur=job['ss_dur'], 178eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes criterion=jsonjob['steadystate']['criterion']) 179eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if not objsame: 180eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = 'FAILED ' + line + ' fio criterion {0} != calculated criterion {1} '.format(jsonjob['steadystate']['criterion'], target) 181eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 182eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if met: 183eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = 'PASSED ' + line + ' target {0} < limit {1}'.format(target, job['ss_limit']) 184eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 185eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = 'FAILED ' + line + ' target {0} < limit {1} but fio reports ss not attained '.format(target, job['ss_limit']) 186eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 187eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes # check runtime, confirm criterion calculation, and confirm that criterion was not met 188eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes expected = job['timeout'] * 1000 189eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes actual = jsonjob['read']['runtime'] 190eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if abs(expected - actual) > 10: 191eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = 'FAILED ' + line + ' ss not attained, expected runtime {0} != actual runtime {1}'.format(expected, actual) 192eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 193eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = line + ' ss not attained, runtime {0} != ss_dur {1} + ss_ramp {2},'.format(actual, job['ss_dur'], job['ss_ramp']) 194eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes objsame, met, mean, target = check(data=jsonjob['steadystate']['data'], 195eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes iops=job['iops'], 196eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes slope=job['slope'], 197eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes pct=job['pct'], 198eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes limit=job['ss_limit'], 199eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes dur=job['ss_dur'], 200eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes criterion=jsonjob['steadystate']['criterion']) 201eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if not objsame: 202eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if actual > (job['ss_dur'] + job['ss_ramp'])*1000: 203eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = 'FAILED ' + line + ' fio criterion {0} != calculated criterion {1} '.format(jsonjob['steadystate']['criterion'], target) 204eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 205eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = 'PASSED ' + line + ' fio criterion {0} == 0.0 since ss_dur + ss_ramp has not elapsed '.format(jsonjob['steadystate']['criterion']) 206eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 207eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if met: 208eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = 'FAILED ' + line + ' target {0} < threshold {1} but fio reports ss not attained '.format(target, job['ss_limit']) 209eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 210eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = 'PASSED ' + line + ' criterion {0} > threshold {1}'.format(target, job['ss_limit']) 211eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 212eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes expected = job['timeout'] * 1000 213eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes actual = jsonjob['read']['runtime'] 214eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if abs(expected - actual) < 10: 215eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes result = 'PASSED ' 216eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes else: 217eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes result = 'FAILED ' 218eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes line = result + line + ' no ss, expected runtime {0} ~= actual runtime {1}'.format(expected, actual) 219eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes print line 220eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes if 'steadystate' in jsonjob: 221eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes pp.pprint(jsonjob['steadystate']) 222eda3a60699e1d96bb68875ef2169ca819eb8f4f9Elliott Hughes jobnum += 1 223