diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/functional/qemu_test/__init__.py | 2 | ||||
-rw-r--r-- | tests/functional/qemu_test/decorators.py | 15 | ||||
-rwxr-xr-x | tests/functional/test_aarch64_replay.py | 4 | ||||
-rwxr-xr-x | tests/functional/test_aarch64_rme_virt.py | 4 | ||||
-rw-r--r-- | tests/qapi-schema/doc-good.json | 2 | ||||
-rw-r--r-- | tests/qapi-schema/doc-good.out | 2 | ||||
-rw-r--r-- | tests/qapi-schema/doc-good.txt | 2 | ||||
-rwxr-xr-x | tests/qemu-iotests/162 | 1 | ||||
-rwxr-xr-x | tests/qemu-iotests/tests/qcow2-encryption | 75 | ||||
-rw-r--r-- | tests/qemu-iotests/tests/qcow2-encryption.out | 32 | ||||
-rw-r--r-- | tests/qtest/libqtest.c | 1 | ||||
-rw-r--r-- | tests/unit/test-bdrv-drain.c | 32 |
12 files changed, 151 insertions, 21 deletions
diff --git a/tests/functional/qemu_test/__init__.py b/tests/functional/qemu_test/__init__.py index 45f7bef..af41c2c 100644 --- a/tests/functional/qemu_test/__init__.py +++ b/tests/functional/qemu_test/__init__.py @@ -15,6 +15,6 @@ from .testcase import QemuBaseTest, QemuUserTest, QemuSystemTest from .linuxkernel import LinuxKernelTest from .decorators import skipIfMissingCommands, skipIfNotMachine, \ skipFlakyTest, skipUntrustedTest, skipBigDataTest, skipSlowTest, \ - skipIfMissingImports + skipIfMissingImports, skipIfOperatingSystem from .archive import archive_extract from .uncompress import uncompress diff --git a/tests/functional/qemu_test/decorators.py b/tests/functional/qemu_test/decorators.py index 1651eb7..50d29de 100644 --- a/tests/functional/qemu_test/decorators.py +++ b/tests/functional/qemu_test/decorators.py @@ -5,7 +5,7 @@ import importlib import os import platform -from unittest import skipUnless +from unittest import skipIf, skipUnless from .cmd import which @@ -28,6 +28,19 @@ def skipIfMissingCommands(*args): ''' Decorator to skip execution of a test if the current +host operating system does match one of the prohibited +ones. +Example + + @skipIfOperatingSystem("Linux", "Darwin") +''' +def skipIfOperatingSystem(*args): + return skipIf(platform.system() in args, + 'running on an OS (%s) that is not able to run this test' % + ", ".join(args)) + +''' +Decorator to skip execution of a test if the current host machine does not match one of the permitted machines. Example diff --git a/tests/functional/test_aarch64_replay.py b/tests/functional/test_aarch64_replay.py index 04cde43..029fef3 100755 --- a/tests/functional/test_aarch64_replay.py +++ b/tests/functional/test_aarch64_replay.py @@ -5,7 +5,7 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -from qemu_test import Asset +from qemu_test import Asset, skipIfOperatingSystem from replay_kernel import ReplayKernelBase @@ -16,6 +16,8 @@ class Aarch64Replay(ReplayKernelBase): 'releases/29/Everything/aarch64/os/images/pxeboot/vmlinuz'), '7e1430b81c26bdd0da025eeb8fbd77b5dc961da4364af26e771bd39f379cbbf7') + # Failing on Darwin: https://gitlab.com/qemu-project/qemu/-/issues/2907 + @skipIfOperatingSystem('Darwin') def test_aarch64_virt(self): self.set_machine('virt') self.cpu = 'cortex-a53' diff --git a/tests/functional/test_aarch64_rme_virt.py b/tests/functional/test_aarch64_rme_virt.py index f4ad4d3..a1abf58 100755 --- a/tests/functional/test_aarch64_rme_virt.py +++ b/tests/functional/test_aarch64_rme_virt.py @@ -87,7 +87,9 @@ class Aarch64RMEVirtMachine(QemuSystemTest): self.vm.add_args('-fsdev', f'local,security_model=none,path={rme_stack},id=shr0') self.vm.add_args('-device', 'virtio-net-pci,netdev=net0') self.vm.add_args('-netdev', 'user,id=net0') - self.vm.add_args('-append', 'root=/dev/vda') + # We need to add nokaslr to avoid triggering this sporadic bug: + # https://gitlab.com/qemu-project/qemu/-/issues/2823 + self.vm.add_args('-append', 'root=/dev/vda nokaslr') self.vm.launch() # Wait for host VM boot to complete. diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json index 0a4f139..14b808f 100644 --- a/tests/qapi-schema/doc-good.json +++ b/tests/qapi-schema/doc-good.json @@ -212,7 +212,7 @@ # # -> "this example" # -# <- "has no title" +# <- ... has no title ... ## { 'command': 'cmd-boxed', 'boxed': true, 'data': 'Object', diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 5773f1d..dc8352e 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -217,7 +217,7 @@ another feature -> "this example" - <- "has no title" + <- ... has no title ... doc symbol=EVT_BOXED body= diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt index cb37db6..17a1d56 100644 --- a/tests/qapi-schema/doc-good.txt +++ b/tests/qapi-schema/doc-good.txt @@ -264,7 +264,7 @@ Example:: -> "this example" - <- "has no title" + <- ... has no title ... "EVT_BOXED" (Event) diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162 index 956c2c5..94dae60 100755 --- a/tests/qemu-iotests/162 +++ b/tests/qemu-iotests/162 @@ -65,7 +65,6 @@ done $QEMU_IMG info "json:{'driver': 'nbd', 'host': 'localhost', 'port': $port}" \ | grep '^image' | sed -e "s/$port/PORT/" -_stop_nbd_server # This is a test for NBD's bdrv_refresh_filename() implementation: It expects # either host or path to be set, but it must not assume that they are set to diff --git a/tests/qemu-iotests/tests/qcow2-encryption b/tests/qemu-iotests/tests/qcow2-encryption new file mode 100755 index 0000000..95f6195 --- /dev/null +++ b/tests/qemu-iotests/tests/qcow2-encryption @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +# group: rw quick +# +# Test case for encryption support in qcow2 +# +# Copyright (C) 2025 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +# creator +owner=kwolf@redhat.com + +seq="$(basename $0)" +echo "QA output created by $seq" + +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ../common.rc +. ../common.filter + +# This tests qcow2-specific low-level functionality +_supported_fmt qcow2 +_supported_proto file +_require_working_luks + +IMG_SIZE=64M + +echo +echo "=== Create an encrypted image ===" +echo + +_make_test_img --object secret,id=sec0,data=123456 -o encrypt.format=luks,encrypt.key-secret=sec0 $IMG_SIZE +$PYTHON ../qcow2.py "$TEST_IMG" dump-header-exts +_img_info +$QEMU_IMG check \ + --object secret,id=sec0,data=123456 \ + --image-opts file.filename="$TEST_IMG",encrypt.key-secret=sec0 \ + | _filter_qemu_img_check + +echo +echo "=== Remove the header extension ===" +echo + +$PYTHON ../qcow2.py "$TEST_IMG" del-header-ext 0x0537be77 +$PYTHON ../qcow2.py "$TEST_IMG" dump-header-exts +_img_info +$QEMU_IMG check \ + --object secret,id=sec0,data=123456 \ + --image-opts file.filename="$TEST_IMG",encrypt.key-secret=sec0 2>&1 \ + | _filter_qemu_img_check \ + | _filter_testdir + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/tests/qcow2-encryption.out b/tests/qemu-iotests/tests/qcow2-encryption.out new file mode 100644 index 0000000..9b549dc2 --- /dev/null +++ b/tests/qemu-iotests/tests/qcow2-encryption.out @@ -0,0 +1,32 @@ +QA output created by qcow2-encryption + +=== Create an encrypted image === + +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +Header extension: +magic 0x537be77 (Crypto header) +length 16 +data <binary> + +Header extension: +magic 0x6803f857 (Feature table) +length 384 +data <binary> + +image: TEST_DIR/t.IMGFMT +file format: IMGFMT +virtual size: 64 MiB (67108864 bytes) +encrypted: yes +cluster_size: 65536 +No errors were found on the image. + +=== Remove the header extension === + +Header extension: +magic 0x6803f857 (Feature table) +length 384 +data <binary> + +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Missing CRYPTO header for crypt method 2 +qemu-img: Could not open 'file.filename=TEST_DIR/t.qcow2,encrypt.key-secret=sec0': Missing CRYPTO header for crypt method 2 +*** done diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index 2750067..fad307d 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -1788,6 +1788,7 @@ void qtest_cb_for_every_machine(void (*cb)(const char *machine), if (!strncmp("xenfv", machines[i].name, 5) || g_str_equal("xenpv", machines[i].name) || g_str_equal("xenpvh", machines[i].name) || + g_str_equal("vmapple", machines[i].name) || g_str_equal("nitro-enclave", machines[i].name)) { continue; } diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c index 7410e6f..290cd2a 100644 --- a/tests/unit/test-bdrv-drain.c +++ b/tests/unit/test-bdrv-drain.c @@ -632,6 +632,8 @@ typedef struct TestBlockJob { BlockDriverState *bs; int run_ret; int prepare_ret; + + /* Accessed with atomics */ bool running; bool should_complete; } TestBlockJob; @@ -667,10 +669,10 @@ static int coroutine_fn test_job_run(Job *job, Error **errp) /* We are running the actual job code past the pause point in * job_co_entry(). */ - s->running = true; + qatomic_set(&s->running, true); job_transition_to_ready(&s->common.job); - while (!s->should_complete) { + while (!qatomic_read(&s->should_complete)) { /* Avoid job_sleep_ns() because it marks the job as !busy. We want to * emulate some actual activity (probably some I/O) here so that drain * has to wait for this activity to stop. */ @@ -685,7 +687,7 @@ static int coroutine_fn test_job_run(Job *job, Error **errp) static void test_job_complete(Job *job, Error **errp) { TestBlockJob *s = container_of(job, TestBlockJob, common.job); - s->should_complete = true; + qatomic_set(&s->should_complete, true); } BlockJobDriver test_job_driver = { @@ -791,7 +793,7 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type, /* job_co_entry() is run in the I/O thread, wait for the actual job * code to start (we don't want to catch the job in the pause point in * job_co_entry(). */ - while (!tjob->running) { + while (!qatomic_read(&tjob->running)) { aio_poll(qemu_get_aio_context(), false); } } @@ -799,7 +801,7 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type, WITH_JOB_LOCK_GUARD() { g_assert_cmpint(job->job.pause_count, ==, 0); g_assert_false(job->job.paused); - g_assert_true(tjob->running); + g_assert_true(qatomic_read(&tjob->running)); g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ } @@ -825,7 +827,7 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type, * * paused is reset in the I/O thread, wait for it */ - while (job->job.paused) { + while (job_is_paused(&job->job)) { aio_poll(qemu_get_aio_context(), false); } } @@ -858,7 +860,7 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type, * * paused is reset in the I/O thread, wait for it */ - while (job->job.paused) { + while (job_is_paused(&job->job)) { aio_poll(qemu_get_aio_context(), false); } } @@ -1411,10 +1413,12 @@ static void test_set_aio_context(void) typedef struct TestDropBackingBlockJob { BlockJob common; - bool should_complete; bool *did_complete; BlockDriverState *detach_also; BlockDriverState *bs; + + /* Accessed with atomics */ + bool should_complete; } TestDropBackingBlockJob; static int coroutine_fn test_drop_backing_job_run(Job *job, Error **errp) @@ -1422,7 +1426,7 @@ static int coroutine_fn test_drop_backing_job_run(Job *job, Error **errp) TestDropBackingBlockJob *s = container_of(job, TestDropBackingBlockJob, common.job); - while (!s->should_complete) { + while (!qatomic_read(&s->should_complete)) { job_sleep_ns(job, 0); } @@ -1541,7 +1545,7 @@ static void test_blockjob_commit_by_drained_end(void) job_start(&job->common.job); - job->should_complete = true; + qatomic_set(&job->should_complete, true); bdrv_drained_begin(bs_child); g_assert(!job_has_completed); bdrv_drained_end(bs_child); @@ -1557,15 +1561,17 @@ static void test_blockjob_commit_by_drained_end(void) typedef struct TestSimpleBlockJob { BlockJob common; - bool should_complete; bool *did_complete; + + /* Accessed with atomics */ + bool should_complete; } TestSimpleBlockJob; static int coroutine_fn test_simple_job_run(Job *job, Error **errp) { TestSimpleBlockJob *s = container_of(job, TestSimpleBlockJob, common.job); - while (!s->should_complete) { + while (!qatomic_read(&s->should_complete)) { job_sleep_ns(job, 0); } @@ -1700,7 +1706,7 @@ static void test_drop_intermediate_poll(void) job->did_complete = &job_has_completed; job_start(&job->common.job); - job->should_complete = true; + qatomic_set(&job->should_complete, true); g_assert(!job_has_completed); ret = bdrv_drop_intermediate(chain[1], chain[0], NULL, false); |