2 # Note: this script is python2 and python 3 compatible.
6 # Limited functonality 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
48 from six.moves import range
52 parser = argparse.ArgumentParser()
53 parser.add_argument('chardev',
54 help='character device target (e.g., /dev/sg0)')
55 parser.add_argument('blockdev',
56 help='block device target (e.g., /dev/sda)')
57 parser.add_argument('fio',
58 help='path to fio executable (e.g., ./fio)')
59 args = parser.parse_args()
66 # submit = complete = 1-4 always
67 # With character devices,
71 # complete = 1-4 except for the IOs in flight
72 # when the job is ending
76 # complete = qdbatch except for the IOs in flight
77 # when the job is ending
81 def check(jsondata, parameters, block, qd, qdbatch, rw):
82 iodepth = jsondata['iodepth_level']
83 submit = jsondata['iodepth_submit']
84 complete = jsondata['iodepth_complete']
88 assert iodepth['1'] == 100.0
89 assert submit['4'] == 100.0
90 assert complete['4'] == 100.0
91 elif 'read' in rw or 'write' in rw:
92 assert iodepth[str(qd)] > 99.9
93 assert submit['4'] == 100.0
94 assert complete['4'] > 99.9
101 batchkey = str(qdbatch)
106 assert iodepth[qdkey] > 99
107 assert submit[batchkey] == 100.0
108 assert complete[batchkey] > 99
109 except AssertionError:
110 print("Assertion failed")
111 traceback.print_exc()
115 print("**********passed*********")
118 def runalltests(args, qd, batch):
120 for dev in [args.chardev, args.blockdev]:
121 for rw in ["randread", "randwrite", "randtrim"]:
122 parameters = ["--name=test",
125 "--output-format=json",
127 "--rw={0}".format(rw),
128 "--filename={0}".format(dev),
129 "--iodepth={0}".format(qd),
130 "--iodepth_batch={0}".format(batch)]
133 output = subprocess.check_output([args.fio] + parameters)
134 jsondata = json.loads(output)
135 jobdata = jsondata['jobs'][0]
136 check(jobdata, parameters, block, qd, batch, rw)
140 def runcdevtrimtest(args, qd, batch):
141 parameters = ["--name=test",
144 "--output-format=json",
147 "--filename={0}".format(args.chardev),
148 "--iodepth={0}".format(qd),
149 "--iodepth_batch={0}".format(batch)]
152 output = subprocess.check_output([args.fio] + parameters)
153 jsondata = json.loads(output)
154 jobdata = jsondata['jobs'][0]
155 check(jobdata, parameters, False, qd, batch, "randtrim")
158 if __name__ == '__main__':
161 runcdevtrimtest(args, 32, 2)
162 runcdevtrimtest(args, 32, 4)
163 runcdevtrimtest(args, 32, 8)
164 runcdevtrimtest(args, 64, 4)
165 runcdevtrimtest(args, 64, 8)
166 runcdevtrimtest(args, 64, 16)
167 runcdevtrimtest(args, 128, 8)
168 runcdevtrimtest(args, 128, 16)
169 runcdevtrimtest(args, 128, 32)
171 runalltests(args, 1, 1)
172 runalltests(args, 16, 2)
173 runalltests(args, 16, 16)