Commit 9bc9e737a3 for qemu.org

commit 9bc9e737a3844ceeeec1bca6cb558e7a05556ccf
Author: Eric Blake <eblake@redhat.com>
Date:   Tue Nov 10 09:53:58 2026 -0600

    iotests: Refactor python NBD server setup

    Extract code from nbd-multiconn that I plan to use in another upcoming
    unit test.

    Signed-off-by: Eric Blake <eblake@redhat.com>
    Message-ID: <20261110155356.1520433-8-eblake@redhat.com>
    Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 642a160bb2..7017d2016c 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -1385,6 +1385,36 @@ def case_skip(self, reason):
         case_notrun(reason)
         self.skipTest(reason)

+    @contextmanager
+    def run_nbd_server(self, nbd_sock: str,
+                       max_conn: Optional[int] = None) -> Iterator[None]:
+        args: Dict[str, Any] = {
+            'addr': {
+                'type': 'unix',
+                'data': {'path': nbd_sock}
+            }
+        }
+        if max_conn is not None:
+            args['max-connections'] = max_conn
+
+        self.vm.cmd('nbd-server-start', args)
+        try:
+            yield
+        finally:
+            self.vm.cmd('nbd-server-stop')
+
+    def add_nbd_export(self, node_name: str, name: str,
+                       writable: Optional[bool] = None) -> None:
+        args: Dict[str, Any] = {
+            'type': 'nbd',
+            'id': name,
+            'node-name': node_name,
+            'name': name,
+        }
+        if writable is not None:
+            args['writable'] = writable
+
+        self.vm.cmd('block-export-add', args)

 def notrun(reason):
     '''Skip this test suite'''
diff --git a/tests/qemu-iotests/tests/nbd-multiconn b/tests/qemu-iotests/tests/nbd-multiconn
index 479e872f2a..96efe01e58 100755
--- a/tests/qemu-iotests/tests/nbd-multiconn
+++ b/tests/qemu-iotests/tests/nbd-multiconn
@@ -62,55 +62,27 @@ class TestNbdMulticonn(iotests.QMPTestCase):
         except OSError:
             pass

-    @contextmanager
-    def run_server(self, max_connections=None):
-        args = {
-            'addr': {
-                'type': 'unix',
-                'data': {'path': nbd_sock}
-            }
-        }
-        if max_connections is not None:
-            args['max-connections'] = max_connections
-
-        self.vm.cmd('nbd-server-start', args)
-        yield
-
-        self.vm.cmd('nbd-server-stop')
-
-    def add_export(self, name, writable=None):
-        args = {
-            'type': 'nbd',
-            'id': name,
-            'node-name': 'n',
-            'name': name,
-        }
-        if writable is not None:
-            args['writable'] = writable
-
-        self.vm.cmd('block-export-add', args)
-
     def test_default_settings(self):
-        with self.run_server():
-            self.add_export('r')
-            self.add_export('w', writable=True)
+        with self.run_nbd_server(nbd_sock):
+            self.add_nbd_export('n', 'r')
+            self.add_nbd_export('n', 'w', writable=True)
             with open_nbd('r') as h:
                 self.assertTrue(h.can_multi_conn())
             with open_nbd('w') as h:
                 self.assertTrue(h.can_multi_conn())

     def test_limited_connections(self):
-        with self.run_server(max_connections=1):
-            self.add_export('r')
-            self.add_export('w', writable=True)
+        with self.run_nbd_server(nbd_sock, max_conn=1):
+            self.add_nbd_export('n', 'r')
+            self.add_nbd_export('n', 'w', writable=True)
             with open_nbd('r') as h:
                 self.assertFalse(h.can_multi_conn())
             with open_nbd('w') as h:
                 self.assertFalse(h.can_multi_conn())

     def test_parallel_writes(self):
-        with self.run_server():
-            self.add_export('w', writable=True)
+        with self.run_nbd_server(nbd_sock):
+            self.add_nbd_export('n', 'w', writable=True)

             clients = [nbd.NBD() for _ in range(3)]
             for c in clients: