@samitouri / QOSamiQemu / commits / 3205b9fa6a

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