Skip to content
This repository was archived by the owner on Feb 18, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
lib/*.o
src/*.o
src/debug/*.o
src/teken_state.h
src/vtc_h2_dectbl.h
vtest
vtest.pc
ext_foo.so

# droppings from submodule use
tests/*.log
Expand Down
60 changes: 58 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ VARNISH_SRC ?= /home/phk/Varnish/trunk/varnish-cache

AWK ?= awk

SED ?= sed

SRCS= src/*.c \
lib/*.c

Expand All @@ -22,7 +24,7 @@ DEPS= lib/*.h \
FLAGS= -O2 -Wall -Werror

CFLAGS= ${FLAGS}
LDFLAGS= ${FLAGS} -s
LDFLAGS= ${FLAGS} -s -rdynamic -ldl
DEFINES=

INCS= -I. \
Expand All @@ -36,6 +38,38 @@ LIBS= -L/usr/local/lib \
-lpcre2-8 \
-lz

PREFIX ?= /usr/local

PACKAGE_VERSION = 0.9

#######################################################################

all: vtest

#######################################################################

vtest.pc: vtest.pc.in
${SED} <$< >$@.tmp "s:@prefix@:$(PREFIX):; s:@PACKAGE_VERSION@:$(PACKAGE_VERSION):;"
mv $@.tmp $@

#######################################################################

HEADERS= \
src/vtc.h \
src/cmds.h \
lib/vdef.h \
lib/miniobj.h \
lib/vas.h \
lib/vsb.h

install: vtest vtest.pc
umask 022 && \
mkdir -p $(PREFIX)/bin $(PREFIX)/include/vtest $(PREFIX)/lib/pkgconfig && \
cp vtest $(PREFIX)/bin && chmod 755 $(PREFIX)/bin/vtest && \
cp $(HEADERS) $(PREFIX)/include/vtest && \
cp vtest.pc $(PREFIX)/lib/pkgconfig && \
chmod 644 $(PREFIX)/include/vtest/*.h $(PREFIX)/lib/pkgconfig/vtest.pc

#######################################################################
# If you want to build vtest without varnish support, use this part:

Expand All @@ -52,6 +86,7 @@ vtest: ${DEPS} ${SRCS}

test: vtest
env PATH=`pwd`:${PATH} vtest tests/*.vtc
./vtest -E `pwd`/ext_foo.so tests/a00029.vtc

#######################################################################
# ... other point to varnish source tree and use this part:
Expand All @@ -70,6 +105,26 @@ varnishtest: ${DEPS} ${SRCS}
-Wl,--rpath,${VARNISH_SRC}/lib/libvarnishapi/.libs \
-lvarnishapi

#######################################################################
# demo extension

src/debug/ext_foo.o: src/debug/ext_foo.c
${CC} \
${CFLAGS} \
${DEFINES} \
${INCS} \
-fPIC -DPIC \
-o $@ -c $<

ext_foo.so: src/debug/ext_foo.o
${CC} \
-shared \
${LDFLAGS} \
-o $@ $<

#######################################################################
# pkg-config

#######################################################################
# Implicit rule used in a sub-process by the rules above, and makes use
# of ${DEFINES} for extra arguments :
Expand Down Expand Up @@ -101,7 +156,8 @@ clean:
rm -f vtest varnishtest
rm -f src/teken_state.h
rm -f src/vtc_h2_dectbl.h
rm -f ${OBJS}
rm -f ${OBJS} src/debug/ext_foo.o ext_foo.so
rm -f vtest.pc

#######################################################################
# Housekeeping
Expand Down
34 changes: 34 additions & 0 deletions src/debug/ext_foo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* example vtc extension to add the 'foo' command
*/

#include "config.h"

#include <string.h>

#include "vtc.h"

static void
cmd_foo(CMD_ARGS)
{
(void)priv;

// fini
if (av == NULL)
return;

AZ(strcmp(av[0], "foo"));
av++;

AN(vl);

for (; *av != NULL; av++)
vtc_log(vl, 1, "foo: %s", *av);
}

static struct cmds foo_cmds[1] = {{"foo", cmd_foo}};

static __attribute__((constructor)) void
foo_init(void) {
register_top_cmds(foo_cmds, vcountof(foo_cmds));
}
60 changes: 56 additions & 4 deletions src/vtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,64 @@ static const struct cmds global_cmds[] = {
{ NULL, NULL }
};

static const struct cmds top_cmds[] = {
static const struct cmds builtin_top_cmds[] = {
#define CMD_TOP(n) { #n, cmd_##n },
#include "cmds.h"
{ NULL, NULL }
};

static struct dyncmds *top = NULL;

/*
* Register commands, to be called from a constructor/init function
*
* the cmds array always has one additional NULL entry.
*
* Because we always search commands in order, the first registration of a
* command wins. We do not check for duplicates.
*
* NB: We never free the dyncmds deliberately as most of the allocations in
*/
static void
register_cmds(struct dyncmds **dynp, const struct cmds *cmds, unsigned n)
{
struct dyncmds *dyn;

AN(dynp);
dyn = *dynp;
if (dyn == NULL) {
ALLOC_FLEX_OBJ(dyn, cmds, n + 1, VTC_DYNCMDS_MAGIC);
AN(dyn);
dyn->n = 1;
} else {
CHECK_OBJ(dyn, VTC_DYNCMDS_MAGIC);
dyn = realloc(dyn, SIZEOF_FLEX_OBJ(dyn, cmds, dyn->n + n));
AN(dyn);
}
assert(dyn->n >= 1);
memcpy(&dyn->cmds[dyn->n - 1], cmds, n * sizeof *cmds);
dyn->n += n;
dyn->cmds[dyn->n - 1] = (struct cmds){0};
*dynp = dyn;
}

void
register_top_cmds(const struct cmds *cmds, unsigned n)
{
register_cmds(&top, cmds, n);
}

const struct cmds *
top_cmds(void)
{
return (top->cmds);
}

static __attribute__((constructor)) void
register_builtin_top_cmds(void)
{
register_top_cmds(builtin_top_cmds, vcountof(builtin_top_cmds));
}

/**********************************************************************/

static struct macro *
Expand Down Expand Up @@ -545,7 +597,7 @@ fail_out(void)
vtc_stop = 1;
vtc_log(vltop, 1, "RESETTING after %s", tfn);
reset_cmds(global_cmds);
reset_cmds(top_cmds);
reset_cmds(top->cmds);
vtc_error |= old_err;

if (vtc_error)
Expand Down Expand Up @@ -579,7 +631,7 @@ exec_file(const char *fn, const char *script, const char *tmpdir,
vtc_loginit(logbuf, loglen);
vltop = vtc_logopen("top");
AN(vltop);
vtc_log_set_cmd(vltop, top_cmds);
vtc_log_set_cmd(vltop, top->cmds);

vtc_log(vltop, 1, "TEST %s starting", fn);

Expand Down
10 changes: 10 additions & 0 deletions src/vtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ struct cmds {
cmd_f *cmd;
};

// to extend cmds with shared objects during startup
struct dyncmds {
unsigned magic;
#define VTC_DYNCMDS_MAGIC 0xc298428f
unsigned n;
struct cmds cmds[] v_counted_by_(n);
};
void register_top_cmds(const struct cmds *cmds, unsigned n);
const struct cmds * top_cmds(void);

void parse_string(struct vtclog *vl, void *priv, const char *spec);
int fail_out(void);

Expand Down
11 changes: 10 additions & 1 deletion src/vtc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <sys/wait.h>

#include <ctype.h>
#include <dlfcn.h>
#include <dirent.h>
#include <poll.h>
#include <stdio.h>
Expand Down Expand Up @@ -185,6 +186,7 @@ usage(void)
"Set internal buffer size (default: 1M)");
fprintf(stderr, FMT, "-C", "Use cleaner subprocess");
fprintf(stderr, FMT, "-D name=val", "Define macro");
fprintf(stderr, FMT, "-E extension.so", "Load extenstion");
fprintf(stderr, FMT, "-i", "Find varnish binaries in build tree");
fprintf(stderr, FMT, "-j jobs", "Run this many tests in parallel");
fprintf(stderr, FMT, "-k", "Continue on test failure");
Expand Down Expand Up @@ -865,7 +867,7 @@ main(int argc, char * const *argv)
AN(cbvsb);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
while ((ch = getopt(argc, argv, "b:CD:hij:kLln:p:qt:vW")) != -1) {
while ((ch = getopt(argc, argv, "b:CD:E:hij:kLln:p:qt:vW")) != -1) {
switch (ch) {
case 'b':
if (VNUM_2bytes(optarg, &bufsiz, 0)) {
Expand All @@ -890,6 +892,13 @@ main(int argc, char * const *argv)
exit(2);
}
break;
case 'E':
if (! dlopen(optarg, RTLD_NOW)) {
fprintf(stderr, "Failed to load extension %s: %s\n",
optarg, dlerror());
exit(2);
}
break;
case 'i':
iflg = 1;
break;
Expand Down
8 changes: 3 additions & 5 deletions src/vtc_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,11 +652,9 @@ cmd_feature(CMD_ARGS)
av++;
if (*av == NULL)
vtc_fatal(vl, "vtest_cmd needs the command name");
#define CMD_TOP(n) \
if (!strcmp(*av, #n)) \
skip = neg;
#define CMD_GLOBAL(n) CMD_TOP(n)
#include "cmds.h"
for (const struct cmds *cmd = top_cmds(); cmd->name != NULL; cmd++)
if (!strcmp(*av, cmd->name))
skip = neg;
}
if (!good)
vtc_fatal(vl, "FAIL test, unknown feature: %s", feat);
Expand Down
5 changes: 5 additions & 0 deletions tests/a00029.vtc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
vtest "extension use"

feature vtest_cmd foo

foo 1 2 3
10 changes: 10 additions & 0 deletions vtest.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
prefix=@prefix@
bindir=${prefix}/bin
includedir=${prefix}/include
pkgincludedir=${includedir}/vtest

Name: VTest2
Description: The HTTP test-program formerly known as Varnishtest (reiterated)
URL: https://github.com/vtest/VTest2
Version: @PACKAGE_VERSION@
Cflags: -I${pkgincludedir}