Skip to content

Commit

Permalink
Merge tag 'pull-request-2022-09-28' of https://gitlab.com/thuth/qemu
Browse files Browse the repository at this point in the history
…into staging

* Fixes for qtests and unit tests to be more portable to non-POSIX platforms

# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmMz9MQRHHRodXRoQHJl
# ZGhhdC5jb20ACgkQLtnXdP5wLbVUKRAAnubo/wtHqjxg/yVO68odX2LFI2koligA
# LcEAnhGkVJ/Pe/+Qo9yVbcOY6k6xfGQU3VIipqvLEwPAdSF0E43EJxlImBNm8/Zq
# MggjNoepXRhdFGULONSmSNm7HJykLH/CHdmBjPLrbpkTCwWG1gg64xP9fI+b8mGf
# vST0ADuYloLDA9J45UbC33AD+9dQsy2GeOs8X99O6ysKF3htEqMD3vBdqKiJSwgT
# 2c7UqySGECn6kMHl7iAdipRNUghSgzpUe8LcH4jP7Y1XnoB3zwC/+VrOVwFESI6y
# LVFsC8u7cEKKSYunoowfQTgHvYbCuSdrDqljy17NE5qRMziKMTnhXaQNR5wtBKNt
# HZxvc082P/QDFdBYYY3MIjB27r/I6x0t6Xl4IVwLz7bK0xfHFF8Ba2Lr57/2RTc/
# SMPDxGrMicTPnPDU/Cw5VROMmw0OC/tVpJMGo1VjVnNESo581RAMApyzkWiUyfZj
# ktKd+4ihmqrBXcZHVjKbIufa6eKNuktlkfv72dnJY4XoUlDHlbDYaVuknybZmxWK
# 9/CDVDG72s5Cqm+M47Q56IagVVZwIGrUP0u3j3h/v0rnHZehY8Qzr3SLEfeqmUb6
# nP7MP+ItZFZtMITdvXb3OtyeVuM0ZSw8kt+/evpvC9zB6FjgYl/e5FppsO0HxB/O
# PeeV43Bk270=
# =n+FM
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 28 Sep 2022 03:16:20 EDT
# gpg:                using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg:                issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* tag 'pull-request-2022-09-28' of https://gitlab.com/thuth/qemu: (37 commits)
  docs/devel: testing: Document writing portable test cases
  tests/qtest: boot-serial-test: Close the serial file before starting QEMU
  tests/qtest: vhost-user-test: Avoid using hardcoded /tmp
  tests/qtest: qmp-test: Avoid using hardcoded /tmp
  tests/qtest: pflash-cfi02-test: Avoid using hardcoded /tmp
  tests/qtest: hd-geo-test: Avoid using hardcoded /tmp
  tests/x86: Move common code to function in device-plug-test
  .gitlab-ci.d/windows.yml: Display meson test logs
  tests/qtest: migration-test: Skip running some TLS cases for win32
  tests/qtest: libqtest: Replace the call to close a socket with closesocket()
  tests/qtest: microbit-test: Fix socket access for win32
  tests/qtest: virtio-net-failover: Disable migration tests for win32
  tests/qtest: ide-test: Open file in binary mode
  tests/qtest: migration-test: Disable IO redirection for win32
  tests/qtest: bios-tables-test: Adapt the case for win32
  tests/qtest: {ahci, ide}-test: Use relative path for temporary files for win32
  tests/qtest: libqtest: Exclude the *_fds APIs for win32
  tests/qtest: libqtest: Adapt global_qtest declaration for win32
  tests/qtest: qmp-test: Skip running test_qmp_oob for win32
  tests/qtest: Build test-filter-{mirror, redirector} cases for posix only
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Sep 28, 2022
2 parents 8b38406 + 0b49bc1 commit 7be0e1c
Show file tree
Hide file tree
Showing 31 changed files with 285 additions and 190 deletions.
4 changes: 2 additions & 2 deletions .gitlab-ci.d/windows.yml
Expand Up @@ -61,7 +61,7 @@ msys2-64bit:
- .\msys64\usr\bin\bash -lc './configure --target-list=x86_64-softmmu
--enable-capstone --without-default-devices'
- .\msys64\usr\bin\bash -lc 'make'
- .\msys64\usr\bin\bash -lc 'make check'
- .\msys64\usr\bin\bash -lc 'make check || { cat build/meson-logs/testlog.txt; exit 1; } ;'

