[libvirt] [PATCH REPOST] Introduce new OOM testing support

Michal Privoznik mprivozn at redhat.com
Tue Feb 18 10:48:25 UTC 2014


On 13.02.2014 11:14, Daniel P. Berrange wrote:
> The previous OOM testing support would re-run the entire "main"
> method each iteration, failing a different malloc each time.
> When a test suite has 'n' allocations, the number of repeats
> requires is  (n * (n + 1) ) / 2.  This gets very large, very
> quickly.
> 
> This new OOM testing support instead integrates at the
> virtTestRun level, so each individual test case gets repeated,
> instead of the entire test suite. This means the values of
> 'n' are orders of magnitude smaller.
> 
> The simple usage is
> 
>     $ VIR_TEST_OOM=1 ./qemuxml2argvtest
>     ...
>     29) QEMU XML-2-ARGV clock-utc                                         ... OK
>         Test OOM for nalloc=36 .................................... OK
>     30) QEMU XML-2-ARGV clock-localtime                                   ... OK
>         Test OOM for nalloc=36 .................................... OK
>     31) QEMU XML-2-ARGV clock-france                                      ... OK
>         Test OOM for nalloc=38 ...................................... OK
>     ...
> 
> the second lines reports how many mallocs have to be failed, and thus
> how many repeats of the test will be run.
> 
> If it crashes, then running under valgrind will often show the problem
> 
>    $ VIR_TEST_OOM=1 ../run valgrind ./qemuxml2argvtest
> 
> When debugging problems it is also helpful to select an individual
> test case
> 
>    $ VIR_TEST_RANGE=30 VIR_TEST_OOM=1 ../run valgrind ./qemuxml2argvtest
> 
> When things get really tricky, it is possible to request that just
> specific allocs are failed. eg to fail allocs 5 -> 12, use
> 
>    $ VIR_TEST_RANGE=30 VIR_TEST_OOM=1:5-12 ../run valgrind ./qemuxml2argvtest
> 
> In the worse case, you might want to know the stack trace of the
> alloc which was failed then VIR_TEST_OOM_TRACE can be set. If it
> is set to 1 then it will only print if it thinks a mistake happened.
> This is often not reliable, so setting it to 2 will make it print
> the stack trace for every alloc that is failed.
> 
>    $ VIR_TEST_OOM_TRACE=2 VIR_TEST_RANGE=30 VIR_TEST_OOM=1:5-5 ../run valgrind ./qemuxml2argvtest
>    30) QEMU XML-2-ARGV clock-localtime                                   ... OK
>        Test OOM for nalloc=36 !virAllocN
>    /home/berrange/src/virt/libvirt/src/util/viralloc.c:180
>    virHashCreateFull
>    /home/berrange/src/virt/libvirt/src/util/virhash.c:144
>    virDomainDefParseXML
>    /home/berrange/src/virt/libvirt/src/conf/domain_conf.c:11745
>    virDomainDefParseNode
>    /home/berrange/src/virt/libvirt/src/conf/domain_conf.c:12646
>    virDomainDefParse
>    /home/berrange/src/virt/libvirt/src/conf/domain_conf.c:12590
>    testCompareXMLToArgvFiles
>    /home/berrange/src/virt/libvirt/tests/qemuxml2argvtest.c:106
>    virtTestRun
>    /home/berrange/src/virt/libvirt/tests/testutils.c:250
>    mymain
>    /home/berrange/src/virt/libvirt/tests/qemuxml2argvtest.c:418 (discriminator 2)
>    virtTestMain
>    /home/berrange/src/virt/libvirt/tests/testutils.c:750
>    ??
>    ??:0
>    _start
>    ??:?
>     FAILED
> 
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
>   cfg.mk                            |   2 +-
>   docs/internals/oomtesting.html.in | 213 ++++++++++++++++++++++++++++++++++++++
>   docs/sitemap.html.in              |   4 +
>   tests/qemuargv2xmltest.c          |  14 +--
>   tests/qemuxml2argvtest.c          |  12 ++-
>   tests/qemuxmlnstest.c             |  18 ++--
>   tests/testutils.c                 | 195 +++++++++++++++++++++++++++++++++-
>   tests/testutils.h                 |   2 +
>   8 files changed, 438 insertions(+), 22 deletions(-)
>   create mode 100644 docs/internals/oomtesting.html.in
> 

