Commit 3587d1b2 authored by Per Buer's avatar Per Buer
parents 3fba51b0 a1a62dc7
...@@ -430,12 +430,12 @@ cnt_error(struct sess *sp) ...@@ -430,12 +430,12 @@ cnt_error(struct sess *sp)
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Fetch an object from the backend, either for pass or for caching. * Fetch response headers from the backend
* *
DOT subgraph xcluster_fetch { DOT subgraph xcluster_fetch {
DOT fetch [ DOT fetch [
DOT shape=ellipse DOT shape=ellipse
DOT label="fetch from backend\n(find obj.ttl)" DOT label="fetch hdr\nfrom backend\n(find obj.ttl)"
DOT ] DOT ]
DOT vcl_fetch [ DOT vcl_fetch [
DOT shape=record DOT shape=record
...@@ -446,11 +446,10 @@ DOT fetch_pass [ ...@@ -446,11 +446,10 @@ DOT fetch_pass [
DOT shape=ellipse DOT shape=ellipse
DOT label="obj.pass=true" DOT label="obj.pass=true"
DOT ] DOT ]
DOT vcl_fetch -> fetch_pass [label="pass",style=bold,color=red] DOT vcl_fetch -> fetch_pass [label="hit_for_pass",style=bold,color=red]
DOT } DOT }
DOT fetch_pass -> deliver [style=bold,color=red] DOT fetch_pass -> fetchbody [style=bold,color=red]
DOT vcl_fetch -> deliver [label="deliver",style=bold,color=blue,weight=2] DOT vcl_fetch -> fetchbody [label="deliver",style=bold,color=blue,weight=2]
DOT vcl_fetch -> recv [label="restart"]
DOT vcl_fetch -> rstfetch [label="restart",color=purple] DOT vcl_fetch -> rstfetch [label="restart",color=purple]
DOT rstfetch [label="RESTART",shape=plaintext] DOT rstfetch [label="RESTART",shape=plaintext]
DOT fetch -> errfetch DOT fetch -> errfetch
...@@ -462,11 +461,6 @@ static int ...@@ -462,11 +461,6 @@ static int
cnt_fetch(struct sess *sp) cnt_fetch(struct sess *sp)
{ {
int i; int i;
struct http *hp, *hp2;
char *b;
unsigned l, nhttp;
int varyl = 0, pass;
struct vsb *vary = NULL;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
...@@ -489,21 +483,6 @@ cnt_fetch(struct sess *sp) ...@@ -489,21 +483,6 @@ cnt_fetch(struct sess *sp)
i = FetchHdr(sp); i = FetchHdr(sp);
} }
/*
* These two headers can be spread over multiple actual headers
* and we rely on their content outside of VCL, so collect them
* into one line here.
*/
http_CollectHdr(sp->wrk->beresp, H_Cache_Control);
http_CollectHdr(sp->wrk->beresp, H_Vary);
/*
* Figure out how the fetch is supposed to happen, before the
* headers are adultered by VCL
* Also sets other sp->wrk variables
*/
sp->wrk->body_status = RFC2616_Body(sp);
if (i) { if (i) {
if (sp->objcore != NULL) { if (sp->objcore != NULL) {
CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
...@@ -520,6 +499,22 @@ cnt_fetch(struct sess *sp) ...@@ -520,6 +499,22 @@ cnt_fetch(struct sess *sp)
return (0); return (0);
} }
/*
* These two headers can be spread over multiple actual headers
* and we rely on their content outside of VCL, so collect them
* into one line here.
*/
http_CollectHdr(sp->wrk->beresp, H_Cache_Control);
http_CollectHdr(sp->wrk->beresp, H_Vary);
/*
* Figure out how the fetch is supposed to happen, before the
* headers are adultered by VCL
* Also sets other sp->wrk variables
*/
sp->wrk->body_status = RFC2616_Body(sp);
sp->err_code = http_GetStatus(sp->wrk->beresp); sp->err_code = http_GetStatus(sp->wrk->beresp);
/* /*
...@@ -541,6 +536,75 @@ cnt_fetch(struct sess *sp) ...@@ -541,6 +536,75 @@ cnt_fetch(struct sess *sp)
VCL_fetch_method(sp); VCL_fetch_method(sp);
switch (sp->handling) {
case VCL_RET_HIT_FOR_PASS:
if (sp->objcore != NULL)
sp->objcore->flags |= OC_F_PASS;
sp->step = STP_FETCHBODY;
return (0);
case VCL_RET_DELIVER:
sp->step = STP_FETCHBODY;
return (0);
default:
break;
}
/*
* We are not going to fetch the body
* Close the connection and clean up...
*/
VDI_CloseFd(sp);
if (sp->objcore != NULL) {
CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
sp->objcore = NULL;
}
http_Setup(sp->wrk->bereq, NULL);
http_Setup(sp->wrk->beresp, NULL);
sp->wrk->h_content_length = NULL;
sp->director = NULL;
sp->wrk->storage_hint = NULL;
switch (sp->handling) {
case VCL_RET_RESTART:
sp->restarts++;
sp->step = STP_RECV;
return (0);
case VCL_RET_ERROR:
sp->step = STP_ERROR;
return (0);
default:
WRONG("Illegal action in vcl_fetch{}");
}
}
/*--------------------------------------------------------------------
* Fetch response body from the backend
*
DOT subgraph xcluster_body {
DOT fetchbody [
DOT shape=ellipse
DOT label="fetch body\nfrom backend\n"
DOT ]
DOT }
DOT fetchbody -> deliver [style=bold,color=red]
*/
static int
cnt_fetchbody(struct sess *sp)
{
int i;
struct http *hp, *hp2;
char *b;
unsigned l, nhttp;
struct vsb *vary = NULL;
int varyl = 0, pass;
assert(sp->handling == VCL_RET_HIT_FOR_PASS ||
sp->handling == VCL_RET_DELIVER);
if (sp->objcore == NULL) { if (sp->objcore == NULL) {
/* This is a pass from vcl_recv */ /* This is a pass from vcl_recv */
pass = 1; pass = 1;
...@@ -550,7 +614,6 @@ cnt_fetch(struct sess *sp) ...@@ -550,7 +614,6 @@ cnt_fetch(struct sess *sp)
/* pass from vcl_fetch{} -> hit-for-pass */ /* pass from vcl_fetch{} -> hit-for-pass */
/* XXX: the bereq was not filtered pass... */ /* XXX: the bereq was not filtered pass... */
pass = 1; pass = 1;
sp->objcore->flags |= OC_F_PASS;
} else { } else {
/* regular object */ /* regular object */
pass = 0; pass = 0;
...@@ -698,24 +761,6 @@ cnt_fetch(struct sess *sp) ...@@ -698,24 +761,6 @@ cnt_fetch(struct sess *sp)
return (0); return (0);
} }
switch (sp->handling) {
case VCL_RET_RESTART:
HSH_Drop(sp);
sp->director = NULL;
sp->restarts++;
sp->step = STP_RECV;
return (0);
case VCL_RET_HIT_FOR_PASS:
case VCL_RET_DELIVER:
break;
case VCL_RET_ERROR:
HSH_Drop(sp);
sp->step = STP_ERROR;
return (0);
default:
WRONG("Illegal action in vcl_fetch{}");
}
if (sp->obj->objcore != NULL) { if (sp->obj->objcore != NULL) {
EXP_Insert(sp->obj); EXP_Insert(sp->obj);
AN(sp->obj->objcore); AN(sp->obj->objcore);
...@@ -1334,7 +1379,6 @@ CNT_Session(struct sess *sp) ...@@ -1334,7 +1379,6 @@ CNT_Session(struct sess *sp)
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC); CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC);
WS_Assert(w->ws); WS_Assert(w->ws);
AZ(sp->wrk->storage_hint);
switch (sp->step) { switch (sp->step) {
#define STEP(l,u) \ #define STEP(l,u) \
......
...@@ -40,6 +40,7 @@ STEP(lookup, LOOKUP) ...@@ -40,6 +40,7 @@ STEP(lookup, LOOKUP)
STEP(miss, MISS) STEP(miss, MISS)
STEP(hit, HIT) STEP(hit, HIT)
STEP(fetch, FETCH) STEP(fetch, FETCH)
STEP(fetchbody, FETCHBODY)
STEP(deliver, DELIVER) STEP(deliver, DELIVER)
STEP(error, ERROR) STEP(error, ERROR)
STEP(done, DONE) STEP(done, DONE)
......
...@@ -5,14 +5,19 @@ test "Check that max_restarts works and that we don't fall over" ...@@ -5,14 +5,19 @@ test "Check that max_restarts works and that we don't fall over"
server s1 { server s1 {
rxreq rxreq
txresp -body "012345\n" txresp -body "012345\n"
accept
rxreq rxreq
txresp -body "012345\n" txresp -body "012345\n"
accept
rxreq rxreq
txresp -body "012345\n" txresp -body "012345\n"
accept
rxreq rxreq
txresp -body "012345\n" txresp -body "012345\n"
accept
rxreq rxreq
txresp -body "012345\n" txresp -body "012345\n"
accept
rxreq rxreq
txresp -body "012345\n" txresp -body "012345\n"
} -start } -start
......
...@@ -18,12 +18,18 @@ server s1 { ...@@ -18,12 +18,18 @@ server s1 {
rxreq rxreq
txresp -hdr "X-Saint: yes" txresp -hdr "X-Saint: yes"
accept
rxreq rxreq
txresp -hdr "X-Saint: yes" txresp -hdr "X-Saint: yes"
accept
rxreq rxreq
txresp -hdr "X-Saint: yes" txresp -hdr "X-Saint: yes"
accept
rxreq rxreq
txresp -hdr "X-Saint: yes" txresp -hdr "X-Saint: yes"
} -start } -start
......
...@@ -18,12 +18,18 @@ server s1 { ...@@ -18,12 +18,18 @@ server s1 {
rxreq rxreq
txresp -hdr "X-Saint: yes" txresp -hdr "X-Saint: yes"
accept
rxreq rxreq
txresp -hdr "X-Saint: yes" txresp -hdr "X-Saint: yes"
accept
rxreq rxreq
txresp -hdr "X-Saint: yes" txresp -hdr "X-Saint: yes"
accept
rxreq rxreq
txresp -hdr "X-Saint: yes" txresp -hdr "X-Saint: yes"
} -start } -start
......
...@@ -8,6 +8,7 @@ server s1 { ...@@ -8,6 +8,7 @@ server s1 {
expect req.url == "/foo" expect req.url == "/foo"
expect req.http.foobar == "harck-coff" expect req.http.foobar == "harck-coff"
txresp -status 400 txresp -status 400
accept
rxreq rxreq
expect req.url == "/bar" expect req.url == "/bar"
expect req.http.foobar == "snark" expect req.http.foobar == "snark"
......
...@@ -6,6 +6,7 @@ server s1 { ...@@ -6,6 +6,7 @@ server s1 {
rxreq rxreq
expect req.url == "/" expect req.url == "/"
txresp -status 303 -hdr "Location: /foo" txresp -status 303 -hdr "Location: /foo"
accept
rxreq rxreq
expect req.url == "/foo" expect req.url == "/foo"
txresp -body "12345" txresp -body "12345"
......
...@@ -11,6 +11,7 @@ server s1 { ...@@ -11,6 +11,7 @@ server s1 {
rxreq rxreq
expect req.url == "/" expect req.url == "/"
txresp -status 200 -hdr "foo: 2" txresp -status 200 -hdr "foo: 2"
accept
rxreq rxreq
expect req.url == "/" expect req.url == "/"
txresp -status 200 -hdr "foo: 3" txresp -status 200 -hdr "foo: 3"
......
...@@ -76,6 +76,8 @@ struct macro { ...@@ -76,6 +76,8 @@ struct macro {
static VTAILQ_HEAD(,macro) macro_list = VTAILQ_HEAD_INITIALIZER(macro_list); static VTAILQ_HEAD(,macro) macro_list = VTAILQ_HEAD_INITIALIZER(macro_list);
struct _extmacro_list extmacro_list = VTAILQ_HEAD_INITIALIZER(extmacro_list);
static pthread_mutex_t macro_mtx; static pthread_mutex_t macro_mtx;
static void static void
...@@ -479,6 +481,7 @@ exec_file(const char *fn, const char *script, const char *tmpdir, ...@@ -479,6 +481,7 @@ exec_file(const char *fn, const char *script, const char *tmpdir,
char *cwd, *p; char *cwd, *p;
char topbuild[BUFSIZ]; char topbuild[BUFSIZ];
FILE *f; FILE *f;
struct extmacro *m;
vtc_loginit(logbuf, loglen); vtc_loginit(logbuf, loglen);
vltop = vtc_logopen("top"); vltop = vtc_logopen("top");
...@@ -487,6 +490,10 @@ exec_file(const char *fn, const char *script, const char *tmpdir, ...@@ -487,6 +490,10 @@ exec_file(const char *fn, const char *script, const char *tmpdir,
init_macro(); init_macro();
init_sema(); init_sema();
/* Apply extmacro definitions */
VTAILQ_FOREACH(m, &extmacro_list, list)
macro_def(vltop, NULL, m->name, m->val);
/* We are still in bin/varnishtest at this point */ /* We are still in bin/varnishtest at this point */
cwd = getcwd(NULL, PATH_MAX); cwd = getcwd(NULL, PATH_MAX);
bprintf(topbuild, "%s/%s", cwd, TOP_BUILDDIR); bprintf(topbuild, "%s/%s", cwd, TOP_BUILDDIR);
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#ifdef HAVE_PTHREAD_NP_H #ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h> #include <pthread_np.h>
#endif #endif
#include "vqueue.h"
struct vsb; struct vsb;
struct vtclog; struct vtclog;
...@@ -49,6 +50,15 @@ struct cmds { ...@@ -49,6 +50,15 @@ struct cmds {
cmd_f *cmd; cmd_f *cmd;
}; };
struct extmacro {
VTAILQ_ENTRY(extmacro) list;
char *name;
char *val;
};
VTAILQ_HEAD(_extmacro_list, extmacro);
extern struct _extmacro_list extmacro_list;
void parse_string(char *buf, const struct cmds *cmd, void *priv, void parse_string(char *buf, const struct cmds *cmd, void *priv,
struct vtclog *vl); struct vtclog *vl);
......
...@@ -91,6 +91,31 @@ static int vtc_good; ...@@ -91,6 +91,31 @@ static int vtc_good;
static int vtc_fail; static int vtc_fail;
static int leave_temp; static int leave_temp;
/**********************************************************************
* Parse a -D option argument into a name/val pair, and insert
* into extmacro list
*/
static int
parse_D_opt(char *arg)
{
char *p, *q;
struct extmacro *m;
p = arg;
q = strchr(p, '=');
if (!q)
return (0);
*q++ = '\0';
m = calloc(sizeof *m, 1);
AN(m);
REPLACE(m->name, p);
REPLACE(m->val, q);
VTAILQ_INSERT_TAIL(&extmacro_list, m, list);
return (1);
}
/********************************************************************** /**********************************************************************
* Read a file into memory * Read a file into memory
*/ */
...@@ -130,6 +155,7 @@ usage(void) ...@@ -130,6 +155,7 @@ usage(void)
{ {
fprintf(stderr, "usage: varnishtest [options] file ...\n"); fprintf(stderr, "usage: varnishtest [options] file ...\n");
#define FMT " %-28s # %s\n" #define FMT " %-28s # %s\n"
fprintf(stderr, FMT, "-D name=val", "Define macro for use in scripts");
fprintf(stderr, FMT, "-j jobs", "Run this many tests in parallel"); fprintf(stderr, FMT, "-j jobs", "Run this many tests in parallel");
fprintf(stderr, FMT, "-k", "Continue on test failure"); fprintf(stderr, FMT, "-k", "Continue on test failure");
fprintf(stderr, FMT, "-l", "Leave /tmp/vtc.* if test fails"); fprintf(stderr, FMT, "-l", "Leave /tmp/vtc.* if test fails");
...@@ -206,7 +232,7 @@ tst_cb(const struct vev *ve, int what) ...@@ -206,7 +232,7 @@ tst_cb(const struct vev *ve, int what)
jp->tst->filename, t); jp->tst->filename, t);
if (!vtc_continue) { if (!vtc_continue) {
/* XXX kill -9 other jobs ? */ /* XXX kill -9 other jobs ? */
exit (2); exit(2);
} }
} else if (vtc_verbosity) { } else if (vtc_verbosity) {
printf("# top TEST %s passed (%.3f)\n", printf("# top TEST %s passed (%.3f)\n",
...@@ -310,8 +336,15 @@ main(int argc, char * const *argv) ...@@ -310,8 +336,15 @@ main(int argc, char * const *argv)
setbuf(stdout, NULL); setbuf(stdout, NULL);
setbuf(stderr, NULL); setbuf(stderr, NULL);
while ((ch = getopt(argc, argv, "j:klLn:qt:v")) != -1) { while ((ch = getopt(argc, argv, "D:j:klLn:qt:v")) != -1) {
switch (ch) { switch (ch) {
case 'D':
if (!parse_D_opt(optarg)) {
fprintf(stderr, "Cannot parse D opt '%s'\n",
optarg);
exit(2);
}
break;
case 'j': case 'j':
npar = strtoul(optarg, NULL, 0); npar = strtoul(optarg, NULL, 0);
break; break;
...@@ -352,7 +385,7 @@ main(int argc, char * const *argv) ...@@ -352,7 +385,7 @@ main(int argc, char * const *argv)
*argv, strerror(errno)); *argv, strerror(errno));
if (vtc_continue) if (vtc_continue)
continue; continue;
exit (2); exit(2);
} }
ALLOC_OBJ(tp, TST_MAGIC); ALLOC_OBJ(tp, TST_MAGIC);
AN(tp); AN(tp);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment