testutils.c 21.4 KB
Newer Older
K
Karel Zak 已提交
1
/*
2
 * testutils.c: basic test utils
K
Karel Zak 已提交
3
 *
4
 * Copyright (C) 2005-2013 Red Hat, Inc.
K
Karel Zak 已提交
5
 *
O
Osier Yang 已提交
6 7 8 9 10 11 12 13 14 15 16
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
K
Karel Zak 已提交
19 20 21 22
 *
 * Karel Zak <kzak@redhat.com>
 */

23
#include <config.h>
24

K
Karel Zak 已提交
25 26 27
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
28 29
#include <sys/types.h>
#include <sys/stat.h>
30 31
#include <sys/wait.h>
#include <regex.h>
32
#include <unistd.h>
33
#include <string.h>
34 35
#include <fcntl.h>
#include <limits.h>
K
Karel Zak 已提交
36
#include "testutils.h"
37
#include "internal.h"
38
#include "viralloc.h"
39
#include "virutil.h"
40
#include "virthread.h"
41
#include "virerror.h"
42
#include "virbuffer.h"
43
#include "virlog.h"
44
#include "vircommand.h"
45
#include "virrandom.h"
E
Eric Blake 已提交
46
#include "dirname.h"
47
#include "virprocess.h"
48
#include "virstring.h"
49 50

#if TEST_OOM_TRACE
51
# include <execinfo.h>
52
#endif
K
Karel Zak 已提交
53

54
#ifdef HAVE_PATHS_H
55
# include <paths.h>
56 57
#endif

58 59
#define VIR_FROM_THIS VIR_FROM_NONE

K
Karel Zak 已提交
60
#define GETTIMEOFDAY(T) gettimeofday(T, NULL)
61
#define DIFF_MSEC(T, U)                                 \
62
    ((((int) ((T)->tv_sec - (U)->tv_sec)) * 1000000.0 + \
63
      ((int) ((T)->tv_usec - (U)->tv_usec))) / 1000.0)
K
Karel Zak 已提交
64

E
Eric Blake 已提交
65
#include "virfile.h"
66

67
static unsigned int testDebug = -1;
68
static unsigned int testVerbose = -1;
69

70
static unsigned int testOOM = 0;
71 72 73
static size_t testCounter = 0;
static size_t testStart = 0;
static size_t testEnd = 0;
74

E
Eric Blake 已提交
75 76 77
char *progname;
char *abs_srcdir;

K
Karel Zak 已提交
78 79 80
double
virtTestCountAverage(double *items, int nitems)
{
81
    long double sum = 0;
82
    size_t i;
K
Karel Zak 已提交
83

84 85
    for (i=1; i < nitems; i++)
        sum += items[i];
K
Karel Zak 已提交
86

87
    return (double) (sum / nitems);
K
Karel Zak 已提交
88 89
}

90

91 92 93 94 95
void virtTestResult(const char *name, int ret, const char *msg, ...)
{
    va_list vargs;
    va_start(vargs, msg);

96 97 98
    if (testCounter == 0 && !virTestGetVerbose())
        fprintf(stderr, "      ");

99 100
    testCounter++;
    if (virTestGetVerbose()) {
101
        fprintf(stderr, "%3zu) %-60s ", testCounter, name);
102 103 104 105 106
        if (ret == 0)
            fprintf(stderr, "OK\n");
        else {
            fprintf(stderr, "FAILED\n");
            if (msg) {
107
                char *str;
108
                if (virVasprintfQuiet(&str, msg, vargs) == 0) {
109 110 111
                    fprintf(stderr, "%s", str);
                    VIR_FREE(str);
                }
112 113 114 115 116
            }
        }
    } else {
        if (testCounter != 1 &&
            !((testCounter-1) % 40)) {
117
            fprintf(stderr, " %-3zu\n", (testCounter-1));
118 119 120 121 122 123 124 125 126 127 128
            fprintf(stderr, "      ");
        }
        if (ret == 0)
            fprintf(stderr, ".");
        else
            fprintf(stderr, "!");
    }

    va_end(vargs);
}

