r5516 - trunk/varnish-cache/bin/varnishtest
phk at varnish-cache.org
phk at varnish-cache.org
Fri Nov 5 01:03:53 CET 2010
Author: phk
Date: 2010-11-05 01:03:52 +0100 (Fri, 05 Nov 2010)
New Revision: 5516
Added:
trunk/varnish-cache/bin/varnishtest/vtc_main.c
Modified:
trunk/varnish-cache/bin/varnishtest/Makefile.am
trunk/varnish-cache/bin/varnishtest/vtc.c
trunk/varnish-cache/bin/varnishtest/vtc.h
trunk/varnish-cache/bin/varnishtest/vtc_log.c
Log:
Major rewrite of the main-function of varnishtest:
Run tests in fork'ed subprocesses.
Support for running tests in parallel.
Command arguments straightened out.
Needs polishing, but I need to sleep.
Modified: trunk/varnish-cache/bin/varnishtest/Makefile.am
===================================================================
--- trunk/varnish-cache/bin/varnishtest/Makefile.am 2010-11-04 13:11:45 UTC (rev 5515)
+++ trunk/varnish-cache/bin/varnishtest/Makefile.am 2010-11-05 00:03:52 UTC (rev 5516)
@@ -16,6 +16,7 @@
vtc.h \
vtc_client.c \
vtc_http.c \
+ vtc_main.c \
vtc_log.c \
vtc_sema.c \
vtc_server.c \
Modified: trunk/varnish-cache/bin/varnishtest/vtc.c
===================================================================
--- trunk/varnish-cache/bin/varnishtest/vtc.c 2010-11-04 13:11:45 UTC (rev 5515)
+++ trunk/varnish-cache/bin/varnishtest/vtc.c 2010-11-05 00:03:52 UTC (rev 5516)
@@ -35,17 +35,17 @@
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
-#include <math.h>
#include <limits.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
-#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include "libvarnish.h"
+#include "vev.h"
#include "vsb.h"
#include "vqueue.h"
#include "miniobj.h"
@@ -56,7 +56,6 @@
#include "compat/srandomdev.h"
#endif
-#define MAX_FILESIZE (1024 * 1024)
#define MAX_TOKENS 200
static char *vtc_desc;
@@ -196,36 +195,6 @@
}
/**********************************************************************
- * Read a file into memory
- */
-
-static char *
-read_file(const char *fn)
-{
- char *buf;
- ssize_t sz = MAX_FILESIZE;
- ssize_t s;
- int fd;
-
- fd = open(fn, O_RDONLY);
- if (fd < 0)
- return (NULL);
- buf = malloc(sz);
- assert(buf != NULL);
- s = read(fd, buf, sz - 1);
- if (s <= 0) {
- free(buf);
- return (NULL);
- }
- AZ(close (fd));
- assert(s < sz); /* XXX: increase MAX_FILESIZE */
- buf[s] = '\0';
- buf = realloc(buf, s + 1);
- assert(buf != NULL);
- return (buf);
-}
-
-/**********************************************************************
* Execute a file
*/
@@ -503,214 +472,51 @@
{ NULL, NULL }
};
-struct priv_exec {
- const char *fn;
- char *buf;
-};
-
-static void *
-exec_file_thread(void *priv)
+int
+exec_file(const char *fn, const char *script, char *logbuf, unsigned loglen)
{
unsigned old_err;
- struct priv_exec *pe;
+ char *cwd, *p;
+ char topbuild[BUFSIZ];
- pe = priv;
+ vtc_loginit(logbuf, loglen);
+ vltop = vtc_logopen("top");
+ AN(vltop);
- vtc_thread = pthread_self();
- parse_string(pe->buf, cmds, NULL, vltop);
- old_err = vtc_error;
- vtc_stop = 1;
- vtc_log(vltop, 1, "RESETTING after %s", pe->fn);
- reset_cmds(cmds);
- vtc_error = old_err;
- return (NULL);
-}
+ init_macro();
+ init_sema();
-#ifndef HAVE_PTHREAD_TIMEDJOIN_NP
-static volatile sig_atomic_t alrm_flag = 0;
+ cwd = getcwd(NULL, PATH_MAX);
+ bprintf(topbuild, "%s/%s", cwd, TOP_BUILDDIR);
+ macro_def(vltop, NULL, "topbuild", topbuild);
-static void
-sigalrm(int x)
-{
+ macro_def(vltop, NULL, "bad_ip", "10.255.255.255");
- (void)x;
- alrm_flag = 1;
- vtc_error = 1;
-}
-#endif
+ srandomdev();
+ bprintf(vtc_tmpdir, "/tmp/vtc.%d.%08x", getpid(), (unsigned)random());
+ AZ(mkdir(vtc_tmpdir, 0700));
+ macro_def(vltop, NULL, "tmpdir", vtc_tmpdir);
-static double
-exec_file(const char *fn, unsigned dur)
-{
- double t0;
- struct priv_exec pe;
- pthread_t pt;
-#ifdef HAVE_PTHREAD_TIMEDJOIN_NP
- double t;
- struct timespec ts;
-#endif
- void *v;
- int i;
-
- vtc_logreset();
- t0 = TIM_mono();
vtc_stop = 0;
vtc_desc = NULL;
vtc_log(vltop, 1, "TEST %s starting", fn);
- pe.buf = read_file(fn);
- if (pe.buf == NULL)
- vtc_log(vltop, 0, "Cannot read file '%s': %s",
- fn, strerror(errno));
- pe.fn = fn;
-#ifdef HAVE_PTHREAD_TIMEDJOIN_NP
- t = TIM_real() + dur;
- ts.tv_sec = (long)floor(t);
- ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9);
+ p = strdup(script);
+ AN(p);
- AZ(pthread_create(&pt, NULL, exec_file_thread, &pe));
- i = pthread_timedjoin_np(pt, &v, &ts);
- memset(&vtc_thread, 0, sizeof vtc_thread);
-#else
- alrm_flag = 0;
- (void)signal(SIGALRM, sigalrm);
- alarm(dur);
- AZ(pthread_create(&pt, NULL, exec_file_thread, &pe));
- i = pthread_join(pt, &v);
- alarm(0);
- if (alrm_flag)
- i = ETIMEDOUT;
-#endif
+ vtc_thread = pthread_self();
+ parse_string(p, cmds, NULL, vltop);
+ old_err = vtc_error;
+ vtc_stop = 1;
+ vtc_log(vltop, 1, "RESETTING after %s", fn);
+ reset_cmds(cmds);
+ vtc_error = old_err;
- if (i != 0) {
- if (i != ETIMEDOUT)
- vtc_log(vltop, 1, "Weird condwait return: %d %s",
- i, strerror(i));
- vtc_log(vltop, 1, "Test timed out");
- vtc_error = 1;
- }
-
if (vtc_error)
vtc_log(vltop, 1, "TEST %s FAILED", fn);
else
vtc_log(vltop, 1, "TEST %s completed", fn);
- t0 = TIM_mono() - t0;
-
- if (vtc_error && vtc_verbosity == 0)
- printf("%s", vtc_logfull());
- else if (vtc_verbosity == 0)
- printf("# top TEST %s passed (%.3fs)\n", fn, t0);
-
free(vtc_desc);
- return (t0);
+ return (vtc_error);
}
-
-/**********************************************************************
- * Print usage
- */
-
-static void
-usage(void)
-{
- fprintf(stderr, "usage: varnishtest [-n iter] [-qv] file ...\n");
- exit(1);
-}
-
-/**********************************************************************
- * Main
- */
-
-int
-main(int argc, char * const *argv)
-{
- int ch, i, ntest = 1, ncheck = 0;
- FILE *fok;
- double tmax, t0, t00;
- unsigned dur = 30;
- const char *nmax;
- char cmd[BUFSIZ];
- char *cwd;
- char topbuild[BUFSIZ];
-
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
- vtc_loginit();
- vltop = vtc_logopen("top");
- AN(vltop);
- while ((ch = getopt(argc, argv, "L:n:qt:v")) != -1) {
- switch (ch) {
- case 'n':
- ntest = strtoul(optarg, NULL, 0);
- break;
- case 'q':
- vtc_verbosity--;
- break;
- case 't':
- dur = strtoul(optarg, NULL, 0);
- break;
- case 'v':
- vtc_verbosity++;
- break;
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc == 0)
- usage();
-
- init_macro();
- init_sema();
-
- srandomdev();
- bprintf(vtc_tmpdir, "/tmp/vtc.%d.%08x", getpid(), (unsigned)random());
- AZ(mkdir(vtc_tmpdir, 0700));
- macro_def(vltop, NULL, "tmpdir", vtc_tmpdir);
-
- cwd = getcwd(NULL, PATH_MAX);
- bprintf(topbuild, "%s/%s", cwd, TOP_BUILDDIR);
- macro_def(vltop, NULL, "topbuild", topbuild);
-
- macro_def(vltop, NULL, "bad_ip", "10.255.255.255");
- tmax = 0;
- nmax = NULL;
- t00 = TIM_mono();
- for (i = 0; i < ntest; i++) {
- for (ch = 0; ch < argc; ch++) {
- t0 = exec_file(argv[ch], dur);
- ncheck++;
- if (t0 > tmax) {
- tmax = t0;
- nmax = argv[ch];
- }
- if (vtc_error)
- break;
- }
- if (vtc_error)
- break;
- }
-
- /* Remove tmpdir on success or non-verbosity */
- if (vtc_error == 0 || vtc_verbosity == 0) {
- bprintf(cmd, "rm -rf %s", vtc_tmpdir);
- AZ(system(cmd));
- }
-
- if (vtc_error)
- return (2);
-
- t00 = TIM_mono() - t00;
- if (ncheck > 1) {
- printf("# top Slowest test: %s %.3fs\n", nmax, tmax);
- printf("# top Total tests run: %d\n", ncheck);
- printf("# top Total duration: %.3fs\n", t00);
- }
-
- fok = fopen("_.ok", "w");
- if (fok != NULL)
- AZ(fclose(fok));
- return (0);
-}
Modified: trunk/varnish-cache/bin/varnishtest/vtc.h
===================================================================
--- trunk/varnish-cache/bin/varnishtest/vtc.h 2010-11-04 13:11:45 UTC (rev 5515)
+++ trunk/varnish-cache/bin/varnishtest/vtc.h 2010-11-05 00:03:52 UTC (rev 5516)
@@ -58,7 +58,6 @@
cmd_f cmd_varnish;
cmd_f cmd_sema;
-extern int vtc_verbosity;
extern volatile sig_atomic_t vtc_error; /* Error, bail out */
extern int vtc_stop; /* Abandon current test, no error */
extern pthread_t vtc_thread;
@@ -70,15 +69,15 @@
void cmd_server_genvcl(struct vsb *vsb);
-void vtc_loginit(void);
-void vtc_logreset(void);
-const char *vtc_logfull(void);
+void vtc_loginit(char *buf, unsigned buflen);
struct vtclog *vtc_logopen(const char *id);
void vtc_logclose(struct vtclog *vl);
void vtc_log(struct vtclog *vl, unsigned lvl, const char *fmt, ...);
void vtc_dump(struct vtclog *vl, unsigned lvl, const char *pfx,
const char *str);
+int exec_file(const char *fn, const char *script, char *logbuf, unsigned loglen);
+
void macro_def(struct vtclog *vl, const char *instance, const char *name,
const char *fmt, ...);
struct vsb *macro_expand(struct vtclog *vl, const char *text);
Modified: trunk/varnish-cache/bin/varnishtest/vtc_log.c
===================================================================
--- trunk/varnish-cache/bin/varnishtest/vtc_log.c 2010-11-04 13:11:45 UTC (rev 5515)
+++ trunk/varnish-cache/bin/varnishtest/vtc_log.c 2010-11-05 00:03:52 UTC (rev 5516)
@@ -44,10 +44,9 @@
#include "vtc.h"
-int vtc_verbosity = 0;
-
-static struct vsb *vtclog_full;
static pthread_mutex_t vtclog_mtx;
+static char *vtclog_buf;
+static unsigned vtclog_left;
struct vtclog {
unsigned magic;
@@ -60,31 +59,14 @@
/**********************************************************************/
void
-vtc_loginit()
+vtc_loginit(char *buf, unsigned buflen)
{
- AZ(vtclog_full);
- vtclog_full = vsb_newauto();
- AN(vtclog_full);
+ vtclog_buf = buf;
+ vtclog_left = buflen;
AZ(pthread_mutex_init(&vtclog_mtx, NULL));
}
-void
-vtc_logreset()
-{
-
- AN(vtclog_full);
- vsb_clear(vtclog_full);
-}
-
-const char *
-vtc_logfull(void)
-{
- vsb_finish(vtclog_full);
- AZ(vsb_overflowed(vtclog_full));
- return (vsb_data(vtclog_full));
-}
-
/**********************************************************************/
@@ -124,14 +106,18 @@
static void
vtc_log_emit(const struct vtclog *vl, unsigned lvl)
{
+ int l;
+
if (vtc_stop && lvl == 0)
return;
+ l = vsb_len(vl->vsb);
AZ(pthread_mutex_lock(&vtclog_mtx));
- vsb_cat(vtclog_full, vsb_data(vl->vsb));
+ assert(vtclog_left > l);
+ memcpy(vtclog_buf,vsb_data(vl->vsb), l);
+ vtclog_buf += l;
+ *vtclog_buf = '\0';
+ vtclog_left -= l;
AZ(pthread_mutex_unlock(&vtclog_mtx));
-
- if (lvl <= vtc_verbosity)
- (void)fputs(vsb_data(vl->vsb), stdout);
}
//lint -e{818}
Added: trunk/varnish-cache/bin/varnishtest/vtc_main.c
===================================================================
--- trunk/varnish-cache/bin/varnishtest/vtc_main.c (rev 0)
+++ trunk/varnish-cache/bin/varnishtest/vtc_main.c 2010-11-05 00:03:52 UTC (rev 5516)
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2008-2010 Redpill Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "svnid.h"
+SVNID("$Id: vtc.c 5507 2010-11-04 11:28:06Z phk $")
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "libvarnish.h"
+#include "vev.h"
+#include "vsb.h"
+#include "vqueue.h"
+#include "miniobj.h"
+
+#include "vtc.h"
+
+#define MAX_FILESIZE (1024 * 1024)
+
+
+struct vtc_tst {
+ unsigned magic;
+#define TST_MAGIC 0x618d8b88
+ VTAILQ_ENTRY(vtc_tst) list;
+ const char *filename;
+ char *script;
+ unsigned ntodo;
+};
+
+struct vtc_job {
+ unsigned magic;
+#define JOB_MAGIC 0x1b5fc419
+ struct vtc_tst *tst;
+ pid_t child;
+ struct vev *ev;
+ struct vev *evt;
+ char *buf;
+ unsigned bufsiz;
+ double t0;
+};
+
+static VTAILQ_HEAD(, vtc_tst) tst_head = VTAILQ_HEAD_INITIALIZER(tst_head);
+static struct vev_base *vb;
+static int njob = 0;
+static int npar = 1; /* Number of parallel tests */
+static unsigned vtc_maxdur = 30; /* Max duration of any test */
+static int vtc_continue; /* Continue on error */
+static int vtc_verbosity = 1; /* Verbosity Level */
+static int vtc_good;
+static int vtc_fail;
+
+/**********************************************************************
+ * Read a file into memory
+ */
+
+static char *
+read_file(const char *fn)
+{
+ char *buf;
+ ssize_t sz = MAX_FILESIZE;
+ ssize_t s;
+ int fd;
+
+ fd = open(fn, O_RDONLY);
+ if (fd < 0)
+ return (NULL);
+ buf = malloc(sz);
+ assert(buf != NULL);
+ s = read(fd, buf, sz - 1);
+ if (s <= 0) {
+ free(buf);
+ return (NULL);
+ }
+ AZ(close (fd));
+ assert(s < sz); /* XXX: increase MAX_FILESIZE */
+ buf[s] = '\0';
+ buf = realloc(buf, s + 1);
+ assert(buf != NULL);
+ return (buf);
+}
+
+/**********************************************************************
+ * Print usage
+ */
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: varnishtest [-n iter] [-qv] file ...\n");
+ exit(1);
+}
+
+/**********************************************************************
+ * CallBack
+ */
+
+static int
+tst_cb(const struct vev *ve, int what)
+{
+ struct vtc_job *jp;
+ char buf[BUFSIZ];
+ int i, stx;
+ pid_t px;
+ double t;
+
+ CAST_OBJ_NOTNULL(jp, ve->priv, JOB_MAGIC);
+
+ // printf("%p %s %d\n", ve, jp->tst->filename, what);
+ if (what == 0) {
+ /* XXX: Timeout */
+ AZ(kill(jp->child, SIGKILL));
+ jp->evt = NULL;
+ return (1);
+ }
+ assert(what & EV_RD);
+
+ *buf = '\0';
+ i = read(ve->fd, buf, sizeof buf - 1);
+ if (i > 0) {
+ buf[i] = '\0';
+ printf("######## %s ########\n%s", jp->tst->filename, buf);
+ }
+ if (i == 0) {
+ njob--;
+ px = wait4(jp->child, &stx, 0, NULL);
+ t = TIM_mono() - jp->t0;
+ AZ(close(ve->fd));
+
+ if (stx && vtc_verbosity)
+ printf("%s\n", jp->buf);
+ else if (vtc_verbosity > 1)
+ printf("%s\n", jp->buf);
+
+ if (stx)
+ vtc_fail++;
+ else
+ vtc_good++;
+
+ if (stx) {
+ printf("# top TEST %s FAILED (%.3f)\n",
+ jp->tst->filename, t);
+ if (!vtc_continue) {
+ /* XXX kill -9 other jobs ? */
+ exit (2);
+ }
+ } else if (vtc_verbosity) {
+ printf("# top TEST %s passed (%.3f)\n",
+ jp->tst->filename, t);
+ }
+ AZ(munmap(jp->buf, jp->bufsiz));
+ if (jp->evt != NULL)
+ vev_del(vb, jp->evt);
+ FREE_OBJ(jp);
+ return (1);
+ }
+ return (0);
+}
+
+/**********************************************************************
+ * Start Test
+ */
+
+static void
+start_test(void)
+{
+ struct vtc_tst *tp;
+ int p[2], sfd, retval;
+ struct vtc_job *jp;
+
+ ALLOC_OBJ(jp, JOB_MAGIC);
+ AN(jp);
+
+ jp->bufsiz = 64*1024; /* XXX */
+
+ jp->buf = mmap(NULL, jp->bufsiz, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
+ assert(jp->buf != MAP_FAILED);
+ memset(jp->buf, 0, jp->bufsiz);
+
+ AZ(minherit(jp->buf, jp->bufsiz, INHERIT_SHARE));
+
+ tp = VTAILQ_FIRST(&tst_head);
+ CHECK_OBJ_NOTNULL(tp, TST_MAGIC);
+ AN(tp->ntodo);
+ tp->ntodo--;
+ VTAILQ_REMOVE(&tst_head, tp, list);
+ if (tp->ntodo >0)
+ VTAILQ_INSERT_TAIL(&tst_head, tp, list);
+
+ jp->tst = tp;
+
+ AZ(pipe(p));
+ assert(p[0] > STDERR_FILENO);
+ assert(p[1] > STDERR_FILENO);
+ jp->t0 = TIM_mono();
+ jp->child = fork();
+ assert(jp->child >= 0);
+ if (jp->child == 0) {
+ AZ(close(STDIN_FILENO));
+ assert(open("/dev/null", O_RDONLY) == STDIN_FILENO);
+ assert(dup2(p[1], STDOUT_FILENO) == STDOUT_FILENO);
+ assert(dup2(p[1], STDERR_FILENO) == STDERR_FILENO);
+ for (sfd = STDERR_FILENO + 1; sfd < 100; sfd++)
+ (void)close(sfd);
+ retval = exec_file(jp->tst->filename, jp->tst->script, jp->buf, jp->bufsiz);
+ _exit(retval);
+ }
+ AZ(close(p[1]));
+ AZ(minherit(jp->buf, jp->bufsiz, INHERIT_NONE));
+
+ jp->ev = vev_new();
+ AN(jp->ev);
+ jp->ev->fd_flags = EV_RD | EV_HUP | EV_ERR;
+ jp->ev->fd = p[0];
+ jp->ev->priv = jp;
+ jp->ev->callback = tst_cb;
+ AZ(vev_add(vb, jp->ev));
+
+ jp->evt = vev_new();
+ AN(jp->evt);
+ jp->evt->fd = -1;
+ jp->evt->timeout = vtc_maxdur;
+ jp->evt->priv = jp;
+ jp->evt->callback = tst_cb;
+ AZ(vev_add(vb, jp->evt));
+}
+
+/**********************************************************************
+ * Main
+ */
+
+int
+main(int argc, char * const *argv)
+{
+ int ch, i;
+ int ntest = 1; /* Run tests this many times */
+ struct vtc_tst *tp;
+ char *p;
+
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+ while ((ch = getopt(argc, argv, "j:kL:n:qt:v")) != -1) {
+ switch (ch) {
+ case 'j':
+ npar = strtoul(optarg, NULL, 0);
+ break;
+ case 'k':
+ vtc_continue = !vtc_continue;
+ break;
+ case 'n':
+ ntest = strtoul(optarg, NULL, 0);
+ break;
+ case 'q':
+ if (vtc_verbosity > 0)
+ vtc_verbosity--;
+ break;
+ case 't':
+ vtc_maxdur = strtoul(optarg, NULL, 0);
+ break;
+ case 'v':
+ if (vtc_verbosity < 2)
+ vtc_verbosity++;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ for (;argc > 0; argc--, argv++) {
+ p = read_file(*argv);
+ if (p == NULL) {
+ fprintf(stderr, "Cannot stat file \"%s\": %s\n",
+ *argv, strerror(errno));
+ if (vtc_continue)
+ continue;
+ exit (2);
+ }
+ ALLOC_OBJ(tp, TST_MAGIC);
+ AN(tp);
+ tp->filename = *argv;
+ tp->script = p;
+ tp->ntodo = ntest;
+ VTAILQ_INSERT_TAIL(&tst_head, tp, list);
+ }
+
+ vb = vev_new_base();
+
+ i = 0;
+ while(!VTAILQ_EMPTY(&tst_head) || i) {
+ if (!VTAILQ_EMPTY(&tst_head) && njob < npar) {
+ start_test();
+ njob++;
+ i = 1;
+ continue;
+ }
+ i = vev_schedule_one(vb);
+ }
+ if (vtc_continue)
+ fprintf(stderr, "%d tests failed, %d tests passed\n",
+ vtc_fail, vtc_good);
+ if (vtc_fail)
+ return (1);
+ return (0);
+}
More information about the varnish-commit
mailing list