2 # Note: this script is python2 and python 3 compatible.
6 # Limited functionality test for trim workloads using fio's sg ioengine
7 # This checks only the three sets of reported iodepths
10 # This script carries out destructive tests. Be sure that
11 # there is no data you want to keep on the supplied devices.
14 # sgunmap-test.py char-device block-device fio-executable
17 # t/sgunmap-test.py /dev/sg1 /dev/sdb ./fio
23 # For both char-dev and block-dev these are the expected
24 # submit/complete IO depths
28 # R QD1 sub/comp: 1-4=100% sub/comp: 1-4=100%
29 # W QD1 sub/comp: 1-4=100% sub/comp: 1-4=100%
30 # T QD1 sub/comp: 1-4=100% sub/comp: 1-4=100%
32 # R QD16, batch8 sub/comp: 1-4=100% sub/comp: 1-4=100%
33 # W QD16, batch8 sub/comp: 1-4=100% sub/comp: 1-4=100%
34 # T QD16, batch8 sub/comp: 1-4=100% sub/comp: 5-8=100%
36 # R QD16, batch16 sub/comp: 1-4=100% sub/comp: 1-4=100%
37 # W QD16, batch16 sub/comp: 1-4=100% sub/comp: 1-4=100%
38 # T QD16, batch16 sub/comp: 1-4=100% sub/comp: 9-16=100%
41 from __future__ import absolute_import
42 from __future__ import print_function
51 parser = argparse.ArgumentParser()
52 parser.add_argument('chardev',
53 help='character device target (e.g., /dev/sg0)')
54 parser.add_argument('blockdev',
55 help='block device target (e.g., /dev/sda)')
56 parser.add_argument('fio',
57 help='path to fio executable (e.g., ./fio)')
58 args = parser.parse_args()
65 # submit = complete = 1-4 always
66 # With character devices,
70 # complete = 1-4 except for the IOs in flight
71 # when the job is ending
75 # complete = qdbatch except for the IOs in flight
76 # when the job is ending
80 def check(jsondata, parameters, block, qd, qdbatch, rw):
81 iodepth = jsondata['iodepth_level']
82 submit = jsondata['iodepth_submit']
83 complete = jsondata['iodepth_complete']
87 assert iodepth['1'] == 100.0
88 assert submit['4'] == 100.0
89 assert complete['4'] == 100.0
90 elif 'read' in rw or 'write' in rw:
91 assert iodepth[str(qd)] > 99.9
92 assert submit['4'] == 100.0
93 assert complete['4'] > 99.9
100 batchkey = str(qdbatch)
105 assert iodepth[qdkey] > 99
106 assert submit[batchkey] == 100.0
107 assert complete[batchkey] > 99
108 except AssertionError:
109 print("Assertion failed")
110 traceback.print_exc()
114 print("**********passed*********")
117 def runalltests(args, qd, batch):
119 for dev in [args.chardev, args.blockdev]:
120 for rw in ["randread", "randwrite", "randtrim"]:
121 parameters = ["--name=test",
124 "--output-format=json",
126 "--rw={0}".format(rw),
127 "--filename={0}".format(dev),
128 "--iodepth={0}".format(qd),
129 "--iodepth_batch={0}".format(batch)]
132 output = subprocess.check_output([args.fio] + parameters)
133 jsondata = json.loads(output)
134 jobdata = jsondata['jobs'][0]
135 check(jobdata, parameters, block, qd, batch, rw)
139 def runcdevtrimtest(args, qd, batch):
140 parameters = ["--name=test",
143 "--output-format=json",
146 "--filename={0}".format(args.chardev),
147 "--iodepth={0}".format(qd),
148 "--iodepth_batch={0}".format(batch)]
151 output = subprocess.check_output([args.fio] + parameters)
152 jsondata = json.loads(output)
153 jobdata = jsondata['jobs'][0]
154 check(jobdata, parameters, False, qd, batch, "randtrim")
157 if __name__ == '__main__':
160 runcdevtrimtest(args, 32, 2)
161 runcdevtrimtest(args, 32, 4)
162 runcdevtrimtest(args, 32, 8)
163 runcdevtrimtest(args, 64, 4)
164 runcdevtrimtest(args, 64, 8)
165 runcdevtrimtest(args, 64, 16)
166 runcdevtrimtest(args, 128, 8)
167 runcdevtrimtest(args, 128, 16)
168 runcdevtrimtest(args, 128, 32)
170 runalltests(args, 1, 1)
171 runalltests(args, 16, 2)
172 runalltests(args, 16, 16)