129
/*
K
Karel Zak 已提交
130
 * Runs test and count average time (if the nloops is grater than 1)
131 132
 *
 * returns: -1 = error, 0 = success
K
Karel Zak 已提交
133 134
 */
int
135
virtTestRun(const char *title, int nloops, int (*body)(const void *data), const void *data)
K
Karel Zak 已提交
136
{
137 138
    int ret = 0;
    size_t i;
139
    double *ts = NULL;
140

141 142 143
    if (testCounter == 0 && !virTestGetVerbose())
        fprintf(stderr, "      ");

144
    testCounter++;
145

146 147 148 149 150 151 152

    /* Skip tests if out of range */
    if ((testStart != 0) &&
        (testCounter < testStart ||
         testCounter > testEnd))
        return 0;

153
    if (testOOM < 2) {
154
        if (virTestGetVerbose())
155
            fprintf(stderr, "%2zu) %-65s ... ", testCounter, title);
156
    }
157

158
    if (nloops > 1 && (VIR_ALLOC_N(ts, nloops) < 0))
159 160 161 162 163 164 165
        return -1;

    for (i=0; i < nloops; i++) {
        struct timeval before, after;

        if (ts)
            GETTIMEOFDAY(&before);
166

167
        virResetLastError();
168
        ret = body(data);
169
        virErrorPtr err = virGetLastError();
170 171 172 173 174 175 176 177 178 179
        if (err) {
            if (virTestGetVerbose() || virTestGetDebug())
                virDispatchError(NULL);
        }

        if (ret != 0) {
            break;
        }

        if (ts) {
180 181 182 183
            GETTIMEOFDAY(&after);
            ts[i] = DIFF_MSEC(&after, &before);
        }
    }
184
    if (testOOM < 2) {
185 186 187 188 189 190
        if (virTestGetVerbose()) {
            if (ret == 0 && ts)
                fprintf(stderr, "OK     [%.5f ms]\n",
                        virtTestCountAverage(ts, nloops));
            else if (ret == 0)
                fprintf(stderr, "OK\n");
191 192
            else if (ret == EXIT_AM_SKIP)
                fprintf(stderr, "SKIP\n");
193 194 195 196 197
            else
                fprintf(stderr, "FAILED\n");
        } else {
            if (testCounter != 1 &&
                !((testCounter-1) % 40)) {
198
                fprintf(stderr, " %-3zu\n", (testCounter-1));
199 200 201 202
                fprintf(stderr, "      ");
            }
            if (ret == 0)
                fprintf(stderr, ".");
203 204
            else if (ret == EXIT_AM_SKIP)
                fprintf(stderr, "_");
205 206 207
            else
                fprintf(stderr, "!");
        }
208
    }
209

210
    VIR_FREE(ts);
211
    return ret;
K
Karel Zak 已提交
212
}
213

214 215 216 217 218 219
/* Allocate BUF to the size of FILE. Read FILE into buffer BUF.
   Upon any failure, diagnose it and return -1, but don't bother trying
   to preserve errno. Otherwise, return the number of bytes copied into BUF. */
int
virtTestLoadFile(const char *file, char **buf)
{
220
    FILE *fp = fopen(file, "r");
221
    struct stat st;
222 223
    char *tmp;
    int len, tmplen, buflen;
224

225
    if (!fp) {
226
        fprintf(stderr, "%s: failed to open: %s\n", file, strerror(errno));
227
        return -1;
228
    }
229 230

    if (fstat(fileno(fp), &st) < 0) {
231
        fprintf(stderr, "%s: failed to fstat: %s\n", file, strerror(errno));
232
        VIR_FORCE_FCLOSE(fp);
233 234 235
        return -1;
    }

236 237 238
    tmplen = buflen = st.st_size + 1;

    if (VIR_ALLOC_N(*buf, buflen) < 0) {
239
        fprintf(stderr, "%s: larger than available memory (> %d)\n", file, buflen);
240
        VIR_FORCE_FCLOSE(fp);
241 242 243
        return -1;
    }

244
    tmp = *buf;
245
    (*buf)[0] = '\0';
246
    if (st.st_size) {
247 248 249
        /* read the file line by line */
        while (fgets(tmp, tmplen, fp) != NULL) {
            len = strlen(tmp);
250 251 252
            /* stop on an empty line */
            if (len == 0)
                break;
253 254 255 256 257 258 259 260 261 262
            /* remove trailing backslash-newline pair */
            if (len >= 2 && tmp[len-2] == '\\' && tmp[len-1] == '\n') {
                len -= 2;
                tmp[len] = '\0';
            }
            /* advance the temporary buffer pointer */
            tmp += len;
            tmplen -= len;
        }
        if (ferror(fp)) {
263
            fprintf(stderr, "%s: read failed: %s\n", file, strerror(errno));
264
            VIR_FORCE_FCLOSE(fp);
265
            VIR_FREE(*buf);
266 267
            return -1;
        }
268 269
    }

270
    VIR_FORCE_FCLOSE(fp);
271
    return strlen(*buf);
272 273
}

A
Atsushi SAKAI 已提交
274
#ifndef WIN32
275 276
static
void virtTestCaptureProgramExecChild(const char *const argv[],
277
                                     int pipefd) {
278
    size_t i;
279 280 281 282
    int open_max;
    int stdinfd = -1;
    const char *const env[] = {
        "LANG=C",
283
# if WITH_DRIVER_MODULES
284
        "LIBVIRT_DRIVER_DIR=" TEST_DRIVER_DIR,
285
# endif
286 287 288
        NULL
    };

289
    if ((stdinfd = open("/dev/null", O_RDONLY)) < 0)
290 291
        goto cleanup;

292
    open_max = sysconf(_SC_OPEN_MAX);
J
John Ferlan 已提交
293 294 295
    if (open_max < 0)
        goto cleanup;

296 297
    for (i = 0; i < open_max; i++) {
        if (i != stdinfd &&
298
            i != pipefd) {
299 300
            int tmpfd;
            tmpfd = i;
301 302
            VIR_FORCE_CLOSE(tmpfd);
        }
303 304 305 306 307 308
    }

    if (dup2(stdinfd, STDIN_FILENO) != STDIN_FILENO)
        goto cleanup;
    if (dup2(pipefd, STDOUT_FILENO) != STDOUT_FILENO)
        goto cleanup;
309
    if (dup2(pipefd, STDERR_FILENO) != STDERR_FILENO)
310 311 312 313
        goto cleanup;

    /* SUS is crazy here, hence the cast */
    execve(argv[0], (char *const*)argv, (char *const*)env);
314 315

 cleanup:
316
    VIR_FORCE_CLOSE(stdinfd);
317 318
}

319 320 321
int
virtTestCaptureProgramOutput(const char *const argv[], char **buf, int maxlen)
{
322
    int pipefd[2];
323
    int len;
324 325 326 327

    if (pipe(pipefd) < 0)
        return -1;

328
    pid_t pid = fork();
329
    switch (pid) {
330
    case 0:
331
        VIR_FORCE_CLOSE(pipefd[0]);
332 333
        virtTestCaptureProgramExecChild(argv, pipefd[1]);

334
        VIR_FORCE_CLOSE(pipefd[1]);
335
        _exit(EXIT_FAILURE);
336

337 338
    case -1:
        return -1;
339

340
    default:
341 342 343
        VIR_FORCE_CLOSE(pipefd[1]);
        len = virFileReadLimFD(pipefd[0], maxlen, buf);
        VIR_FORCE_CLOSE(pipefd[0]);
344
        if (virProcessWait(pid, NULL) < 0)
E
Eric Blake 已提交
345
            return -1;
346

347
        return len;
348
    }
349
}
350
#else /* !WIN32 */
351 352 353 354 355
int
virtTestCaptureProgramOutput(const char *const argv[] ATTRIBUTE_UNUSED,
                             char **buf ATTRIBUTE_UNUSED,
                             int maxlen ATTRIBUTE_UNUSED)
{
356 357
    return -1;
}
A
Atsushi SAKAI 已提交
358
#endif /* !WIN32 */
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377


