Merge branch 'directory-operation' of https://github.com/friendy-su/fio
[fio.git] / t / sgunmap-test.py
CommitLineData
8629f5f5 1#!/usr/bin/env python3
15835530
VF
2# Note: this script is python2 and python 3 compatible.
3#
4# sgunmap-test.py
5#
fc002f14 6# Limited functionality test for trim workloads using fio's sg ioengine
15835530
VF
7# This checks only the three sets of reported iodepths
8#
9# !!!WARNING!!!
10# This script carries out destructive tests. Be sure that
11# there is no data you want to keep on the supplied devices.
12#
13# USAGE
14# sgunmap-test.py char-device block-device fio-executable
15#
16# EXAMPLE
17# t/sgunmap-test.py /dev/sg1 /dev/sdb ./fio
18#
19# REQUIREMENTS
20# Python 2.6+
21#
22# TEST MATRIX
23# For both char-dev and block-dev these are the expected
24# submit/complete IO depths
25#
26# blockdev chardev
27# iodepth iodepth
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%
31#
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%
35#
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%
39#
40
41from __future__ import absolute_import
42from __future__ import print_function
43import sys
44import json
45import argparse
46import traceback
47import subprocess
15835530
VF
48
49
50def parse_args():
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()
59
60 return args
61
62#
63# With block devices,
64# iodepth = 1 always
65# submit = complete = 1-4 always
66# With character devices,
67# RW
68# iodepth = qd
69# submit = 1-4
70# complete = 1-4 except for the IOs in flight
71# when the job is ending
72# T
73# iodepth = qd
74# submit = qdbatch
75# complete = qdbatch except for the IOs in flight
76# when the job is ending
77#
78
79
80def check(jsondata, parameters, block, qd, qdbatch, rw):
81 iodepth = jsondata['iodepth_level']
82 submit = jsondata['iodepth_submit']
83 complete = jsondata['iodepth_complete']
84
85 try:
86 if block:
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
94 else:
95 if qdbatch <= 4:
96 batchkey = '4'
97 elif qdbatch > 64:
98 batchkey = '>=64'
99 else:
100 batchkey = str(qdbatch)
101 if qd >= 64:
102 qdkey = ">=64"
103 else:
104 qdkey = str(qd)
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()
111 print(jsondata)
112 return
113
114 print("**********passed*********")
115
116
117def runalltests(args, qd, batch):
118 block = False
119 for dev in [args.chardev, args.blockdev]:
120 for rw in ["randread", "randwrite", "randtrim"]:
121 parameters = ["--name=test",
122 "--time_based",
123 "--runtime=30s",
124 "--output-format=json",
125 "--ioengine=sg",
126 "--rw={0}".format(rw),
127 "--filename={0}".format(dev),
128 "--iodepth={0}".format(qd),
129 "--iodepth_batch={0}".format(batch)]
130
131 print(parameters)
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)
136 block = True
137
138
139def runcdevtrimtest(args, qd, batch):
140 parameters = ["--name=test",
141 "--time_based",
142 "--runtime=30s",
143 "--output-format=json",
144 "--ioengine=sg",
145 "--rw=randtrim",
146 "--filename={0}".format(args.chardev),
147 "--iodepth={0}".format(qd),
148 "--iodepth_batch={0}".format(batch)]
149
150 print(parameters)
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")
155
156
157if __name__ == '__main__':
158 args = parse_args()
159
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)
169
170 runalltests(args, 1, 1)
171 runalltests(args, 16, 2)
172 runalltests(args, 16, 16)