iotests/136: Test stats-intervals with -blockdev/-device
Commit 9f0c763e introduced the "stats-intervals" qdev property for block devices, a setting that was previously only accessible with -drive. Extend the corresponding test to include test cases that set the property on -device instead, both with -drive and -blockdev. We wouldn't really improve coverage with testing every combination of account_invalid and account_failed with all modes to set up statistics, so it seems good enough to test all combinations with the old way, and only both True or both False with the additional ways. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Message-ID: <20260521101854.31997-1-kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Kevin Wolf committed
May 21, 2026 at 12:18 UTC
3205b9fa6a968eb3e8d569f47da1b43494133acf
2 files changed
+77
-14
tests/qemu-iotests/136
+75
-12
@@ -22,6 +22,7 @@
22
23
import iotests
24
import os
25
+import json
26
27
interval_length = 10
28
nsec_per_sec = 1000000000
@@ -45,14 +46,22 @@ class BlockDeviceStatsTestCase(iotests.QMPTestCase):
46
wr_highest_offset = 0
47
account_invalid = False
48
account_failed = False
49
+ stats_in_device = False
50
+ use_blockdev = False
51
52
def blockstats(self, device):
53
result = self.vm.qmp("query-blockstats")
54
for r in result['return']:
52
- if r['device'] == device:
55
+ if r['device'] == device or r['node-name'] == device:
56
return r['stats']
57
raise Exception("Device not found for blockstats: %s" % device)
58
59
+ def qemu_io(self, cmd):
60
+ if self.use_blockdev:
61
+ self.vm.hmp_qemu_io("virtio0/virtio-backend", cmd, qdev=True)
62
+ else:
63
+ self.vm.hmp_qemu_io("drive0", cmd)
64
+
65
def create_blkdebug_file(self):
66
file = open(blkdebug_file, 'w')
67
file.write('''
@@ -73,17 +82,54 @@ sector = "%d"
82
83
@iotests.skip_if_unsupported(required_drivers)
84
def setUp(self):
76
- drive_args = []
77
- drive_args.append("stats-intervals.0=%d" % interval_length)
78
- drive_args.append("stats-account-invalid=%s" %
79
- (self.account_invalid and "on" or "off"))
80
- drive_args.append("stats-account-failed=%s" %
81
- (self.account_failed and "on" or "off"))
82
- drive_args.append("file.image.read-zeroes=on")
85
self.create_blkdebug_file()
84
- self.vm = iotests.VM().add_drive('blkdebug:%s:%s://' %
85
- (blkdebug_file, self.test_driver),
86
- ','.join(drive_args))
86
+ self.vm = iotests.VM()
87
+
88
+ drive_args = [
89
+ "file.image.read-zeroes=on",
90
+ ]
91
+ if self.stats_in_device:
92
+ interface = "none"
93
+ dev_args = {
94
+ "driver": "virtio-blk",
95
+ "id": "virtio0",
96
+ "drive": "drive0",
97
+ "stats-intervals": [ interval_length ],
98
+ "account-invalid": "on" if self.account_invalid else "off",
99
+ "account-failed": "on" if self.account_failed else "off",
100
+ }
101
+ self.vm.add_device(json.dumps(dev_args))
102
+ else:
103
+ assert not self.use_blockdev
104
+ interface = "virtio"
105
+ drive_args += [
106
+ "stats-intervals.0=%d" % interval_length,
107
+ "stats-account-invalid=%s" %
108
+ (self.account_invalid and "on" or "off"),
109
+ "stats-account-failed=%s" %
110
+ (self.account_failed and "on" or "off"),
111
+ ]
112
+
113
+ if self.use_blockdev:
114
+ blockdev_args = {
115
+ "node-name": "drive0",
116
+ "driver": "raw",
117
+ "file": {
118
+ "driver": "blkdebug",
119
+ "config": blkdebug_file,
120
+ "image": {
121
+ "driver": self.test_driver,
122
+ "read-zeroes": True,
123
+ },
124
+ },
125
+ }
126
+ self.vm.add_blockdev(json.dumps(blockdev_args))
127
+ else:
128
+ self.vm.add_drive('blkdebug:%s:%s://' %
129
+ (blkdebug_file, self.test_driver),
130
+ ','.join(drive_args),
131
+ interface=interface)
132
+
133
self.vm.launch()
134
# Set an initial value for the clock
135
self.vm.qtest("clock_step %d" % nsec_per_sec)
@@ -261,7 +307,7 @@ sector = "%d"
307
308
# Now perform all operations
309
for op in ops:
264
- self.vm.hmp_qemu_io("drive0", op)
310
+ self.qemu_io(op)
311
312
# Update the expected totals
313
self.total_rd_bytes += rd_ops * rd_size
@@ -328,6 +374,12 @@ sector = "%d"
374
# All values must be sane before doing any I/O
375
self.check_values()
376
377
+class BlockDeviceStatsTestDevice(BlockDeviceStatsTestCase):
378
+ stats_in_device = True
379
+
380
+class BlockDeviceStatsTestBlockdev(BlockDeviceStatsTestCase):
381
+ stats_in_device = True
382
+ use_blockdev = True
383
384
class BlockDeviceStatsTestAccountInvalid(BlockDeviceStatsTestCase):
385
account_invalid = True
@@ -341,6 +393,17 @@ class BlockDeviceStatsTestAccountBoth(BlockDeviceStatsTestCase):
393
account_invalid = True
394
account_failed = True
395
396
+class BlockDeviceStatsTestAccountBothDevice(BlockDeviceStatsTestCase):
397
+ account_invalid = True
398
+ account_failed = True
399
+ stats_in_device = True
400
+
401
+class BlockDeviceStatsTestAccountBothBlockdev(BlockDeviceStatsTestCase):
402
+ account_invalid = True
403
+ account_failed = True
404
+ stats_in_device = True
405
+ use_blockdev = True
406
+
407
class BlockDeviceStatsTestCoroutine(BlockDeviceStatsTestCase):
408
test_driver = "null-co"
409
tests/qemu-iotests/136.out
+2
-2
@@ -1,5 +1,5 @@
1
-...................................
1
+...............................................................
2
----------------------------------------------------------------------
3
-Ran 35 tests
3
+Ran 63 tests
4
5
OK