/**
 * @param stream: output stream write to differences to
 * @param expect: expected output text
 * @param actual: actual output text
 *
 * Display expected and actual output text, trimmed to
 * first and last characters at which differences occur
 */
int virtTestDifference(FILE *stream,
                       const char *expect,
                       const char *actual)
{
    const char *expectStart = expect;
    const char *expectEnd = expect + (strlen(expect)-1);
    const char *actualStart = actual;
    const char *actualEnd = actual + (strlen(actual)-1);

378
    if (!virTestGetDebug())
379 380
        return 0;

381
    if (virTestGetDebug() < 2) {
382 383 384 385 386 387
        /* Skip to first character where they differ */
        while (*expectStart && *actualStart &&
               *actualStart == *expectStart) {
            actualStart++;
            expectStart++;
        }
388

389 390 391 392 393 394 395
        /* Work backwards to last character where they differ */
        while (actualEnd > actualStart &&
               expectEnd > expectStart &&
               *actualEnd == *expectEnd) {
            actualEnd--;
            expectEnd--;
        }
396 397 398
    }

    /* Show the trimmed differences */
E
Eric Blake 已提交
399
    fprintf(stream, "\nOffset %d\nExpect [", (int) (expectStart - expect));
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
    if ((expectEnd - expectStart + 1) &&
        fwrite(expectStart, (expectEnd-expectStart+1), 1, stream) != 1)
        return -1;
    fprintf(stream, "]\n");
    fprintf(stream, "Actual [");
    if ((actualEnd - actualStart + 1) &&
        fwrite(actualStart, (actualEnd-actualStart+1), 1, stream) != 1)
        return -1;
    fprintf(stream, "]\n");

    /* Pad to line up with test name ... in virTestRun */
    fprintf(stream, "                                                                      ... ");

    return 0;
}
415

416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
/**
 * @param stream: output stream write to differences to
 * @param expect: expected output text
 * @param actual: actual output text
 *
 * Display expected and actual output text, trimmed to
 * first and last characters at which differences occur
 */
int virtTestDifferenceBin(FILE *stream,
                          const char *expect,
                          const char *actual,
                          size_t length)
{
    size_t start = 0, end = length;
    ssize_t i;

    if (!virTestGetDebug())
        return 0;

    if (virTestGetDebug() < 2) {
        /* Skip to first character where they differ */
437
        for (i = 0; i < length; i++) {
438 439 440 441 442 443 444
            if (expect[i] != actual[i]) {
                start = i;
                break;
            }
        }

        /* Work backwards to last character where they differ */
445
        for (i = (length -1); i >= 0; i--) {
446 447 448 449 450 451
            if (expect[i] != actual[i]) {
                end = i;
                break;
            }
        }
    }
E
Eric Blake 已提交
452
    /* Round to nearest boundary of 4, except that last word can be short */
453 454 455 456 457 458 459
    start -= (start % 4);
    end += 4 - (end % 4);
    if (end >= length)
        end = length - 1;

    /* Show the trimmed differences */
    fprintf(stream, "\nExpect [ Region %d-%d", (int)start, (int)end);
460
    for (i = start; i < end; i++) {
461 462 463 464 465 466
        if ((i % 4) == 0)
            fprintf(stream, "\n    ");
        fprintf(stream, "0x%02x, ", ((int)expect[i])&0xff);
    }
    fprintf(stream, "]\n");
    fprintf(stream, "Actual [ Region %d-%d", (int)start, (int)end);
467
    for (i = start; i < end; i++) {
468 469 470 471 472 473 474 475 476 477 478 479
        if ((i % 4) == 0)
            fprintf(stream, "\n    ");
        fprintf(stream, "0x%02x, ", ((int)actual[i])&0xff);
    }
    fprintf(stream, "]\n");

    /* Pad to line up with test name ... in virTestRun */
    fprintf(stream, "                                                                      ... ");

    return 0;
}

