Introduce a "_flaky_test" function for shell based I/O tests which
accepts a GitLab issue URL, and causes the I/O test to be skipped
unless the $QEMU_TEST_FLAKY_TESTS environment variable is set.

The equivalent "skip_flaky" test decorator is added for python based
I/O tests with the same behaviour.

This is used by:

  * Test 151 which fails in QEMU private AWS runners due to failure
    to make progress in time
  * Test 181 which fails with a non-responsive QEMU on AWS runners
    with the QED format
  * Test 185 which fails in GitLab shared runners
  * Test 308 which fails to see disk usage increase after fallocate

Signed-off-by: Daniel P. Berrangé <[email protected]>
---

Previously posted as part of the larger I/O tests series. Attempted
to merge but it failed on AWS private runners, while still passing
on GitLab shared runners.

  https://lists.gnu.org/archive/html/qemu-devel/2026-05/msg04939.html

To skip the further tests we needed changes to iotests.py too, hence
posting for re-review before proposing for merge again

 tests/qemu-iotests/151        |  1 +
 tests/qemu-iotests/181        |  2 ++
 tests/qemu-iotests/185        |  1 +
 tests/qemu-iotests/308        |  2 ++
 tests/qemu-iotests/common.rc  | 16 ++++++++++++++++
 tests/qemu-iotests/iotests.py | 16 ++++++++++++++++
 6 files changed, 38 insertions(+)

diff --git a/tests/qemu-iotests/151 b/tests/qemu-iotests/151
index 9b9c815db5..647194094a 100755
--- a/tests/qemu-iotests/151
+++ b/tests/qemu-iotests/151
@@ -308,6 +308,7 @@ class TestThrottledWithNbdExportBase(iotests.QMPTestCase):
 class TestLowThrottledWithNbdExport(TestThrottledWithNbdExportBase):
     iops = 16
 
+    
@iotests.skip_flaky("https://gitlab.com/qemu-project/qemu/-/work_items/3513";)
     def testUnderLoad(self):
         '''
         Throttle the source node, then issue a whole bunch of external requests
diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181
index dc90a10757..b904e8ce01 100755
--- a/tests/qemu-iotests/181
+++ b/tests/qemu-iotests/181
@@ -48,6 +48,8 @@ _unsupported_fmt qcow vdi vhdx vmdk vpc vvfat parallels
 _supported_proto generic
 _supported_os Linux
 
+_flaky_test https://gitlab.com/qemu-project/qemu/-/work_items/3515
+
 size=64M
 _make_test_img $size
 
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
index 17489fb91c..a62ae8d329 100755
--- a/tests/qemu-iotests/185
+++ b/tests/qemu-iotests/185
@@ -50,6 +50,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 _supported_fmt qcow2
 _supported_proto file
 _supported_os Linux
+_flaky_test https://gitlab.com/qemu-project/qemu/-/issues/3270
 
 size=$((64 * 1048576))
 TEST_IMG="${TEST_IMG}.base" _make_test_img $size
diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308
index f4a06a522e..a2290825f4 100755
--- a/tests/qemu-iotests/308
+++ b/tests/qemu-iotests/308
@@ -53,6 +53,8 @@ _supported_proto file # We create the FUSE export manually
 _supported_os Linux # We need /dev/urandom
 _require_disk_usage
 
+_flaky_test https://gitlab.com/qemu-project/qemu/-/work_items/3514
+
 # $1: Export ID
 # $2: Options (beyond the node-name and ID)
 # $3: Expected return value (defaults to 'return')
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 731e4b2b99..298bc483e0 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -1088,5 +1088,21 @@ _qcow2_dump_header()
     fi
 }
 
+# This must be referenced after any _require_  lines, so that
+# test filtering happens first
+_flaky_test()
+{
+    if test -z "$1"
+    then
+       echo "A GitLab issue URL must be provided for a flaky test"
+       exit 1
+    fi
+
+    if test -z "$QEMU_TEST_FLAKY_TESTS"
+    then
+       _notrun "Test is flaky (see $1) and \$QEMU_TEST_FLAKY_TESTS is not set"
+    fi
+}
+
 # make sure this script returns success
 true
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 05274772ce..072be80e07 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -1603,6 +1603,22 @@ def func_wrapper(*args, **kwargs):
             return func(*args, **kwargs)
     return func_wrapper
 
+def skip_flaky(bugurl):
+    '''Skip Test Decorator
+       Always skips test due to unreliable design.
+       Requires a bug report URL for historical record.'''
+    def skip_test_decorator(func):
+        def func_wrapper(*args, **kwargs):
+            if os.environ.get("QEMU_TEST_FLAKY_TESTS", None) is None:
+                case_notrun(
+                    ('{}: test is flaky (see {}) and $QEMU_TEST_FLAKY_TESTS ' +
+                     'is not set').format(args[0], bugurl))
+                return None
+            else:
+                return func(*args, **kwargs)
+        return func_wrapper
+    return skip_test_decorator
+
 # We need to filter out the time taken from the output so that
 # qemu-iotest can reliably diff the results against master output,
 # and hide skipped tests from the reference output.
-- 
2.54.0


Reply via email to