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 <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Peter Krempa 2023-12-01 16:47:23 +01:00
parent 91116e35b6
commit 3a85755f66
5 changed files with 80 additions and 2 deletions

View File

@ -73,7 +73,7 @@ mymain(void)
{ {
int ret = 0; int ret = 0;
g_autoptr(virConnect) conn = NULL; g_autoptr(virConnect) conn = NULL;
struct testQemuConf testConf = { NULL, NULL, NULL, NULL }; struct testQemuConf testConf = { NULL, NULL, NULL, NULL, NULL };
if (qemuTestDriverInit(&driver) < 0) if (qemuTestDriverInit(&driver) < 0)
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -623,6 +623,9 @@ testCompareXMLToArgv(const void *data)
virArch arch = VIR_ARCH_NONE; virArch arch = VIR_ARCH_NONE;
g_autoptr(virIdentity) sysident = virIdentityGetSystem(); 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) if (testQemuInfoInitArgs((struct testQemuInfo *) info) < 0)
goto cleanup; goto cleanup;
@ -820,22 +823,76 @@ testInfoSetPaths(struct testQemuInfo *info,
abs_srcdir, info->name, suffix ? suffix : ""); 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 static int
mymain(void) mymain(void)
{ {
int ret = 0; int ret = 0;
g_autoptr(GHashTable) duplicateTests = virHashNew(NULL); g_autoptr(GHashTable) duplicateTests = virHashNew(NULL);
g_autoptr(GHashTable) existingTestCases = virHashNew(NULL);
g_autoptr(GHashTable) capslatest = testQemuGetLatestCaps(); g_autoptr(GHashTable) capslatest = testQemuGetLatestCaps();
g_autoptr(GHashTable) qapiSchemaCache = virHashNew((GDestroyNotify) g_hash_table_unref); g_autoptr(GHashTable) qapiSchemaCache = virHashNew((GDestroyNotify) g_hash_table_unref);
g_autoptr(GHashTable) capscache = virHashNew(virObjectUnref); g_autoptr(GHashTable) capscache = virHashNew(virObjectUnref);
struct testQemuConf testConf = { .capslatest = capslatest, struct testQemuConf testConf = { .capslatest = capslatest,
.capscache = capscache, .capscache = capscache,
.qapiSchemaCache = qapiSchemaCache, .qapiSchemaCache = qapiSchemaCache,
.duplicateTests = duplicateTests }; .duplicateTests = duplicateTests,
.existingTestCases = existingTestCases };
if (!capslatest) if (!capslatest)
return EXIT_FAILURE; 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. /* Set the timezone because we are mocking the time() function.
* If we don't do that, then localtime() may return unpredictable * If we don't do that, then localtime() may return unpredictable
* results. In order to detect things that just work by a blind * 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-incorrect");
DO_TEST_CAPS_LATEST("tap-vhost"); DO_TEST_CAPS_LATEST("tap-vhost");
/* check that all input files were actually used here */
if (testConfXMLCheck(existingTestCases) < 0)
ret = -1;
qemuTestDriverFree(&driver); qemuTestDriverFree(&driver);
virFileWrapperClearPrefixes(); virFileWrapperClearPrefixes();

View File

@ -746,6 +746,20 @@ virTestGetRegenerate(void)
return testRegenerate; 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 static int
virTestSetEnvPath(void) virTestSetEnvPath(void)
{ {

View File

@ -82,6 +82,8 @@ unsigned int virTestGetExpensive(void);
unsigned int virTestGetRegenerate(void); unsigned int virTestGetRegenerate(void);
void virTestPropagateLibvirtError(void); void virTestPropagateLibvirtError(void);
bool virTestHasRangeBitmap(void);
#define VIR_TEST_DEBUG(fmt, ...) \ #define VIR_TEST_DEBUG(fmt, ...) \
do { \ do { \
if (virTestGetDebug()) \ if (virTestGetDebug()) \

View File

@ -70,6 +70,7 @@ struct testQemuConf {
GHashTable *capslatest; GHashTable *capslatest;
GHashTable *qapiSchemaCache; GHashTable *qapiSchemaCache;
GHashTable *duplicateTests; /* for checking duplicated invocations */ GHashTable *duplicateTests; /* for checking duplicated invocations */
GHashTable *existingTestCases; /* for checking missing invocations */
}; };
typedef enum { typedef enum {