480
#if TEST_OOM
481 482 483 484
static void
virtTestErrorFuncQuiet(void *data ATTRIBUTE_UNUSED,
                       virErrorPtr err ATTRIBUTE_UNUSED)
{ }
485
#endif
486

487 488 489 490 491 492
struct virtTestLogData {
    virBuffer buf;
};

static struct virtTestLogData testLog = { VIR_BUFFER_INITIALIZER };

493
static void
494
virtTestLogOutput(virLogSource source ATTRIBUTE_UNUSED,
495
                  virLogPriority priority ATTRIBUTE_UNUSED,
496 497
                  const char *filename ATTRIBUTE_UNUSED,
                  int lineno ATTRIBUTE_UNUSED,
498
                  const char *funcname ATTRIBUTE_UNUSED,
499
                  const char *timestamp,
M
Miloslav Trmač 已提交
500
                  virLogMetadataPtr metadata ATTRIBUTE_UNUSED,
501
                  unsigned int flags,
502
                  const char *rawstr ATTRIBUTE_UNUSED,
503 504
                  const char *str,
                  void *data)
505 506
{
    struct virtTestLogData *log = data;
507
    virCheckFlags(VIR_LOG_STACK_TRACE,);
508
    virBufferAsprintf(&log->buf, "%s: %s", timestamp, str);
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
}

static void
virtTestLogClose(void *data)
{
    struct virtTestLogData *log = data;

    virBufferFreeAndReset(&log->buf);
}

/* Return a malloc'd string (possibly with strlen of 0) of all data
 * logged since the last call to this function, or NULL on failure.  */
char *
virtTestLogContentAndReset(void)
{
    char *ret;

    if (virBufferError(&testLog.buf))
        return NULL;
    ret = virBufferContentAndReset(&testLog.buf);
529 530 531
    if (!ret)
        ignore_value(VIR_STRDUP(ret, ""));
    return ret;
532 533
}

534
#if TEST_OOM_TRACE
535
static void
536
virtTestErrorHook(int n, void *data ATTRIBUTE_UNUSED)
537 538 539
{
    void *trace[30];
    int ntrace = ARRAY_CARDINALITY(trace);
540
    size_t i;
541 542 543 544 545
    char **symbols = NULL;

    ntrace = backtrace(trace, ntrace);
    symbols = backtrace_symbols(trace, ntrace);
    if (symbols) {
546
        fprintf(stderr, "Failing allocation %d at:\n", n);
547
        for (i = 0; i < ntrace; i++) {
548 549 550
            if (symbols[i])
                fprintf(stderr, "  TRACE:  %s\n", symbols[i]);
        }
551
        VIR_FREE(symbols);
552 553
    }
}
554
#endif
555

556 557 558 559
static unsigned int
virTestGetFlag(const char *name) {
    char *flagStr;
    unsigned int flag;
560

561
    if ((flagStr = getenv(name)) == NULL)
562 563
        return 0;

564
    if (virStrToLong_ui(flagStr, NULL, 10, &flag) < 0)
565 566
        return 0;

567 568 569 570
    return flag;
}

unsigned int
571
virTestGetDebug(void) {
572 573
    if (testDebug == -1)
        testDebug = virTestGetFlag("VIR_TEST_DEBUG");
574 575
    return testDebug;
}
576

577
unsigned int
578
virTestGetVerbose(void) {
579 580 581 582 583
    if (testVerbose == -1)
        testVerbose = virTestGetFlag("VIR_TEST_VERBOSE");
    return testVerbose || virTestGetDebug();
}

584 585
int virtTestMain(int argc,
                 char **argv,
E
Eric Blake 已提交
586
                 int (*func)(void))
587 588
{
    int ret;
589
    bool abs_srcdir_cleanup = false;
590
    char *testRange = NULL;
591
#if TEST_OOM
592 593
    int approxAlloc = 0;
    int n;
594
    char *oomStr = NULL;
595
    int oomCount;
596 597 598
    int mp = 0;
    pid_t *workers;
    int worker = 0;
599 600
#endif

E
Eric Blake 已提交
601
    abs_srcdir = getenv("abs_srcdir");
602 603 604 605
    if (!abs_srcdir) {
        abs_srcdir = getcwd(NULL, 0);
        abs_srcdir_cleanup = true;
    }
E
Eric Blake 已提交
606
    if (!abs_srcdir)
607
        return EXIT_AM_HARDFAIL;
E
Eric Blake 已提交
608

E
Eric Blake 已提交
609 610 611
    progname = last_component(argv[0]);
    if (STRPREFIX(progname, "lt-"))
        progname += 3;
E
Eric Blake 已提交
612 613
    if (argc > 1) {
        fprintf(stderr, "Usage: %s\n", argv[0]);
614 615 616 617
        fputs("effective environment variables:\n"
              "VIR_TEST_VERBOSE set to show names of individual tests\n"
              "VIR_TEST_DEBUG set to show information for debugging failures\n",
              stderr);
E
Eric Blake 已提交
618 619 620
        return EXIT_FAILURE;
    }
    fprintf(stderr, "TEST: %s\n", progname);
621

622
    if (virThreadInitialize() < 0 ||
623
        virErrorInitialize() < 0)
624
        return EXIT_FAILURE;
625

626
    virLogSetFromEnv();
627 628
    if (!getenv("LIBVIRT_DEBUG") && !virLogGetNbOutputs()) {
        if (virLogDefineOutput(virtTestLogOutput, virtTestLogClose, &testLog,
629
                               VIR_LOG_DEBUG, VIR_LOG_TO_STDERR, NULL, 0) < 0)
630
            return EXIT_FAILURE;
631
    }
632

633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659
    if ((testRange = getenv("VIR_TEST_RANGE")) != NULL) {
        char *end = NULL;
        unsigned int i;
        if (virStrToLong_ui(testRange, &end, 10, &i) < 0) {
            fprintf(stderr, "Cannot parse range %s\n", testRange);
            return EXIT_FAILURE;
        }
        testStart = testEnd = i;
        if (end && *end) {
            if (*end != '-') {
                fprintf(stderr, "Cannot parse range %s\n", testRange);
                return EXIT_FAILURE;
            }
            end++;
            if (virStrToLong_ui(end, NULL, 10, &i) < 0) {
                fprintf(stderr, "Cannot parse range %s\n", testRange);
                return EXIT_FAILURE;
            }
            testEnd = i;

            if (testEnd < testStart) {
                fprintf(stderr, "Test range end %zu must be >= %zu\n", testEnd, testStart);
                return EXIT_FAILURE;
            }
        }
    }

660
#if TEST_OOM
661 662 663 664 665 666 667 668 669 670
    if ((oomStr = getenv("VIR_TEST_OOM")) != NULL) {
        if (virStrToLong_i(oomStr, NULL, 10, &oomCount) < 0)
            oomCount = 0;

        if (oomCount < 0)
            oomCount = 0;
        if (oomCount)
            testOOM = 1;
    }

671 672 673
    if (getenv("VIR_TEST_MP") != NULL) {
        mp = sysconf(_SC_NPROCESSORS_ONLN);
        fprintf(stderr, "Using %d worker processes\n", mp);
674 675 676 677
        if (VIR_ALLOC_N(workers, mp) < 0) {
            ret = EXIT_FAILURE;
            goto cleanup;
        }
678 679
    }

D
Daniel P. Berrange 已提交
680
    /* Run once to prime any static allocations & ensure it passes */
E
Eric Blake 已提交
681
    ret = (func)();
682
    if (ret != EXIT_SUCCESS)
683
        goto cleanup;
684

685
# if TEST_OOM_TRACE
686
    if (virTestGetDebug())
687
        virAllocTestHook(virtTestErrorHook, NULL);
688
# endif
689 690 691 692 693 694

    if (testOOM) {
        /* Makes next test runs quiet... */
        testOOM++;
        virSetErrorFunc(NULL, virtTestErrorFuncQuiet);

D
Daniel P. Berrange 已提交
695 696 697
        virAllocTestInit();

        /* Run again to count allocs, and ensure it passes :-) */
E
Eric Blake 已提交
698
        ret = (func)();
D
Daniel P. Berrange 已提交
699 700 701
        if (ret != EXIT_SUCCESS)
            goto cleanup;

702 703
        approxAlloc = virAllocTestCount();
        testCounter++;
704
        if (virTestGetDebug())
705 706 707 708
            fprintf(stderr, "%d) OOM...\n", testCounter);
        else
            fprintf(stderr, "%d) OOM of %d allocs ", testCounter, approxAlloc);

709
        if (mp) {
710
            size_t i;
711
            for (i = 0; i < mp; i++) {
712 713 714 715 716 717 718 719
                workers[i] = fork();
                if (workers[i] == 0) {
                    worker = i + 1;
                    break;
                }
            }
        }

720 721
        /* Run once for each alloc, failing a different one
           and validating that the test case failed */
722
        for (n = 0; n < approxAlloc && (!mp || worker); n++) {
723 724
            if (mp &&
                (n % mp) != (worker - 1))
725
                continue;
726
            if (!virTestGetDebug()) {
727 728 729 730
                if (mp)
                    fprintf(stderr, "%d", worker);
                else
                    fprintf(stderr, ".");
731 732 733 734
                fflush(stderr);
            }
            virAllocTestOOM(n+1, oomCount);

E
Eric Blake 已提交
735
            if (((func)()) != EXIT_FAILURE) {
736 737 738 739 740
                ret = EXIT_FAILURE;
                break;
            }
        }

741 742 743 744
        if (mp) {
            if (worker) {
                _exit(ret);
            } else {
745
                size_t i;
746
                for (i = 0; i < mp; i++) {
747
                    if (virProcessWait(workers[i], NULL) < 0)
748 749 750 751 752 753
                        ret = EXIT_FAILURE;
                }
                VIR_FREE(workers);
            }
        }

754
        if (virTestGetDebug())
755 756 757 758 759 760 761
            fprintf(stderr, " ... OOM of %d allocs", approxAlloc);

        if (ret == EXIT_SUCCESS)
            fprintf(stderr, " OK\n");
        else
            fprintf(stderr, " FAILED\n");
    }
762
cleanup:
763
#else
E
Eric Blake 已提交
764
    ret = (func)();
765
#endif
766

767 768
    if (abs_srcdir_cleanup)
        VIR_FREE(abs_srcdir);
769
    virResetLastError();
770
    if (!virTestGetVerbose() && ret != EXIT_AM_SKIP) {
E
Eric Blake 已提交
771
        if (testCounter == 0 || testCounter % 40)
772 773
            fprintf(stderr, "%*s", 40 - (int)(testCounter % 40), "");
        fprintf(stderr, " %-3zu %s\n", testCounter, ret == 0 ? "OK" : "FAIL");
774
    }
775
    return ret;
776
}
777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821


int virtTestClearLineRegex(const char *pattern,
                           char *str)
{
    regex_t reg;
    char *lineStart = str;
    char *lineEnd = strchr(str, '\n');

    if (regcomp(&reg, pattern, REG_EXTENDED | REG_NOSUB) != 0)
        return -1;

    while (lineStart) {
        int ret;
        if (lineEnd)
            *lineEnd = '\0';


        ret = regexec(&reg, lineStart, 0, NULL, 0);
        //fprintf(stderr, "Match %d '%s' '%s'\n", ret, lineStart, pattern);
        if (ret == 0) {
            if (lineEnd) {
                memmove(lineStart, lineEnd + 1, strlen(lineEnd+1) + 1);
                /* Don't update lineStart - just iterate again on this
                   location */
                lineEnd = strchr(lineStart, '\n');
            } else {
                *lineStart = '\0';
                lineStart = NULL;
            }
        } else {
            if (lineEnd) {
                *lineEnd = '\n';
                lineStart = lineEnd + 1;
                lineEnd = strchr(lineStart, '\n');
            } else {
                lineStart = NULL;
            }
        }
    }

    regfree(&reg);

    return 0;
}