xref: /openbmc/qemu/tests/qemu-iotests/136 (revision 4214face09bed08279c68a67fa1a4b01be887346)
1*4214faceSAlberto Garcia#!/usr/bin/env python
2*4214faceSAlberto Garcia#
3*4214faceSAlberto Garcia# Tests for block device statistics
4*4214faceSAlberto Garcia#
5*4214faceSAlberto Garcia# Copyright (C) 2015 Igalia, S.L.
6*4214faceSAlberto Garcia# Author: Alberto Garcia <berto@igalia.com>
7*4214faceSAlberto Garcia#
8*4214faceSAlberto Garcia# This program is free software; you can redistribute it and/or modify
9*4214faceSAlberto Garcia# it under the terms of the GNU General Public License as published by
10*4214faceSAlberto Garcia# the Free Software Foundation; either version 2 of the License, or
11*4214faceSAlberto Garcia# (at your option) any later version.
12*4214faceSAlberto Garcia#
13*4214faceSAlberto Garcia# This program is distributed in the hope that it will be useful,
14*4214faceSAlberto Garcia# but WITHOUT ANY WARRANTY; without even the implied warranty of
15*4214faceSAlberto Garcia# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*4214faceSAlberto Garcia# GNU General Public License for more details.
17*4214faceSAlberto Garcia#
18*4214faceSAlberto Garcia# You should have received a copy of the GNU General Public License
19*4214faceSAlberto Garcia# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20*4214faceSAlberto Garcia#
21*4214faceSAlberto Garcia
22*4214faceSAlberto Garciaimport iotests
23*4214faceSAlberto Garciaimport os
24*4214faceSAlberto Garcia
25*4214faceSAlberto Garciainterval_length = 10
26*4214faceSAlberto Garciansec_per_sec = 1000000000
27*4214faceSAlberto Garciaop_latency = nsec_per_sec / 1000 # See qtest_latency_ns in accounting.c
28*4214faceSAlberto Garciabad_sector = 8192
29*4214faceSAlberto Garciabad_offset = bad_sector * 512
30*4214faceSAlberto Garciablkdebug_file = os.path.join(iotests.test_dir, 'blkdebug.conf')
31*4214faceSAlberto Garcia
32*4214faceSAlberto Garciaclass BlockDeviceStatsTestCase(iotests.QMPTestCase):
33*4214faceSAlberto Garcia    test_img = "null-aio://"
34*4214faceSAlberto Garcia    total_rd_bytes = 0
35*4214faceSAlberto Garcia    total_rd_ops = 0
36*4214faceSAlberto Garcia    total_wr_bytes = 0
37*4214faceSAlberto Garcia    total_wr_ops = 0
38*4214faceSAlberto Garcia    total_wr_merged = 0
39*4214faceSAlberto Garcia    total_flush_ops = 0
40*4214faceSAlberto Garcia    failed_rd_ops = 0
41*4214faceSAlberto Garcia    failed_wr_ops = 0
42*4214faceSAlberto Garcia    invalid_rd_ops = 0
43*4214faceSAlberto Garcia    invalid_wr_ops = 0
44*4214faceSAlberto Garcia    wr_highest_offset = 0
45*4214faceSAlberto Garcia    account_invalid = False
46*4214faceSAlberto Garcia    account_failed = False
47*4214faceSAlberto Garcia
48*4214faceSAlberto Garcia    def blockstats(self, device):
49*4214faceSAlberto Garcia        result = self.vm.qmp("query-blockstats")
50*4214faceSAlberto Garcia        for r in result['return']:
51*4214faceSAlberto Garcia            if r['device'] == device:
52*4214faceSAlberto Garcia                return r['stats']
53*4214faceSAlberto Garcia        raise Exception("Device not found for blockstats: %s" % device)
54*4214faceSAlberto Garcia
55*4214faceSAlberto Garcia    def create_blkdebug_file(self):
56*4214faceSAlberto Garcia        file = open(blkdebug_file, 'w')
57*4214faceSAlberto Garcia        file.write('''
58*4214faceSAlberto Garcia[inject-error]
59*4214faceSAlberto Garciaevent = "read_aio"
60*4214faceSAlberto Garciaerrno = "5"
61*4214faceSAlberto Garciasector = "%d"
62*4214faceSAlberto Garcia
63*4214faceSAlberto Garcia[inject-error]
64*4214faceSAlberto Garciaevent = "write_aio"
65*4214faceSAlberto Garciaerrno = "5"
66*4214faceSAlberto Garciasector = "%d"
67*4214faceSAlberto Garcia''' % (bad_sector, bad_sector))
68*4214faceSAlberto Garcia        file.close()
69*4214faceSAlberto Garcia
70*4214faceSAlberto Garcia    def setUp(self):
71*4214faceSAlberto Garcia        drive_args = []
72*4214faceSAlberto Garcia        drive_args.append("stats-intervals=%d" % interval_length)
73*4214faceSAlberto Garcia        drive_args.append("stats-account-invalid=%s" %
74*4214faceSAlberto Garcia                          (self.account_invalid and "on" or "off"))
75*4214faceSAlberto Garcia        drive_args.append("stats-account-failed=%s" %
76*4214faceSAlberto Garcia                          (self.account_failed and "on" or "off"))
77*4214faceSAlberto Garcia        self.create_blkdebug_file()
78*4214faceSAlberto Garcia        self.vm = iotests.VM().add_drive('blkdebug:%s:%s ' %
79*4214faceSAlberto Garcia                                         (blkdebug_file, self.test_img),
80*4214faceSAlberto Garcia                                         ','.join(drive_args))
81*4214faceSAlberto Garcia        self.vm.launch()
82*4214faceSAlberto Garcia        # Set an initial value for the clock
83*4214faceSAlberto Garcia        self.vm.qtest("clock_step %d" % nsec_per_sec)
84*4214faceSAlberto Garcia
85*4214faceSAlberto Garcia    def tearDown(self):
86*4214faceSAlberto Garcia        self.vm.shutdown()
87*4214faceSAlberto Garcia        os.remove(blkdebug_file)
88*4214faceSAlberto Garcia
89*4214faceSAlberto Garcia    def accounted_ops(self, read = False, write = False, flush = False):
90*4214faceSAlberto Garcia        ops = 0
91*4214faceSAlberto Garcia        if write:
92*4214faceSAlberto Garcia            ops += self.total_wr_ops
93*4214faceSAlberto Garcia            if self.account_failed:
94*4214faceSAlberto Garcia                ops += self.failed_wr_ops
95*4214faceSAlberto Garcia            if self.account_invalid:
96*4214faceSAlberto Garcia                ops += self.invalid_wr_ops
97*4214faceSAlberto Garcia        if read:
98*4214faceSAlberto Garcia            ops += self.total_rd_ops
99*4214faceSAlberto Garcia            if self.account_failed:
100*4214faceSAlberto Garcia                ops += self.failed_rd_ops
101*4214faceSAlberto Garcia            if self.account_invalid:
102*4214faceSAlberto Garcia                ops += self.invalid_rd_ops
103*4214faceSAlberto Garcia        if flush:
104*4214faceSAlberto Garcia            ops += self.total_flush_ops
105*4214faceSAlberto Garcia        return ops
106*4214faceSAlberto Garcia
107*4214faceSAlberto Garcia    def accounted_latency(self, read = False, write = False, flush = False):
108*4214faceSAlberto Garcia        latency = 0
109*4214faceSAlberto Garcia        if write:
110*4214faceSAlberto Garcia            latency += self.total_wr_ops * op_latency
111*4214faceSAlberto Garcia            if self.account_failed:
112*4214faceSAlberto Garcia                latency += self.failed_wr_ops * op_latency
113*4214faceSAlberto Garcia        if read:
114*4214faceSAlberto Garcia            latency += self.total_rd_ops * op_latency
115*4214faceSAlberto Garcia            if self.account_failed:
116*4214faceSAlberto Garcia                latency += self.failed_rd_ops * op_latency
117*4214faceSAlberto Garcia        if flush:
118*4214faceSAlberto Garcia            latency += self.total_flush_ops * op_latency
119*4214faceSAlberto Garcia        return latency
120*4214faceSAlberto Garcia
121*4214faceSAlberto Garcia    def check_values(self):
122*4214faceSAlberto Garcia        stats = self.blockstats('drive0')
123*4214faceSAlberto Garcia
124*4214faceSAlberto Garcia        # Check that the totals match with what we have calculated
125*4214faceSAlberto Garcia        self.assertEqual(self.total_rd_bytes, stats['rd_bytes'])
126*4214faceSAlberto Garcia        self.assertEqual(self.total_wr_bytes, stats['wr_bytes'])
127*4214faceSAlberto Garcia        self.assertEqual(self.total_rd_ops, stats['rd_operations'])
128*4214faceSAlberto Garcia        self.assertEqual(self.total_wr_ops, stats['wr_operations'])
129*4214faceSAlberto Garcia        self.assertEqual(self.total_flush_ops, stats['flush_operations'])
130*4214faceSAlberto Garcia        self.assertEqual(self.wr_highest_offset, stats['wr_highest_offset'])
131*4214faceSAlberto Garcia        self.assertEqual(self.failed_rd_ops, stats['failed_rd_operations'])
132*4214faceSAlberto Garcia        self.assertEqual(self.failed_wr_ops, stats['failed_wr_operations'])
133*4214faceSAlberto Garcia        self.assertEqual(self.invalid_rd_ops, stats['invalid_rd_operations'])
134*4214faceSAlberto Garcia        self.assertEqual(self.invalid_wr_ops, stats['invalid_wr_operations'])
135*4214faceSAlberto Garcia        self.assertEqual(self.account_invalid, stats['account_invalid'])
136*4214faceSAlberto Garcia        self.assertEqual(self.account_failed, stats['account_failed'])
137*4214faceSAlberto Garcia        self.assertEqual(self.total_wr_merged, stats['wr_merged'])
138*4214faceSAlberto Garcia
139*4214faceSAlberto Garcia        # Check that there's exactly one interval with the length we defined
140*4214faceSAlberto Garcia        self.assertEqual(1, len(stats['timed_stats']))
141*4214faceSAlberto Garcia        timed_stats = stats['timed_stats'][0]
142*4214faceSAlberto Garcia        self.assertEqual(interval_length, timed_stats['interval_length'])
143*4214faceSAlberto Garcia
144*4214faceSAlberto Garcia        total_rd_latency = self.accounted_latency(read = True)
145*4214faceSAlberto Garcia        if (total_rd_latency != 0):
146*4214faceSAlberto Garcia            self.assertEqual(total_rd_latency, stats['rd_total_time_ns'])
147*4214faceSAlberto Garcia            self.assertEqual(op_latency, timed_stats['min_rd_latency_ns'])
148*4214faceSAlberto Garcia            self.assertEqual(op_latency, timed_stats['max_rd_latency_ns'])
149*4214faceSAlberto Garcia            self.assertEqual(op_latency, timed_stats['avg_rd_latency_ns'])
150*4214faceSAlberto Garcia            self.assertLess(0, timed_stats['avg_rd_queue_depth'])
151*4214faceSAlberto Garcia        else:
152*4214faceSAlberto Garcia            self.assertEqual(0, stats['rd_total_time_ns'])
153*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['min_rd_latency_ns'])
154*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['max_rd_latency_ns'])
155*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['avg_rd_latency_ns'])
156*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['avg_rd_queue_depth'])
157*4214faceSAlberto Garcia
158*4214faceSAlberto Garcia        # min read latency <= avg read latency <= max read latency
159*4214faceSAlberto Garcia        self.assertLessEqual(timed_stats['min_rd_latency_ns'],
160*4214faceSAlberto Garcia                             timed_stats['avg_rd_latency_ns'])
161*4214faceSAlberto Garcia        self.assertLessEqual(timed_stats['avg_rd_latency_ns'],
162*4214faceSAlberto Garcia                             timed_stats['max_rd_latency_ns'])
163*4214faceSAlberto Garcia
164*4214faceSAlberto Garcia        total_wr_latency = self.accounted_latency(write = True)
165*4214faceSAlberto Garcia        if (total_wr_latency != 0):
166*4214faceSAlberto Garcia            self.assertEqual(total_wr_latency, stats['wr_total_time_ns'])
167*4214faceSAlberto Garcia            self.assertEqual(op_latency, timed_stats['min_wr_latency_ns'])
168*4214faceSAlberto Garcia            self.assertEqual(op_latency, timed_stats['max_wr_latency_ns'])
169*4214faceSAlberto Garcia            self.assertEqual(op_latency, timed_stats['avg_wr_latency_ns'])
170*4214faceSAlberto Garcia            self.assertLess(0, timed_stats['avg_wr_queue_depth'])
171*4214faceSAlberto Garcia        else:
172*4214faceSAlberto Garcia            self.assertEqual(0, stats['wr_total_time_ns'])
173*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['min_wr_latency_ns'])
174*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['max_wr_latency_ns'])
175*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['avg_wr_latency_ns'])
176*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['avg_wr_queue_depth'])
177*4214faceSAlberto Garcia
178*4214faceSAlberto Garcia        # min write latency <= avg write latency <= max write latency
179*4214faceSAlberto Garcia        self.assertLessEqual(timed_stats['min_wr_latency_ns'],
180*4214faceSAlberto Garcia                             timed_stats['avg_wr_latency_ns'])
181*4214faceSAlberto Garcia        self.assertLessEqual(timed_stats['avg_wr_latency_ns'],
182*4214faceSAlberto Garcia                             timed_stats['max_wr_latency_ns'])
183*4214faceSAlberto Garcia
184*4214faceSAlberto Garcia        total_flush_latency = self.accounted_latency(flush = True)
185*4214faceSAlberto Garcia        if (total_flush_latency != 0):
186*4214faceSAlberto Garcia            self.assertEqual(total_flush_latency, stats['flush_total_time_ns'])
187*4214faceSAlberto Garcia            self.assertEqual(op_latency, timed_stats['min_flush_latency_ns'])
188*4214faceSAlberto Garcia            self.assertEqual(op_latency, timed_stats['max_flush_latency_ns'])
189*4214faceSAlberto Garcia            self.assertEqual(op_latency, timed_stats['avg_flush_latency_ns'])
190*4214faceSAlberto Garcia        else:
191*4214faceSAlberto Garcia            self.assertEqual(0, stats['flush_total_time_ns'])
192*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['min_flush_latency_ns'])
193*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['max_flush_latency_ns'])
194*4214faceSAlberto Garcia            self.assertEqual(0, timed_stats['avg_flush_latency_ns'])
195*4214faceSAlberto Garcia
196*4214faceSAlberto Garcia        # min flush latency <= avg flush latency <= max flush latency
197*4214faceSAlberto Garcia        self.assertLessEqual(timed_stats['min_flush_latency_ns'],
198*4214faceSAlberto Garcia                             timed_stats['avg_flush_latency_ns'])
199*4214faceSAlberto Garcia        self.assertLessEqual(timed_stats['avg_flush_latency_ns'],
200*4214faceSAlberto Garcia                             timed_stats['max_flush_latency_ns'])
201*4214faceSAlberto Garcia
202*4214faceSAlberto Garcia        # idle_time_ns must be > 0 if we have performed any operation
203*4214faceSAlberto Garcia        if (self.accounted_ops(read = True, write = True, flush = True) != 0):
204*4214faceSAlberto Garcia            self.assertLess(0, stats['idle_time_ns'])
205*4214faceSAlberto Garcia        else:
206*4214faceSAlberto Garcia            self.assertFalse(stats.has_key('idle_time_ns'))
207*4214faceSAlberto Garcia
208*4214faceSAlberto Garcia        # This test does not alter these, so they must be all 0
209*4214faceSAlberto Garcia        self.assertEqual(0, stats['rd_merged'])
210*4214faceSAlberto Garcia        self.assertEqual(0, stats['failed_flush_operations'])
211*4214faceSAlberto Garcia        self.assertEqual(0, stats['invalid_flush_operations'])
212*4214faceSAlberto Garcia
213*4214faceSAlberto Garcia    def do_test_stats(self, rd_size = 0, rd_ops = 0, wr_size = 0, wr_ops = 0,
214*4214faceSAlberto Garcia                      flush_ops = 0, invalid_rd_ops = 0, invalid_wr_ops = 0,
215*4214faceSAlberto Garcia                      failed_rd_ops = 0, failed_wr_ops = 0, wr_merged = 0):
216*4214faceSAlberto Garcia        # The 'ops' list will contain all the requested I/O operations
217*4214faceSAlberto Garcia        ops = []
218*4214faceSAlberto Garcia        for i in range(rd_ops):
219*4214faceSAlberto Garcia            ops.append("aio_read %d %d" % (i * rd_size, rd_size))
220*4214faceSAlberto Garcia
221*4214faceSAlberto Garcia        for i in range(wr_ops):
222*4214faceSAlberto Garcia            ops.append("aio_write %d %d" % (i * wr_size, wr_size))
223*4214faceSAlberto Garcia
224*4214faceSAlberto Garcia        for i in range(flush_ops):
225*4214faceSAlberto Garcia            ops.append("aio_flush")
226*4214faceSAlberto Garcia
227*4214faceSAlberto Garcia        highest_offset = wr_ops * wr_size
228*4214faceSAlberto Garcia
229*4214faceSAlberto Garcia        # Two types of invalid operations: unaligned length and unaligned offset
230*4214faceSAlberto Garcia        for i in range(invalid_rd_ops / 2):
231*4214faceSAlberto Garcia            ops.append("aio_read 0 511")
232*4214faceSAlberto Garcia
233*4214faceSAlberto Garcia        for i in range(invalid_rd_ops / 2, invalid_rd_ops):
234*4214faceSAlberto Garcia            ops.append("aio_read 13 512")
235*4214faceSAlberto Garcia
236*4214faceSAlberto Garcia        for i in range(invalid_wr_ops / 2):
237*4214faceSAlberto Garcia            ops.append("aio_write 0 511")
238*4214faceSAlberto Garcia
239*4214faceSAlberto Garcia        for i in range(invalid_wr_ops / 2, invalid_wr_ops):
240*4214faceSAlberto Garcia            ops.append("aio_write 13 512")
241*4214faceSAlberto Garcia
242*4214faceSAlberto Garcia        for i in range(failed_rd_ops):
243*4214faceSAlberto Garcia            ops.append("aio_read %d 512" % bad_offset)
244*4214faceSAlberto Garcia
245*4214faceSAlberto Garcia        for i in range(failed_wr_ops):
246*4214faceSAlberto Garcia            ops.append("aio_write %d 512" % bad_offset)
247*4214faceSAlberto Garcia
248*4214faceSAlberto Garcia        if failed_wr_ops > 0:
249*4214faceSAlberto Garcia            highest_offset = max(highest_offset, bad_offset + 512)
250*4214faceSAlberto Garcia
251*4214faceSAlberto Garcia        for i in range(wr_merged):
252*4214faceSAlberto Garcia            first = i * wr_size * 2
253*4214faceSAlberto Garcia            second = first + wr_size
254*4214faceSAlberto Garcia            ops.append("multiwrite %d %d ; %d %d" %
255*4214faceSAlberto Garcia                       (first, wr_size, second, wr_size))
256*4214faceSAlberto Garcia
257*4214faceSAlberto Garcia        highest_offset = max(highest_offset, wr_merged * wr_size * 2)
258*4214faceSAlberto Garcia
259*4214faceSAlberto Garcia        # Now perform all operations
260*4214faceSAlberto Garcia        for op in ops:
261*4214faceSAlberto Garcia            self.vm.hmp_qemu_io("drive0", op)
262*4214faceSAlberto Garcia
263*4214faceSAlberto Garcia        # Update the expected totals
264*4214faceSAlberto Garcia        self.total_rd_bytes += rd_ops * rd_size
265*4214faceSAlberto Garcia        self.total_rd_ops += rd_ops
266*4214faceSAlberto Garcia        self.total_wr_bytes += wr_ops * wr_size
267*4214faceSAlberto Garcia        self.total_wr_ops += wr_ops
268*4214faceSAlberto Garcia        self.total_wr_merged += wr_merged
269*4214faceSAlberto Garcia        self.total_flush_ops += flush_ops
270*4214faceSAlberto Garcia        self.invalid_rd_ops += invalid_rd_ops
271*4214faceSAlberto Garcia        self.invalid_wr_ops += invalid_wr_ops
272*4214faceSAlberto Garcia        self.failed_rd_ops += failed_rd_ops
273*4214faceSAlberto Garcia        self.failed_wr_ops += failed_wr_ops
274*4214faceSAlberto Garcia
275*4214faceSAlberto Garcia        self.wr_highest_offset = max(self.wr_highest_offset, highest_offset)
276*4214faceSAlberto Garcia
277*4214faceSAlberto Garcia        # Advance the clock so idle_time_ns has a meaningful value
278*4214faceSAlberto Garcia        self.vm.qtest("clock_step %d" % nsec_per_sec)
279*4214faceSAlberto Garcia
280*4214faceSAlberto Garcia        # And check that the actual statistics match the expected ones
281*4214faceSAlberto Garcia        self.check_values()
282*4214faceSAlberto Garcia
283*4214faceSAlberto Garcia    def test_read_only(self):
284*4214faceSAlberto Garcia        test_values = [[512,    1],
285*4214faceSAlberto Garcia                       [65536,  1],
286*4214faceSAlberto Garcia                       [512,   12],
287*4214faceSAlberto Garcia                       [65536, 12]]
288*4214faceSAlberto Garcia        for i in test_values:
289*4214faceSAlberto Garcia            self.do_test_stats(rd_size = i[0], rd_ops = i[1])
290*4214faceSAlberto Garcia
291*4214faceSAlberto Garcia    def test_write_only(self):
292*4214faceSAlberto Garcia        test_values = [[512,    1],
293*4214faceSAlberto Garcia                       [65536,  1],
294*4214faceSAlberto Garcia                       [512,   12],
295*4214faceSAlberto Garcia                       [65536, 12]]
296*4214faceSAlberto Garcia        for i in test_values:
297*4214faceSAlberto Garcia            self.do_test_stats(wr_size = i[0], wr_ops = i[1])
298*4214faceSAlberto Garcia
299*4214faceSAlberto Garcia    def test_invalid(self):
300*4214faceSAlberto Garcia        self.do_test_stats(invalid_rd_ops = 7)
301*4214faceSAlberto Garcia        self.do_test_stats(invalid_wr_ops = 3)
302*4214faceSAlberto Garcia        self.do_test_stats(invalid_rd_ops = 4, invalid_wr_ops = 5)
303*4214faceSAlberto Garcia
304*4214faceSAlberto Garcia    def test_failed(self):
305*4214faceSAlberto Garcia        self.do_test_stats(failed_rd_ops = 8)
306*4214faceSAlberto Garcia        self.do_test_stats(failed_wr_ops = 6)
307*4214faceSAlberto Garcia        self.do_test_stats(failed_rd_ops = 5, failed_wr_ops = 12)
308*4214faceSAlberto Garcia
309*4214faceSAlberto Garcia    def test_flush(self):
310*4214faceSAlberto Garcia        self.do_test_stats(flush_ops = 8)
311*4214faceSAlberto Garcia
312*4214faceSAlberto Garcia    def test_merged(self):
313*4214faceSAlberto Garcia        for i in range(5):
314*4214faceSAlberto Garcia            self.do_test_stats(wr_merged = i * 3)
315*4214faceSAlberto Garcia
316*4214faceSAlberto Garcia    def test_all(self):
317*4214faceSAlberto Garcia        # rd_size, rd_ops, wr_size, wr_ops, flush_ops
318*4214faceSAlberto Garcia        # invalid_rd_ops,  invalid_wr_ops,
319*4214faceSAlberto Garcia        # failed_rd_ops,   failed_wr_ops
320*4214faceSAlberto Garcia        # wr_merged
321*4214faceSAlberto Garcia        test_values = [[512,    1, 512,   1, 1, 4, 7, 5, 2, 1],
322*4214faceSAlberto Garcia                       [65536,  1, 2048, 12, 7, 7, 5, 2, 5, 5],
323*4214faceSAlberto Garcia                       [32768,  9, 8192,  1, 4, 3, 2, 4, 6, 4],
324*4214faceSAlberto Garcia                       [16384, 11, 3584, 16, 9, 8, 6, 7, 3, 4]]
325*4214faceSAlberto Garcia        for i in test_values:
326*4214faceSAlberto Garcia            self.do_test_stats(*i)
327*4214faceSAlberto Garcia
328*4214faceSAlberto Garcia    def test_no_op(self):
329*4214faceSAlberto Garcia        # All values must be sane before doing any I/O
330*4214faceSAlberto Garcia        self.check_values()
331*4214faceSAlberto Garcia
332*4214faceSAlberto Garcia
333*4214faceSAlberto Garciaclass BlockDeviceStatsTestAccountInvalid(BlockDeviceStatsTestCase):
334*4214faceSAlberto Garcia    account_invalid = True
335*4214faceSAlberto Garcia    account_failed = False
336*4214faceSAlberto Garcia
337*4214faceSAlberto Garciaclass BlockDeviceStatsTestAccountFailed(BlockDeviceStatsTestCase):
338*4214faceSAlberto Garcia    account_invalid = False
339*4214faceSAlberto Garcia    account_failed = True
340*4214faceSAlberto Garcia
341*4214faceSAlberto Garciaclass BlockDeviceStatsTestAccountBoth(BlockDeviceStatsTestCase):
342*4214faceSAlberto Garcia    account_invalid = True
343*4214faceSAlberto Garcia    account_failed = True
344*4214faceSAlberto Garcia
345*4214faceSAlberto Garciaclass BlockDeviceStatsTestCoroutine(BlockDeviceStatsTestCase):
346*4214faceSAlberto Garcia    test_img = "null-co://"
347*4214faceSAlberto Garcia
348*4214faceSAlberto Garciaif __name__ == '__main__':
349*4214faceSAlberto Garcia    iotests.main(supported_fmts=["raw"])
350