[PATCH] iotests/136: Test stats-intervals with -blockdev/-device

Kevin Wolf posted 1 patch 1 week, 2 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260521101854.31997-1-kwolf@redhat.com
Maintainers: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>
tests/qemu-iotests/136     | 87 ++++++++++++++++++++++++++++++++------
tests/qemu-iotests/136.out |  4 +-
2 files changed, 77 insertions(+), 14 deletions(-)
[PATCH] iotests/136: Test stats-intervals with -blockdev/-device
Posted by Kevin Wolf 1 week, 2 days ago
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>
---
 tests/qemu-iotests/136     | 87 ++++++++++++++++++++++++++++++++------
 tests/qemu-iotests/136.out |  4 +-
 2 files changed, 77 insertions(+), 14 deletions(-)

diff --git a/tests/qemu-iotests/136 b/tests/qemu-iotests/136
index 8fce88bd677..58df876bafc 100755
--- a/tests/qemu-iotests/136
+++ b/tests/qemu-iotests/136
@@ -22,6 +22,7 @@
 
 import iotests
 import os
+import json
 
 interval_length = 10
 nsec_per_sec = 1000000000
@@ -45,14 +46,22 @@ class BlockDeviceStatsTestCase(iotests.QMPTestCase):
     wr_highest_offset = 0
     account_invalid = False
     account_failed = False
+    stats_in_device = False
+    use_blockdev = False
 
     def blockstats(self, device):
         result = self.vm.qmp("query-blockstats")
         for r in result['return']:
-            if r['device'] == device:
+            if r['device'] == device or r['node-name'] == device:
                 return r['stats']
         raise Exception("Device not found for blockstats: %s" % device)
 
+    def qemu_io(self, cmd):
+        if self.use_blockdev:
+            self.vm.hmp_qemu_io("virtio0/virtio-backend", cmd, qdev=True)
+        else:
+            self.vm.hmp_qemu_io("drive0", cmd)
+
     def create_blkdebug_file(self):
         file = open(blkdebug_file, 'w')
         file.write('''
@@ -73,17 +82,54 @@ sector = "%d"
 
     @iotests.skip_if_unsupported(required_drivers)
     def setUp(self):
-        drive_args = []
-        drive_args.append("stats-intervals.0=%d" % interval_length)
-        drive_args.append("stats-account-invalid=%s" %
-                          (self.account_invalid and "on" or "off"))
-        drive_args.append("stats-account-failed=%s" %
-                          (self.account_failed and "on" or "off"))
-        drive_args.append("file.image.read-zeroes=on")
         self.create_blkdebug_file()
-        self.vm = iotests.VM().add_drive('blkdebug:%s:%s://' %
-                                         (blkdebug_file, self.test_driver),
-                                         ','.join(drive_args))
+        self.vm = iotests.VM()
+
+        drive_args = [
+            "file.image.read-zeroes=on",
+        ]
+        if self.stats_in_device:
+            interface = "none"
+            dev_args = {
+                "driver": "virtio-blk",
+                "id": "virtio0",
+                "drive": "drive0",
+                "stats-intervals": [ interval_length ],
+                "account-invalid": "on" if self.account_invalid else "off",
+                "account-failed": "on" if self.account_failed else "off",
+            }
+            self.vm.add_device(json.dumps(dev_args))
+        else:
+            assert not self.use_blockdev
+            interface = "virtio"
+            drive_args += [
+                "stats-intervals.0=%d" % interval_length,
+                "stats-account-invalid=%s" %
+                    (self.account_invalid and "on" or "off"),
+                "stats-account-failed=%s" %
+                    (self.account_failed and "on" or "off"),
+            ]
+
+        if self.use_blockdev:
+            blockdev_args = {
+                "node-name": "drive0",
+                "driver": "raw",
+                "file": {
+                    "driver": "blkdebug",
+                    "config": blkdebug_file,
+                    "image": {
+                        "driver": self.test_driver,
+                        "read-zeroes": True,
+                    },
+                },
+            }
+            self.vm.add_blockdev(json.dumps(blockdev_args))
+        else:
+            self.vm.add_drive('blkdebug:%s:%s://' %
+                              (blkdebug_file, self.test_driver),
+                              ','.join(drive_args),
+                              interface=interface)
+
         self.vm.launch()
         # Set an initial value for the clock
         self.vm.qtest("clock_step %d" % nsec_per_sec)
@@ -261,7 +307,7 @@ sector = "%d"
 
         # Now perform all operations
         for op in ops:
-            self.vm.hmp_qemu_io("drive0", op)
+            self.qemu_io(op)
 
         # Update the expected totals
         self.total_rd_bytes += rd_ops * rd_size
@@ -328,6 +374,12 @@ sector = "%d"
         # All values must be sane before doing any I/O
         self.check_values()
 
+class BlockDeviceStatsTestDevice(BlockDeviceStatsTestCase):
+    stats_in_device = True
+
+class BlockDeviceStatsTestBlockdev(BlockDeviceStatsTestCase):
+    stats_in_device = True
+    use_blockdev = True
 
 class BlockDeviceStatsTestAccountInvalid(BlockDeviceStatsTestCase):
     account_invalid = True
@@ -341,6 +393,17 @@ class BlockDeviceStatsTestAccountBoth(BlockDeviceStatsTestCase):
     account_invalid = True
     account_failed = True
 
+class BlockDeviceStatsTestAccountBothDevice(BlockDeviceStatsTestCase):
+    account_invalid = True
+    account_failed = True
+    stats_in_device = True
+
+class BlockDeviceStatsTestAccountBothBlockdev(BlockDeviceStatsTestCase):
+    account_invalid = True
+    account_failed = True
+    stats_in_device = True
+    use_blockdev = True
+
 class BlockDeviceStatsTestCoroutine(BlockDeviceStatsTestCase):
     test_driver = "null-co"
 
diff --git a/tests/qemu-iotests/136.out b/tests/qemu-iotests/136.out
index cfa5c0d0e66..4823c113d58 100644
--- a/tests/qemu-iotests/136.out
+++ b/tests/qemu-iotests/136.out
@@ -1,5 +1,5 @@
-...................................
+...............................................................
 ----------------------------------------------------------------------
-Ran 35 tests
+Ran 63 tests
 
 OK
-- 
2.54.0
Re: [PATCH] iotests/136: Test stats-intervals with -blockdev/-device
Posted by Stefan Hajnoczi 2 days, 22 hours ago
On Thu, May 21, 2026 at 12:18:54PM +0200, Kevin Wolf wrote:
> 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>
> ---
>  tests/qemu-iotests/136     | 87 ++++++++++++++++++++++++++++++++------
>  tests/qemu-iotests/136.out |  4 +-
>  2 files changed, 77 insertions(+), 14 deletions(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>