> diff --git a/tests/testutils.c b/tests/testutils.c
> index 32fe374..52d07eb 100644
> --- a/tests/testutils.c
> +++ b/tests/testutils.c
> @@ -47,6 +47,13 @@
>   #include "virprocess.h"
>   #include "virstring.h"
>   
> +#ifdef TEST_OOM
> +# ifdef TEST_OOM_TRACE
> +#  include <dlfcn.h>
> +#  include <execinfo.h>
> +# endif
> +#endif
> +
>   #ifdef HAVE_PATHS_H
>   # include <paths.h>
>   #endif
> @@ -64,12 +71,37 @@ static unsigned int testDebug = -1;
>   static unsigned int testVerbose = -1;
>   static unsigned int testExpensive = -1;
>   
> +#ifdef TEST_OOM
> +static unsigned int testOOM = 0;
> +static unsigned int testOOMStart = -1;
> +static unsigned int testOOMEnd = -1;
> +static unsigned int testOOMTrace = 0;
> +# ifdef TEST_OOM_TRACE
> +void *testAllocStack[30];
> +int ntestAllocStack;
> +# endif
> +#endif
> +static bool testOOMActive = false;
> +
>   static size_t testCounter = 0;
>   static size_t testStart = 0;
>   static size_t testEnd = 0;
>   
>   char *progname;
>   
> +bool virtTestOOMActive(void)
> +{
> +    return testOOMActive;
> +}
> +
> +#ifdef TEST_OOM_TRACE
> +static void virTestAllocHook(int nalloc ATTRIBUTE_UNUSED,
> +                             void *opaque ATTRIBUTE_UNUSED)
> +{
> +    ntestAllocStack = backtrace(testAllocStack, ARRAY_CARDINALITY(testAllocStack));
> +}
> +#endif
> +
>   void virtTestResult(const char *name, int ret, const char *msg, ...)
>   {
>       va_list vargs;
> @@ -108,6 +140,35 @@ void virtTestResult(const char *name, int ret, const char *msg, ...)
>       va_end(vargs);
>   }
>   
> +#ifdef TEST_OOM_TRACE
> +static void
> +virTestShowTrace(void)
> +{
> +    size_t j;
> +    for (j = 2; j < ntestAllocStack; j++) {
> +        Dl_info info;
> +        char *cmd;
> +
> +        dladdr(testAllocStack[j], &info);
> +        if (info.dli_fname &&
> +            strstr(info.dli_fname, ".so")) {
> +            if (virAsprintf(&cmd, "addr2line -f -e %s %p",
> +                            info.dli_fname,
> +                            ((void*)((unsigned long long)testAllocStack[j]
> +                                     - (unsigned long long)info.dli_fbase))) < 0)
> +                continue;
> +        } else {
> +            if (virAsprintf(&cmd, "addr2line -f -e %s %p",
> +                            (char*)(info.dli_fname ? info.dli_fname : "<unknown>"),
> +                            testAllocStack[j]) < 0)
> +                continue;
> +        }

For some reason I'm seeing an error here:

tests $ VIR_TEST_OOM_TRACE=2 VIR_TEST_OOM=1 ./qemuxml2argvtest
<snip/>
</capabilities>
 1) QEMU XML-2-ARGV minimal                                           ... OK
    Test OOM for nalloc=42 !sh: addr2line: command not found
sh: addr2line: command not found
sh: addr2line: command not found
sh: addr2line: command not found

But I DO have addr2line:

tests $ which addr2line
/usr/bin/addr2line




ACK with this squashed in:

diff --git a/configure.ac b/configure.ac
index 0d505d3..15cd190 100644
--- a/configure.ac
+++ b/configure.ac
@@ -422,6 +422,8 @@ AC_PATH_PROG([OVSVSCTL], [ovs-vsctl], [ovs-vsctl],
        [/sbin:/usr/sbin:/usr/local/sbin:$PATH])
 AC_PATH_PROG([SCRUB], [scrub], [scrub],
        [/sbin:/usr/sbin:/usr/local/sbin:$PATH])
+AC_PATH_PROG([ADDR2LINE], [addr2line], [addr2line],
+       [/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:$PATH])
 
 AC_DEFINE_UNQUOTED([DMIDECODE],["$DMIDECODE"],
         [Location or name of the dmidecode program])
@@ -452,6 +454,8 @@ if test -n "$RMMOD"; then
 fi
 AC_DEFINE_UNQUOTED([SCRUB],["$SCRUB"],
         [Location or name of the scrub program (for wiping algorithms)])
+AC_DEFINE_UNQUOTED([ADDR2LINE],["$ADDR2LINE"],
+        [Location of addr2line program])
 
 dnl Specific dir for HTML output ?
 AC_ARG_WITH([html-dir], [AS_HELP_STRING([--with-html-dir=path],
diff --git a/tests/testutils.c b/tests/testutils.c
index 52d07eb..3f42b13 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -152,13 +152,13 @@ virTestShowTrace(void)
         dladdr(testAllocStack[j], &info);
         if (info.dli_fname &&
             strstr(info.dli_fname, ".so")) {
-            if (virAsprintf(&cmd, "addr2line -f -e %s %p",
+            if (virAsprintf(&cmd, ADDR2LINE " -f -e %s %p",
                             info.dli_fname,
                             ((void*)((unsigned long long)testAllocStack[j]
                                      - (unsigned long long)info.dli_fbase))) < 0)
                 continue;
         } else {
-            if (virAsprintf(&cmd, "addr2line -f -e %s %p",
+            if (virAsprintf(&cmd, ADDR2LINE " -f -e %s %p",
                             (char*)(info.dli_fname ? info.dli_fname : "<unknown>"),
                             testAllocStack[j]) < 0)
                 continue;

Michal




More information about the libvir-list mailing list