msys2-32bit:
extends: .shared_msys2_builder
Expand Down Expand Up @@ -94,4 +94,4 @@ msys2-32bit:
- cd output
- ..\msys64\usr\bin\bash -lc "../configure --target-list=ppc64-softmmu"
- ..\msys64\usr\bin\bash -lc 'make'
- ..\msys64\usr\bin\bash -lc 'make check'
- ..\msys64\usr\bin\bash -lc 'make check || { cat meson-logs/testlog.txt; exit 1; } ;'
30 changes: 30 additions & 0 deletions docs/devel/testing.rst
Expand Up @@ -81,6 +81,36 @@ QTest cases can be executed with
make check-qtest
Writing portable test cases
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Both unit tests and qtests can run on POSIX hosts as well as Windows hosts.
Care must be taken when writing portable test cases that can be built and run
successfully on various hosts. The following list shows some best practices:

* Use portable APIs from glib whenever necessary, e.g.: g_setenv(),
g_mkdtemp(), g_mkdir().
* Avoid using hardcoded /tmp for temporary file directory.
Use g_get_tmp_dir() instead.
* Bear in mind that Windows has different special string representation for
stdin/stdout/stderr and null devices. For example if your test case uses
"/dev/fd/2" and "/dev/null" on Linux, remember to use "2" and "nul" on
Windows instead. Also IO redirection does not work on Windows, so avoid
using "2>nul" whenever necessary.
* If your test cases uses the blkdebug feature, use relative path to pass
the config and image file paths in the command line as Windows absolute
path contains the delimiter ":" which will confuse the blkdebug parser.
* Use double quotes in your extra QEMU commmand line in your test cases
instead of single quotes, as Windows does not drop single quotes when
passing the command line to QEMU.
* Windows opens a file in text mode by default, while a POSIX compliant
implementation treats text files and binary files the same. So if your
test cases opens a file to write some data and later wants to compare the
written data with the original one, be sure to pass the letter 'b' as
part of the mode string to fopen(), or O_BINARY flag for the open() call.
* If a certain test case can only run on POSIX or Linux hosts, use a proper
#ifdef in the codes. If the whole test suite cannot run on Windows, disable
the build in the meson.build file.

QAPI schema tests
~~~~~~~~~~~~~~~~~

Expand Down
36 changes: 27 additions & 9 deletions tests/qtest/ahci-test.c
Expand Up @@ -44,9 +44,9 @@
#define TEST_IMAGE_SIZE_MB_SMALL 64

/*** Globals ***/
static char tmp_path[] = "/tmp/qtest.XXXXXX";
static char debug_path[] = "/tmp/qtest-blkdebug.XXXXXX";
static char mig_socket[] = "/tmp/qtest-migration.XXXXXX";
static char *tmp_path;
static char *debug_path;
static char *mig_socket;
static bool ahci_pedantic;
static const char *imgfmt;
static unsigned test_image_size_mb;
Expand Down Expand Up @@ -1437,10 +1437,10 @@ static void test_ncq_simple(void)

