From 3a85755f668abd15b7936778a6a13fb8ce4a8c12 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Fri, 1 Dec 2023 16:47:23 +0100 Subject: [PATCH] qemuxml2argvtest: Add checker that all input files are used To prevent regressions when refactoring tests and accidentally forgotten input files make sure that qemuxml2argvtest is invoked for all input files in tests/qemuxml2argvdata Signed-off-by: Peter Krempa Reviewed-by: Michal Privoznik --- tests/qemustatusxml2xmltest.c | 2 +- tests/qemuxml2argvtest.c | 63 ++++++++++++++++++++++++++++++++++- tests/testutils.c | 14 ++++++++ tests/testutils.h | 2 ++ tests/testutilsqemu.h | 1 + 5 files changed, 80 insertions(+), 2 deletions(-) diff --git a/tests/qemustatusxml2xmltest.c b/tests/qemustatusxml2xmltest.c index 4796b62853..f60378c691 100644 --- a/tests/qemustatusxml2xmltest.c +++ b/tests/qemustatusxml2xmltest.c @@ -73,7 +73,7 @@ mymain(void) { int ret = 0; g_autoptr(virConnect) conn = NULL; - struct testQemuConf testConf = { NULL, NULL, NULL, NULL }; + struct testQemuConf testConf = { NULL, NULL, NULL, NULL, NULL }; if (qemuTestDriverInit(&driver) < 0) return EXIT_FAILURE; diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 9a93fd8990..cb78465fc2 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -623,6 +623,9 @@ testCompareXMLToArgv(const void *data) virArch arch = VIR_ARCH_NONE; g_autoptr(virIdentity) sysident = virIdentityGetSystem(); + /* mark test case as used */ + ignore_value(g_hash_table_remove(info->conf->existingTestCases, info->infile)); + if (testQemuInfoInitArgs((struct testQemuInfo *) info) < 0) goto cleanup; @@ -820,22 +823,76 @@ testInfoSetPaths(struct testQemuInfo *info, abs_srcdir, info->name, suffix ? suffix : ""); } + +static int +testConfXMLCheck(GHashTable *existingTestCases) +{ + g_autofree virHashKeyValuePair *items = virHashGetItems(existingTestCases, NULL, true); + size_t i; + int ret = 0; + + for (i = 0; items[i].key; i++) { + if (ret == 0) + fprintf(stderr, "\n"); + + fprintf(stderr, "unused input file: %s\n", (const char *) items[i].key); + ret = -1; + } + + return ret; +} + + +static int +testConfXMLEnumerate(GHashTable *existingTestCases) +{ + struct dirent *ent; + g_autoptr(DIR) dir = NULL; + int rc; + + /* If VIR_TEST_RANGE is in use don't bother filling in the data, which + * also makes testConfXMLCheck succeed. */ + if (virTestHasRangeBitmap()) + return 0; + + if (virDirOpen(&dir, abs_srcdir "/qemuxml2argvdata") < 0) + return -1; + + while ((rc = virDirRead(dir, &ent, abs_srcdir "/qemuxml2argvdata")) > 0) { + if (virStringHasSuffix(ent->d_name, ".xml")) { + g_hash_table_insert(existingTestCases, + g_strdup_printf(abs_srcdir "/qemuxml2argvdata/%s", ent->d_name), + NULL); + } + } + + return rc; +} + + static int mymain(void) { int ret = 0; g_autoptr(GHashTable) duplicateTests = virHashNew(NULL); + g_autoptr(GHashTable) existingTestCases = virHashNew(NULL); g_autoptr(GHashTable) capslatest = testQemuGetLatestCaps(); g_autoptr(GHashTable) qapiSchemaCache = virHashNew((GDestroyNotify) g_hash_table_unref); g_autoptr(GHashTable) capscache = virHashNew(virObjectUnref); struct testQemuConf testConf = { .capslatest = capslatest, .capscache = capscache, .qapiSchemaCache = qapiSchemaCache, - .duplicateTests = duplicateTests }; + .duplicateTests = duplicateTests, + .existingTestCases = existingTestCases }; if (!capslatest) return EXIT_FAILURE; + /* enumerate and store all available test cases to verify at the end that + * all of them were invoked */ + if (testConfXMLEnumerate(existingTestCases) < 0) + return EXIT_FAILURE; + /* Set the timezone because we are mocking the time() function. * If we don't do that, then localtime() may return unpredictable * results. In order to detect things that just work by a blind @@ -2600,6 +2657,10 @@ mymain(void) DO_TEST_CAPS_LATEST("tap-vhost-incorrect"); DO_TEST_CAPS_LATEST("tap-vhost"); + /* check that all input files were actually used here */ + if (testConfXMLCheck(existingTestCases) < 0) + ret = -1; + qemuTestDriverFree(&driver); virFileWrapperClearPrefixes(); diff --git a/tests/testutils.c b/tests/testutils.c index e546422941..b20e447b99 100644 --- a/tests/testutils.c +++ b/tests/testutils.c @@ -746,6 +746,20 @@ virTestGetRegenerate(void) return testRegenerate; } + +/** + * virTestHasRangeBitmap: + * + * Returns whether the test was invoked with VIR_TEST_RANGE declared thus + * limiting the run only on specific test cases. + */ +bool +virTestHasRangeBitmap(void) +{ + return !!testBitmap; +} + + static int virTestSetEnvPath(void) { diff --git a/tests/testutils.h b/tests/testutils.h index cf8a346dff..bb84327b1e 100644 --- a/tests/testutils.h +++ b/tests/testutils.h @@ -82,6 +82,8 @@ unsigned int virTestGetExpensive(void); unsigned int virTestGetRegenerate(void); void virTestPropagateLibvirtError(void); +bool virTestHasRangeBitmap(void); + #define VIR_TEST_DEBUG(fmt, ...) \ do { \ if (virTestGetDebug()) \ diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h index 71e220de3a..0d570ec31e 100644 --- a/tests/testutilsqemu.h +++ b/tests/testutilsqemu.h @@ -70,6 +70,7 @@ struct testQemuConf { GHashTable *capslatest; GHashTable *qapiSchemaCache; GHashTable *duplicateTests; /* for checking duplicated invocations */ + GHashTable *existingTestCases; /* for checking missing invocations */ }; typedef enum {