From nobody Mon Feb 9 01:52:08 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1603110177; cv=none; d=zohomail.com; s=zohoarc; b=nc3ZoPJCpuPrkGpnPZLLRKJQ2+dTfekWxcYU8zKI2nfyGGcE5hJzBoDaGEePeDFYGCZhAtYxxHC6sTiQ09L7EJTLnYwJ75gz6hl0Osx5c1TietYpyxLNJqk5R3W/0e0ocsufciCjzeYOGDcE617F6M+f3llIIdtphJhnfC6euEE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1603110177; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=vaD+Xt98GebdiuZfd7kC8O7UtffqL7+3j1GoeDp0HzY=; b=BeJXsBMLnIvVn9LUQ6XWqaBMVJl9vJprNg8fZIvsmvUG84vr+VpOALShyrPxbpZxp986pF6ep+T5N2f8q0iZqkbMJZGxOvOoSp4yn05TGvY2CxYJEn6JV5YKldt6yOUwX2rkusoabANkIpYQhQ9RP3XTDfjfbdst3r6nb8OQRs4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1603110177271611.1969076848621; Mon, 19 Oct 2020 05:22:57 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-420--t_-iziAO6C_8GIFUBThHg-1; Mon, 19 Oct 2020 08:22:47 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 65A2E192AB7C; Mon, 19 Oct 2020 12:22:41 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 43F875D9D2; Mon, 19 Oct 2020 12:22:41 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id A8D7418408AB; Mon, 19 Oct 2020 12:22:40 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 09JCMdBl001863 for ; Mon, 19 Oct 2020 08:22:39 -0400 Received: by smtp.corp.redhat.com (Postfix) id 658836198E; Mon, 19 Oct 2020 12:22:39 +0000 (UTC) Received: from speedmetal.redhat.com (unknown [10.40.208.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id B0B8B6198C for ; Mon, 19 Oct 2020 12:22:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1603110174; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=vaD+Xt98GebdiuZfd7kC8O7UtffqL7+3j1GoeDp0HzY=; b=eSzknh6JnXF2TkZdNq7MGqCq8SQGIV4yMK60hP1W1vo1+yWOMikZe9fiZA32yQlD7wgN30 JZ44v+YH8okszSsW8T8pKABfDoAZ0Ir+6r03oeGcPqTiPyt7E0QJRxUPg9rtugF2E5rkS6 7sm5y7cdwnTXQgGl9bxG2JA12a4zLpI= X-MC-Unique: -t_-iziAO6C_8GIFUBThHg-1 From: Peter Krempa To: libvir-list@redhat.com Subject: [PATCH v2 01/18] virschematest: Rewrite internals to allow increasing XML test coverage Date: Mon, 19 Oct 2020 14:22:10 +0200 Message-Id: <9aa7e6ba73a8511da7d4288566560ae77f743348.1603109876.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" To allow greater variablitity of XML schema validation tests without needlessly reparsing the schema we need to refactor the internals to pass in structs rather than just paths to directory. This allows to directly implement testing of single files and will simplify further additions such as filtering of the list of XML files in a directory. The list of tested paths is directly ported for now and will be improved in follow-up patches. Signed-off-by: Peter Krempa --- tests/virschematest.c | 317 ++++++++++++++++++++++++++---------------- 1 file changed, 199 insertions(+), 118 deletions(-) diff --git a/tests/virschematest.c b/tests/virschematest.c index 17eb2a4b34..e6e176eef3 100644 --- a/tests/virschematest.c +++ b/tests/virschematest.c @@ -30,36 +30,49 @@ VIR_LOG_INIT("tests.schematest"); +struct testSchemaEntry { + const char *dir; + const char *file; +}; + + struct testSchemaData { virXMLValidatorPtr validator; - const char *schema; const char *xml_path; }; static int -testSchemaFile(const void *args) +testSchemaValidateXML(const void *args) { const struct testSchemaData *data =3D args; bool shouldFail =3D virStringHasSuffix(data->xml_path, "-invalid.xml"); - xmlDocPtr xml =3D NULL; - int ret =3D -1; + g_autoptr(xmlDoc) xml =3D NULL; if (!(xml =3D virXMLParseFile(data->xml_path))) return -1; - if (virXMLValidatorValidate(data->validator, xml) < 0) { - if (!shouldFail) - goto cleanup; - } else { - if (shouldFail) - goto cleanup; - } + if ((virXMLValidatorValidate(data->validator, xml) < 0) !=3D shouldFai= l) + return -1; - ret =3D 0; - cleanup: - xmlFreeDoc(xml); - return ret; + return 0; +} + + +static int +testSchemaFile(const char *schema, + virXMLValidatorPtr validator, + const char *path) +{ + g_autofree char *test_name =3D NULL; + struct testSchemaData data =3D { + .validator =3D validator, + .xml_path =3D path, + }; + + test_name =3D g_strdup_printf("Checking %s against %s", path, schema); + + return virTestRun(test_name, testSchemaValidateXML, &data); } @@ -72,9 +85,6 @@ testSchemaDir(const char *schema, struct dirent *ent; int ret =3D 0; int rc; - struct testSchemaData data =3D { - .validator =3D validator, - }; if (virDirOpen(&dir, dir_path) < 0) { virTestPropagateLibvirtError(); @@ -82,7 +92,6 @@ testSchemaDir(const char *schema, } while ((rc =3D virDirRead(dir, &ent, dir_path)) > 0) { - g_autofree char *test_name =3D NULL; g_autofree char *xml_path =3D NULL; if (!virStringHasSuffix(ent->d_name, ".xml")) @@ -92,10 +101,7 @@ testSchemaDir(const char *schema, xml_path =3D g_strdup_printf("%s/%s", dir_path, ent->d_name); - test_name =3D g_strdup_printf("Checking %s against %s", ent->d_nam= e, schema); - - data.xml_path =3D xml_path; - if (virTestRun(test_name, testSchemaFile, &data) < 0) + if (testSchemaFile(schema, validator, xml_path) < 0) ret =3D -1; } @@ -109,122 +115,197 @@ testSchemaDir(const char *schema, } +/** + * testSchemaGrammarReport: + * + * We need to parse the schema regardless since it's necessary also when t= ests + * are skipped using VIR_TEST_RANGE so this function merely reports whethe= r the + * schema was parsed successfully via virTestRun. + */ static int -testSchemaDirs(const char *schema, virXMLValidatorPtr validator, ...) +testSchemaGrammarReport(const void *opaque) { - va_list args; - int ret =3D 0; - const char *dir; + const virXMLValidator *validator =3D opaque; - va_start(args, validator); + if (!validator) + return -1; - while ((dir =3D va_arg(args, char *))) { - g_autofree char *dir_path =3D g_strdup_printf("%s/%s", abs_srcdir,= dir); - if (testSchemaDir(schema, validator, dir_path) < 0) - ret =3D -1; - } + return 0; +} + +static virXMLValidatorPtr +testSchemaGrammarLoad(const char *schema) +{ + g_autofree char *schema_path =3D NULL; + g_autofree char *testname =3D NULL; + virXMLValidatorPtr ret; + + schema_path =3D g_strdup_printf("%s/%s", abs_top_srcdir, schema); + + ret =3D virXMLValidatorInit(schema_path); + + testname =3D g_strdup_printf("test schema grammar file: '%s'", schema); + + ignore_value(virTestRun(testname, testSchemaGrammarReport, ret)); - va_end(args); return ret; } static int -testSchemaGrammar(const void *opaque) +testSchemaEntries(const char *schema, + const struct testSchemaEntry *entries, + size_t nentries) { - struct testSchemaData *data =3D (struct testSchemaData *) opaque; - g_autofree char *schema_path =3D NULL; - - schema_path =3D g_strdup_printf("%s/docs/schemas/%s", abs_top_srcdir, - data->schema); + g_autoptr(virXMLValidator) validator =3D NULL; + size_t i; + int ret =3D 0; - if (!(data->validator =3D virXMLValidatorInit(schema_path))) + if (!(validator =3D testSchemaGrammarLoad(schema))) return -1; - return 0; + for (i =3D 0; i < nentries; i++) { + const struct testSchemaEntry *entry =3D entries + i; + + if (!entry->file =3D=3D !entry->dir) { + VIR_TEST_VERBOSE("\nmust specify exactly one of 'dir' and 'fil= e' for struct testSchemaEntry\n"); + ret =3D -1; + continue; + } + + if (entry->dir) { + g_autofree char *path =3D g_strdup_printf("%s/%s", abs_top_src= dir, entry->dir); + + if (testSchemaDir(schema, validator, path) < 0) + ret =3D -1; + } + + if (entry->file) { + g_autofree char *path =3D g_strdup_printf("%s/%s", abs_top_src= dir, entry->file); + + if (testSchemaFile(schema, validator, path) < 0) + ret =3D -1; + } + } + + return ret; } +static const struct testSchemaEntry schemaCapability[] =3D { + { .dir =3D "tests/capabilityschemadata" }, + { .dir =3D "tests/vircaps2xmldata" }, +}; + +static const struct testSchemaEntry schemaDomain[] =3D { + { .dir =3D "tests/domainschemadata" }, + { .dir =3D "tests/qemuxml2argvdata" }, + { .dir =3D "tests/xmconfigdata" }, + { .dir =3D "tests/qemuxml2xmloutdata" }, + { .dir =3D "tests/lxcxml2xmldata" }, + { .dir =3D "tests/lxcxml2xmloutdata" }, + { .dir =3D "tests/bhyvexml2argvdata" }, + { .dir =3D "tests/bhyvexml2xmloutdata" }, + { .dir =3D "tests/genericxml2xmlindata" }, + { .dir =3D "tests/genericxml2xmloutdata" }, + { .dir =3D "tests/xlconfigdata" }, + { .dir =3D "tests/libxlxml2domconfigdata" }, + { .dir =3D "tests/qemuhotplugtestdomains" }, +}; + +static const struct testSchemaEntry schemaDomainCaps[] =3D { + { .dir =3D "tests/domaincapsdata" }, +}; + +static const struct testSchemaEntry schemaDomainBackup[] =3D { + { .dir =3D "tests/domainbackupxml2xmlin" }, + { .dir =3D "tests/domainbackupxml2xmlout" }, +}; + +static const struct testSchemaEntry schemaDomainCheckpoint[] =3D { + { .dir =3D "tests/qemudomaincheckpointxml2xmlin" }, + { .dir =3D "tests/qemudomaincheckpointxml2xmlout" }, +}; + +static const struct testSchemaEntry schemaDomainSnapshot[] =3D { + { .dir =3D "tests/qemudomainsnapshotxml2xmlin" }, + { .dir =3D "tests/qemudomainsnapshotxml2xmlout" }, +}; + +static const struct testSchemaEntry schemaInterface[] =3D { + { .dir =3D "tests/interfaceschemadata" }, +}; + +static const struct testSchemaEntry schemaNetwork[] =3D { + { .dir =3D "src/network" }, + { .dir =3D "tests/networkxml2xmlin" }, + { .dir =3D "tests/networkxml2xmlout" }, + { .dir =3D "tests/networkxml2confdata" }, +}; + +static const struct testSchemaEntry schemaNetworkport[] =3D { + { .dir =3D "tests/virnetworkportxml2xmldata" }, +}; + +static const struct testSchemaEntry schemaNodedev[] =3D { + { .dir =3D "tests/nodedevschemadata" }, +}; + +static const struct testSchemaEntry schemaNwfilter[] =3D { + { .dir =3D "tests/nwfilterxml2xmlout" }, + { .dir =3D "src/nwfilter" }, +}; + +static const struct testSchemaEntry schemaNwfilterbinding[] =3D { + { .dir =3D "tests/virnwfilterbindingxml2xmldata" }, +}; + +static const struct testSchemaEntry schemaSecret[] =3D { + { .dir =3D "tests/secretxml2xmlin" }, +}; + +static const struct testSchemaEntry schemaStoragepoolcaps[] =3D { + { .dir =3D "tests/storagepoolcapsschemadata" }, +}; + +static const struct testSchemaEntry schemaStoragePool[] =3D { + { .dir =3D "tests/storagepoolxml2xmlin" }, + { .dir =3D "tests/storagepoolxml2xmlout" }, + { .dir =3D "tests/storagepoolschemadata" }, +}; + +static const struct testSchemaEntry schemaStorageVol[] =3D { + { .dir =3D "tests/storagevolxml2xmlin" }, + { .dir =3D "tests/storagevolxml2xmlout" }, + { .dir =3D "tests/storagevolschemadata" }, +}; + + static int mymain(void) { int ret =3D 0; - struct testSchemaData data; - - memset(&data, 0, sizeof(data)); - -#define DO_TEST_DIR(sch, ...) \ - do { \ - data.schema =3D sch; \ - if (virTestRun("test schema grammar file: " sch, \ - testSchemaGrammar, &data) =3D=3D 0) { \ - /* initialize the validator even if the schema test \ - * was skipped because of VIR_TEST_RANGE */ \ - if (!data.validator && testSchemaGrammar(&data) < 0) { \ - ret =3D -1; \ - break; \ - } \ - if (testSchemaDirs(sch, data.validator, __VA_ARGS__, NULL) < 0= ) \ - ret =3D -1; \ - \ - virXMLValidatorFree(data.validator); \ - data.validator =3D NULL; \ - } else { \ - ret =3D -1; \ - } \ - } while (0) - -#define DO_TEST_FILE(sch, xmlfile) \ - do { \ - data.schema =3D sch; \ - data.xml_path =3D abs_srcdir "/" xmlfile; \ - if (virTestRun("test schema grammar file: " sch, \ - testSchemaGrammar, &data) =3D=3D 0) { \ - /* initialize the validator even if the schema test \ - * was skipped because of VIR_TEST_RANGE */ \ - if (!data.validator && testSchemaGrammar(&data) < 0) { \ - ret =3D -1; \ - break; \ - } \ - if (virTestRun("Checking " xmlfile " against " sch, \ - testSchemaFile, &data) < 0) \ - ret =3D -1; \ - \ - virXMLValidatorFree(data.validator); \ - data.validator =3D NULL; \ - } else { \ - ret =3D -1; \ - } \ - } while (0) - - DO_TEST_DIR("capability.rng", "capabilityschemadata", "vircaps2xmldata= "); - DO_TEST_DIR("domain.rng", "domainschemadata", - "qemuxml2argvdata", "xmconfigdata", - "qemuxml2xmloutdata", "lxcxml2xmldata", - "lxcxml2xmloutdata", "bhyvexml2argvdata", - "bhyvexml2xmloutdata", "genericxml2xmlindata", - "genericxml2xmloutdata", "xlconfigdata", "libxlxml2domconf= igdata", - "qemuhotplugtestdomains"); - DO_TEST_DIR("domaincaps.rng", "domaincapsdata"); - DO_TEST_DIR("domainbackup.rng", "domainbackupxml2xmlin", - "domainbackupxml2xmlout"); - DO_TEST_DIR("domaincheckpoint.rng", "qemudomaincheckpointxml2xmlin", - "qemudomaincheckpointxml2xmlout"); - DO_TEST_DIR("domainsnapshot.rng", "qemudomainsnapshotxml2xmlin", - "qemudomainsnapshotxml2xmlout"); - DO_TEST_DIR("interface.rng", "interfaceschemadata"); - DO_TEST_DIR("network.rng", "../src/network", "networkxml2xmlin", - "networkxml2xmlout", "networkxml2confdata"); - DO_TEST_DIR("networkport.rng", "virnetworkportxml2xmldata"); - DO_TEST_DIR("nodedev.rng", "nodedevschemadata"); - DO_TEST_DIR("nwfilter.rng", "nwfilterxml2xmlout", "../src/nwfilter"); - DO_TEST_DIR("nwfilterbinding.rng", "virnwfilterbindingxml2xmldata"); - DO_TEST_DIR("secret.rng", "secretxml2xmlin"); - DO_TEST_DIR("storagepoolcaps.rng", "storagepoolcapsschemadata"); - DO_TEST_DIR("storagepool.rng", "storagepoolxml2xmlin", "storagepoolxml= 2xmlout", - "storagepoolschemadata"); - DO_TEST_DIR("storagevol.rng", "storagevolxml2xmlin", "storagevolxml2xm= lout", - "storagevolschemadata"); + +#define DO_TEST(sch, ent) \ + if (testSchemaEntries((sch), (ent), G_N_ELEMENTS(ent)) < 0) \ + ret =3D -1; + + DO_TEST("docs/schemas/capability.rng", schemaCapability); + DO_TEST("docs/schemas/domain.rng", schemaDomain); + DO_TEST("docs/schemas/domaincaps.rng", schemaDomainCaps); + DO_TEST("docs/schemas/domainbackup.rng", schemaDomainBackup); + DO_TEST("docs/schemas/domaincheckpoint.rng", schemaDomainCheckpoint); + DO_TEST("docs/schemas/domainsnapshot.rng", schemaDomainSnapshot); + DO_TEST("docs/schemas/interface.rng", schemaInterface); + DO_TEST("docs/schemas/network.rng", schemaNetwork); + DO_TEST("docs/schemas/networkport.rng", schemaNetworkport); + DO_TEST("docs/schemas/nodedev.rng", schemaNodedev); + DO_TEST("docs/schemas/nwfilter.rng", schemaNwfilter); + DO_TEST("docs/schemas/nwfilterbinding.rng", schemaNwfilterbinding); + DO_TEST("docs/schemas/secret.rng", schemaSecret); + DO_TEST("docs/schemas/storagepoolcaps.rng", schemaStoragepoolcaps); + DO_TEST("docs/schemas/storagepool.rng", schemaStoragePool); + DO_TEST("docs/schemas/storagevol.rng", schemaStorageVol); return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; } --=20 2.26.2