static int prepare_iso(size_t size, unsigned char **buf, char **name)
{
char cdrom_path[] = "/tmp/qtest.iso.XXXXXX";
g_autofree char *cdrom_path = NULL;
unsigned char *patt;
ssize_t ret;
int fd = mkstemp(cdrom_path);
int fd = g_file_open_tmp("qtest.iso.XXXXXX", &cdrom_path, NULL);

g_assert(fd != -1);
g_assert(buf);
Expand Down Expand Up @@ -1833,7 +1833,7 @@ static void create_ahci_io_test(enum IOMode type, enum AddrMode addr,

int main(int argc, char **argv)
{
const char *arch;
const char *arch, *base;
int ret;
int fd;
int c;
Expand Down Expand Up @@ -1871,8 +1871,22 @@ int main(int argc, char **argv)
return 0;
}

/*
* "base" stores the starting point where we create temporary files.
*
* On Windows, this is set to the relative path of current working
* directory, because the absolute path causes the blkdebug filename
* parser fail to parse "blkdebug:path/to/config:path/to/image".
*/
#ifndef _WIN32
base = g_get_tmp_dir();
#else
base = ".";
#endif

/* Create a temporary image */
fd = mkstemp(tmp_path);
tmp_path = g_strdup_printf("%s/qtest.XXXXXX", base);
fd = g_mkstemp(tmp_path);
g_assert(fd >= 0);
if (have_qemu_img()) {
imgfmt = "qcow2";
Expand All @@ -1889,12 +1903,13 @@ int main(int argc, char **argv)
close(fd);

/* Create temporary blkdebug instructions */
fd = mkstemp(debug_path);
debug_path = g_strdup_printf("%s/qtest-blkdebug.XXXXXX", base);
fd = g_mkstemp(debug_path);
g_assert(fd >= 0);
close(fd);

/* Reserve a hollow file to use as a socket for migration tests */
fd = mkstemp(mig_socket);
fd = g_file_open_tmp("qtest-migration.XXXXXX", &mig_socket, NULL);
g_assert(fd >= 0);
close(fd);

Expand Down Expand Up @@ -1947,8 +1962,11 @@ int main(int argc, char **argv)

/* Cleanup */
unlink(tmp_path);
g_free(tmp_path);
unlink(debug_path);
g_free(debug_path);
unlink(mig_socket);
g_free(mig_socket);

return ret;
}
5 changes: 2 additions & 3 deletions tests/qtest/aspeed_smc-test.c
Expand Up @@ -608,16 +608,15 @@ static void test_write_block_protect_bottom_bit(void)
flash_reset();
}

static char tmp_path[] = "/tmp/qtest.m25p80.XXXXXX";

int main(int argc, char **argv)
{
g_autofree char *tmp_path = NULL;
int ret;
int fd;

g_test_init(&argc, &argv, NULL);

fd = mkstemp(tmp_path);
fd = g_file_open_tmp("qtest.m25p80.XXXXXX", &tmp_path, NULL);
g_assert(fd >= 0);
ret = ftruncate(fd, FLASH_SIZE);
g_assert(ret == 0);
Expand Down
12 changes: 9 additions & 3 deletions tests/qtest/bios-tables-test.c
Expand Up @@ -1615,16 +1615,22 @@ static void test_acpi_virt_viot(void)
free_test_data(&data);
}

#ifndef _WIN32
# define DEV_NULL "/dev/null"
#else
# define DEV_NULL "nul"
#endif

static void test_acpi_q35_slic(void)
{
test_data data = {
.machine = MACHINE_Q35,
.variant = ".slic",
};

test_acpi_one("-acpitable sig=SLIC,oem_id='CRASH ',oem_table_id='ME',"
"oem_rev=00002210,asl_compiler_id='qemu',"
"asl_compiler_rev=00000000,data=/dev/null",
test_acpi_one("-acpitable sig=SLIC,oem_id=\"CRASH \",oem_table_id=ME,"
"oem_rev=00002210,asl_compiler_id=qemu,"
"asl_compiler_rev=00000000,data=" DEV_NULL,
&data);
free_test_data(&data);
}
Expand Down
11 changes: 7 additions & 4 deletions tests/qtest/boot-serial-test.c
Expand Up @@ -224,15 +224,16 @@ static bool check_guest_output(QTestState *qts, const testdef_t *test, int fd)
static void test_machine(const void *data)
{
const testdef_t *test = data;
char serialtmp[] = "/tmp/qtest-boot-serial-sXXXXXX";
char codetmp[] = "/tmp/qtest-boot-serial-cXXXXXX";
g_autofree char *serialtmp = NULL;
g_autofree char *codetmp = NULL;
const char *codeparam = "";
const uint8_t *code = NULL;
QTestState *qts;
int ser_fd;

ser_fd = mkstemp(serialtmp);
ser_fd = g_file_open_tmp("qtest-boot-serial-sXXXXXX", &serialtmp, NULL);
g_assert(ser_fd != -1);
close(ser_fd);

if (test->kernel) {
code = test->kernel;
Expand All @@ -246,7 +247,7 @@ static void test_machine(const void *data)
ssize_t wlen;
int code_fd;

code_fd = mkstemp(codetmp);
code_fd = g_file_open_tmp("qtest-boot-serial-cXXXXXX", &codetmp, NULL);
g_assert(code_fd != -1);
wlen = write(code_fd, code, test->codesize);
g_assert(wlen == test->codesize);
Expand All @@ -266,6 +267,8 @@ static void test_machine(const void *data)
unlink(codetmp);
}

ser_fd = open(serialtmp, O_RDONLY);
g_assert(ser_fd != -1);
if (!check_guest_output(qts, test, ser_fd)) {
g_error("Failed to find expected string. Please check '%s'",
serialtmp);
Expand Down
15 changes: 6 additions & 9 deletions tests/qtest/cxl-test.c
Expand Up @@ -93,10 +93,9 @@ static void cxl_2root_port(void)
static void cxl_t3d(void)
{
g_autoptr(GString) cmdline = g_string_new(NULL);
char template[] = "/tmp/cxl-test-XXXXXX";
const char *tmpfs;
g_autofree const char *tmpfs = NULL;

tmpfs = g_mkdtemp(template);
tmpfs = g_dir_make_tmp("cxl-test-XXXXXX", NULL);

g_string_printf(cmdline, QEMU_PXB_CMD QEMU_RP QEMU_T3D, tmpfs, tmpfs);

Expand All @@ -107,10 +106,9 @@ static void cxl_t3d(void)
static void cxl_1pxb_2rp_2t3d(void)
{
g_autoptr(GString) cmdline = g_string_new(NULL);
char template[] = "/tmp/cxl-test-XXXXXX";
const char *tmpfs;
g_autofree const char *tmpfs = NULL;

tmpfs = g_mkdtemp(template);
tmpfs = g_dir_make_tmp("cxl-test-XXXXXX", NULL);

g_string_printf(cmdline, QEMU_PXB_CMD QEMU_2RP QEMU_2T3D,
tmpfs, tmpfs, tmpfs, tmpfs);
Expand All @@ -122,10 +120,9 @@ static void cxl_1pxb_2rp_2t3d(void)
static void cxl_2pxb_4rp_4t3d(void)
{
g_autoptr(GString) cmdline = g_string_new(NULL);
char template[] = "/tmp/cxl-test-XXXXXX";
const char *tmpfs;
g_autofree const char *tmpfs = NULL;

tmpfs = g_mkdtemp(template);
tmpfs = g_dir_make_tmp("cxl-test-XXXXXX", NULL);

g_string_printf(cmdline, QEMU_2PXB_CMD QEMU_4RP QEMU_4T3D,
tmpfs, tmpfs, tmpfs, tmpfs, tmpfs, tmpfs,
Expand Down
42 changes: 17 additions & 25 deletions tests/qtest/device-plug-test.c
Expand Up @@ -61,6 +61,18 @@ static void wait_device_deleted_event(QTestState *qtest, const char *id)
}
}

static void process_device_remove(QTestState *qtest, const char *id)
{
/*
* Request device removal. As the guest is not running, the request won't
* be processed. However during system reset, the removal will be
* handled, removing the device.
*/
device_del(qtest, id);
system_reset(qtest);
wait_device_deleted_event(qtest, id);
}

static void test_pci_unplug_request(void)
{
const char *arch = qtest_get_arch();
Expand All @@ -73,14 +85,7 @@ static void test_pci_unplug_request(void)
QTestState *qtest = qtest_initf("%s -device virtio-mouse-pci,id=dev0",
machine_addition);

/*
* Request device removal. As the guest is not running, the request won't
* be processed. However during system reset, the removal will be
* handled, removing the device.
*/
device_del(qtest, "dev0");
system_reset(qtest);
wait_device_deleted_event(qtest, "dev0");
process_device_remove(qtest, "dev0");

qtest_quit(qtest);
}
Expand All @@ -98,14 +103,7 @@ static void test_pci_unplug_json_request(void)
"%s -device \"{'driver': 'virtio-mouse-pci', 'id': 'dev0'}\"",
machine_addition);

/*
* Request device removal. As the guest is not running, the request won't
* be processed. However during system reset, the removal will be
* handled, removing the device.
*/
device_del(qtest, "dev0");
system_reset(qtest);
wait_device_deleted_event(qtest, "dev0");
process_device_remove(qtest, "dev0");

qtest_quit(qtest);
}
Expand All @@ -128,9 +126,7 @@ static void test_spapr_cpu_unplug_request(void)
"-device power9_v2.0-spapr-cpu-core,core-id=1,id=dev0");

/* similar to test_pci_unplug_request */
device_del(qtest, "dev0");
system_reset(qtest);
wait_device_deleted_event(qtest, "dev0");
process_device_remove(qtest, "dev0");

qtest_quit(qtest);
}
Expand All @@ -144,9 +140,7 @@ static void test_spapr_memory_unplug_request(void)
"-device pc-dimm,id=dev0,memdev=mem0");

/* similar to test_pci_unplug_request */
device_del(qtest, "dev0");
system_reset(qtest);
wait_device_deleted_event(qtest, "dev0");
process_device_remove(qtest, "dev0");

qtest_quit(qtest);
}
Expand All @@ -158,9 +152,7 @@ static void test_spapr_phb_unplug_request(void)
qtest = qtest_initf("-device spapr-pci-host-bridge,index=1,id=dev0");

