[PATCH 4/4] qemu*xml2*test: Cache capabilities between tests

Jonathon Jongsma jjongsma at redhat.com
Fri Feb 19 16:49:11 UTC 2021


On Fri, 19 Feb 2021 16:53:21 +0100
Peter Krempa <pkrempa at redhat.com> wrote:

> Invoking the XML parser every time is quite expensive. Since we have a
> deep copy function for 'virQEMUCapsPtr' object, we can cache the
> parsed results lazily.
> 
> This brings significant speedup to qemuxml2argvtest:
> 
> real	0m2.234s
> user	0m2.140s
> sys	0m0.089s
> 
> vs.
> 
> real	0m1.161s
> user	0m1.087s
> sys	0m0.072s
> 
> qemuxml2xmltest benefits too:
> 
> real	0m0.879s
> user	0m0.801s
> sys	0m0.071s
> 
> vs.
> 
> real	0m0.466s
> user	0m0.424s
> sys	0m0.040s
> 
> Signed-off-by: Peter Krempa <pkrempa at redhat.com>
> ---
>  tests/qemustatusxml2xmltest.c |  3 ++-
>  tests/qemuxml2argvtest.c      |  3 ++-
>  tests/qemuxml2xmltest.c       |  3 ++-
>  tests/testutilsqemu.c         | 18 +++++++++++++++---
>  tests/testutilsqemu.h         |  1 +
>  5 files changed, 22 insertions(+), 6 deletions(-)
> 
> diff --git a/tests/qemustatusxml2xmltest.c
> b/tests/qemustatusxml2xmltest.c index 67a070c986..2b2c409cba 100644
> --- a/tests/qemustatusxml2xmltest.c
> +++ b/tests/qemustatusxml2xmltest.c
> @@ -73,6 +73,7 @@ mymain(void)
>      g_autofree char *fakerootdir = NULL;
>      g_autoptr(virQEMUDriverConfig) cfg = NULL;
>      g_autoptr(GHashTable) capslatest = NULL;
> +    g_autoptr(GHashTable) capscache =
> virHashNew(virObjectFreeHashData); g_autoptr(virConnect) conn = NULL;
> 
>      capslatest = testQemuGetLatestCaps();
> @@ -109,7 +110,7 @@ mymain(void)
>          static struct testQemuInfo info = { \
>              .name = _name, \
>          }; \
> -        if (testQemuInfoSetArgs(&info, capslatest, \
> +        if (testQemuInfoSetArgs(&info, capscache, capslatest, \
>                                  ARG_QEMU_CAPS, QEMU_CAPS_LAST, \
>                                  ARG_END) < 0 || \
>              qemuTestCapsCacheInsert(driver.qemuCapsCache,
> info.qemuCaps) < 0) { \ diff --git a/tests/qemuxml2argvtest.c
> b/tests/qemuxml2argvtest.c index 2d538bee9c..d6d707cd24 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -789,6 +789,7 @@ mymain(void)
>      g_autofree char *fakerootdir = NULL;
>      g_autoptr(GHashTable) capslatest = NULL;
>      g_autoptr(GHashTable) qapiSchemaCache =
> virHashNew((GDestroyNotify) virHashFree);
> +    g_autoptr(GHashTable) capscache =
> virHashNew(virObjectFreeHashData);
> 
>      fakerootdir = g_strdup(FAKEROOTDIRTEMPLATE);
> 
> @@ -883,7 +884,7 @@ mymain(void)
>              .name = _name, \
>          }; \
>          info.qapiSchemaCache = qapiSchemaCache; \
> -        if (testQemuInfoSetArgs(&info, capslatest, \
> +        if (testQemuInfoSetArgs(&info, capscache, capslatest, \
>                                  __VA_ARGS__, ARG_END) < 0) \
>              return EXIT_FAILURE; \
>          testInfoSetPaths(&info, _suffix); \
> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
> index 5cd945f28f..01ac5886f2 100644
> --- a/tests/qemuxml2xmltest.c
> +++ b/tests/qemuxml2xmltest.c
> @@ -85,6 +85,7 @@ mymain(void)
>      g_autofree char *fakerootdir = NULL;
>      g_autoptr(virQEMUDriverConfig) cfg = NULL;
>      g_autoptr(GHashTable) capslatest = NULL;
> +    g_autoptr(GHashTable) capscache =
> virHashNew(virObjectFreeHashData); g_autoptr(virConnect) conn = NULL;
> 
>      capslatest = testQemuGetLatestCaps();
> @@ -130,7 +131,7 @@ mymain(void)
>          static struct testQemuInfo info = { \
>              .name = _name, \
>          }; \
> -        if (testQemuInfoSetArgs(&info, capslatest, \
> +        if (testQemuInfoSetArgs(&info, capscache, capslatest, \
>                                  __VA_ARGS__, \
>                                  ARG_END) < 0 || \
>              qemuTestCapsCacheInsert(driver.qemuCapsCache,
> info.qemuCaps) < 0) { \ diff --git a/tests/testutilsqemu.c
> b/tests/testutilsqemu.c index a96c9d487a..1dcf5caf6a 100644
> --- a/tests/testutilsqemu.c
> +++ b/tests/testutilsqemu.c
> @@ -681,6 +681,7 @@ testQemuCapsIterate(const char *suffix,
> 
>  int
>  testQemuInfoSetArgs(struct testQemuInfo *info,
> +                    GHashTable *capscache,
>                      GHashTable *capslatest, ...)
>  {
>      va_list argptr;
> @@ -773,6 +774,7 @@ testQemuInfoSetArgs(struct testQemuInfo *info,
> 
>      if (!qemuCaps && capsarch && capsver) {
>          bool stripmachinealiases = false;
> +        virQEMUCapsPtr cachecaps = NULL;
> 
>          info->arch = virArchFromString(capsarch);
> 
> @@ -784,11 +786,21 @@ testQemuInfoSetArgs(struct testQemuInfo *info,
>                                         TEST_QEMU_CAPS_PATH, capsver,
> capsarch); }
> 
> -        if (!(qemuCaps = qemuTestParseCapabilitiesArch(info->arch,
> capsfile)))
> +        if (!g_hash_table_lookup_extended(capscache, capsfile, NULL,
> (void **) &cachecaps)) {
> +            if (!(qemuCaps =
> qemuTestParseCapabilitiesArch(info->arch, capsfile)))
> +                goto cleanup;
> +
> +            if (stripmachinealiases)
> +                virQEMUCapsStripMachineAliases(qemuCaps);
> +
> +            cachecaps = qemuCaps;
> +
> +            g_hash_table_insert(capscache, g_strdup(capsfile),
> g_steal_pointer(&qemuCaps));
> +        }
> +
> +        if (!(qemuCaps = virQEMUCapsNewCopy(cachecaps)))
>              goto cleanup;
> 
> -        if (stripmachinealiases)
> -            virQEMUCapsStripMachineAliases(qemuCaps);
>          info->flags |= FLAG_REAL_CAPS;
> 
>          /* provide path to the replies file for schema testing */
> diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h
> index 86ba69e96b..e1b386f234 100644
> --- a/tests/testutilsqemu.h
> +++ b/tests/testutilsqemu.h
> @@ -110,6 +110,7 @@ int testQemuCapsIterate(const char *suffix,
>                          void *opaque);
> 
>  int testQemuInfoSetArgs(struct testQemuInfo *info,
> +                        GHashTable *capscache,
>                          GHashTable *capslatest, ...);
>  void testQemuInfoClear(struct testQemuInfo *info);
> 


Series looks fine to me. One thing I find a little bit confusing in
this patch is that you have both 'cachecaps' and 'capscache' in the same
function. I think just renaming 'cachecaps' to 'caps' (or even
'cachedcaps' with a d) would make things slightly less confusing.

Reviewed-by: Jonathon Jongsma <jjongsma at redhat.com>




More information about the libvir-list mailing list