/* similar to test_pci_unplug_request */
device_del(qtest, "dev0");
system_reset(qtest);
wait_device_deleted_event(qtest, "dev0");
process_device_remove(qtest, "dev0");

qtest_quit(qtest);
}
Expand Down
5 changes: 3 additions & 2 deletions tests/qtest/fdc-test.c
Expand Up @@ -68,7 +68,7 @@ enum {
DSKCHG = 0x80,
};

static char test_image[] = "/tmp/qtest.XXXXXX";
static char *test_image;

#define assert_bit_set(data, mask) g_assert_cmphex((data) & (mask), ==, (mask))
#define assert_bit_clear(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
Expand Down Expand Up @@ -608,7 +608,7 @@ int main(int argc, char **argv)
int ret;

/* Create a temporary raw image */
fd = mkstemp(test_image);
fd = g_file_open_tmp("qtest.XXXXXX", &test_image, NULL);
g_assert(fd >= 0);
ret = ftruncate(fd, TEST_IMAGE_SIZE);
g_assert(ret == 0);
Expand Down Expand Up @@ -640,6 +640,7 @@ int main(int argc, char **argv)
/* Cleanup */
qtest_end();
unlink(test_image);
g_free(test_image);

return ret;
}
4 changes: 2 additions & 2 deletions tests/qtest/fuzz/generic_fuzz_configs.h
Expand Up @@ -20,8 +20,8 @@ typedef struct generic_fuzz_config {
} generic_fuzz_config;

static inline gchar *generic_fuzzer_virtio_9p_args(void){
char tmpdir[] = "/tmp/qemu-fuzz.XXXXXX";
g_assert_nonnull(g_mkdtemp(tmpdir));
g_autofree char *tmpdir = g_dir_make_tmp("qemu-fuzz.XXXXXX", NULL);
g_assert_nonnull(tmpdir);

return g_strdup_printf("-machine q35 -nodefaults "
"-device virtio-9p,fsdev=hshare,mount_tag=hshare "
Expand Down
4 changes: 2 additions & 2 deletions tests/qtest/fuzz/virtio_blk_fuzz.c
Expand Up @@ -181,10 +181,10 @@ static void drive_destroy(void *path)
static char *drive_create(void)
{
int fd, ret;
char *t_path = g_strdup("/tmp/qtest.XXXXXX");
char *t_path;

/* Create a temporary raw image */
fd = mkstemp(t_path);
fd = g_file_open_tmp("qtest.XXXXXX", &t_path, NULL);
g_assert_cmpint(fd, >=, 0);
ret = ftruncate(fd, TEST_IMAGE_SIZE);
g_assert_cmpint(ret, ==, 0);
Expand Down

0 comments on commit 7be0e1c

Please sign in to comment.