[master] d89c8bf59 Test per-instance PRIV_TASK
Nils Goroll
nils.goroll at uplex.de
Tue Jan 12 15:30:08 UTC 2021
commit d89c8bf59b9da8263f1a767c68e4ee35d2569d11
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Tue Jan 12 16:24:27 2021 +0100
Test per-instance PRIV_TASK
this is how we have been using VRT_priv_task() for long. Before making
it the official way, bring vmod_debug and our own tests in sync.
This tests
- that PRIV_TASK is different for client and backend side
- that vcl_pipe is client side wrt PRIV_TASK
- that finalizers are called
and probably things I forgot.
diff --git a/bin/varnishtest/tests/v00041.vtc b/bin/varnishtest/tests/v00041.vtc
index ce162378e..a01903b53 100644
--- a/bin/varnishtest/tests/v00041.vtc
+++ b/bin/varnishtest/tests/v00041.vtc
@@ -20,35 +20,51 @@ varnish v1 -arg "-p debug=+vclrel -p workspace_client=1m" -vcl+backend {
import std;
sub vcl_init {
- new objx = debug.obj();
+ new objc = debug.obj();
+ new objb = debug.obj();
+ }
+
+ sub log_obj {
+ std.log("objc " + objc.test_priv_task());
+ std.log("objb " + objb.test_priv_task());
}
sub vcl_init {
debug.test_priv_task("something");
debug.test_priv_task("to remember");
std.log("func " + debug.test_priv_task());
- std.log("obj " + objx.test_priv_task());
+ objc.test_priv_task("initX");
+ objb.test_priv_task("initY");
+ call log_obj;
}
sub vcl_recv {
if (req.url == "/perf") {
return (synth(200));
}
- if (req.url == "/pipe") {
- return (pipe);
- }
debug.test_priv_task(req.url);
set req.http.x0 = debug.test_priv_task();
debug.test_priv_task("bazz");
+ call log_obj;
+ objc.test_priv_task("c" + req.xid);
+ if (req.url == "/pipe") {
+ return (pipe);
+ }
}
sub vcl_pipe {
+ call log_obj;
+ objc.test_priv_task("p" + req.xid);
+
debug.test_priv_task(req.url);
set req.http.x0 = debug.test_priv_task();
debug.test_priv_task("bazz");
}
sub vcl_synth {
+ call log_obj;
+ objc.test_priv_task("s" + req.xid);
+
std.log("discard 1000 " + debug.priv_perf(1000));
std.log("perf 1 " + debug.priv_perf(1));
std.log("perf 10 " + debug.priv_perf(10));
@@ -58,66 +74,156 @@ varnish v1 -arg "-p debug=+vclrel -p workspace_client=1m" -vcl+backend {
}
sub vcl_deliver {
+ call log_obj;
+ objc.test_priv_task("d" + req.xid);
+
set resp.http.x0 = req.http.x0;
set resp.http.x1 = debug.test_priv_task();
- set resp.http.o1 = objx.test_priv_task();
+ set resp.http.objc = objc.test_priv_task();
}
sub vcl_backend_fetch {
- objx.test_priv_task("b");
- std.log("foo");
+ call log_obj;
+ objb.test_priv_task("f" + bereq.xid);
+
+ debug.test_priv_task("b");
set bereq.http.bx0 = debug.test_priv_task(bereq.url);
- std.log("bar");
}
sub vcl_backend_response {
+ call log_obj;
+ objb.test_priv_task("r" + bereq.xid);
+
set beresp.http.bx0 = bereq.http.bx0;
set beresp.http.bx1 = debug.test_priv_task("");
- set beresp.http.bo1 = objx.test_priv_task("");
+ set beresp.http.objb = objb.test_priv_task("");
}
sub vcl_fini {
debug.test_priv_task("cleaning");
debug.test_priv_task("up");
std.log("func " + debug.test_priv_task());
- std.log("obj " + objx.test_priv_task());
+ std.log("obj " + objc.test_priv_task());
}
} -start
-logexpect l1 -v v1 -g raw -d 1 {
+logexpect l0 -v v1 -g raw -d 1 -q "vxid == 0 and not ExpKill" {
expect 0 0 CLI {^Rd vcl.load}
expect 0 = Debug {^test_priv_task.*new.$}
expect 0 = Debug {^test_priv_task.*update.$}
expect 0 = Debug {^test_priv_task.*exists.$}
expect 0 = VCL_Log {^func something to remember}
- expect 0 = Debug {^test_priv_task.*exists.$}
- expect 0 = VCL_Log {^obj something to remember}
+ expect 0 = Debug {^objc.priv_task.. = .*"initX". .new.}
+ expect 0 = Debug {^objb.priv_task.. = .*"initY". .new.}
+ expect 0 = Debug {^objc.priv_task.. = .*"initX"}
+ expect 0 = VCL_Log {^objc initX}
+ expect 0 = Debug {^objb.priv_task.. = .*"initY"}
+ expect 0 = VCL_Log {^objb initY}
+ expect 0 = Debug {^priv_task_free}
+ expect 0 = Debug {^obj_priv_task_fini.*"initX"}
+ expect 0 = Debug {^obj_priv_task_fini.*"initY"}
+ expect 0 = Debug {^vcl1: VCL_EVENT_WARM}
- expect * 1002 Begin fetch$
- expect * = VCL_call ^BACKEND_FETCH
- expect 0 = VCL_Log ^foo
- expect 0 = BereqHeader {^bx0: b /foobar}
- expect 0 = VCL_Log ^bar
-
- expect * 1004 Begin fetch$
- expect * = VCL_call ^BACKEND_FETCH
- expect 0 = VCL_Log ^foo
- expect 0 = BereqHeader {^bx0: b /snafu}
- expect 0 = VCL_Log ^bar
-
- # this is not the order of events because std.log logs
- # into the CLI ctx->vsl, while vmod_debug VSL() goes straight
- # to the log.
- expect * 0 Debug {^vcl1: VCL_EVENT_COLD}
- expect * 0 CLI {^Rd vcl.discard}
+ # 1001/1002
+ expect * = Debug {^test_priv_task.*new.$}
+ expect 0 = Debug {^test_priv_task.*exists.$}
+ expect 0 = Debug {^test_priv_task.*update.$}
expect 0 = Debug {^test_priv_task.*new.$}
expect 0 = Debug {^test_priv_task.*update.$}
expect 0 = Debug {^test_priv_task.*exists.$}
+ expect 0 = Debug {^priv_task_free}
+ expect 0 = Debug {^obj_priv_task_fini.*"r1002"}
+ expect 0 = Debug {^test_priv_task.*exists}
+ expect 0 = Debug {^priv_task_free}
+ expect 0 = Debug {^obj_priv_task_fini.*"d1001"}
+
+ # ...
+ # 1006 pipe
+ expect * = Debug {^obj_priv_task_fini.*"p1006"}
+
+ # vcl_fini
+ expect * = Debug {^vcl1: VCL_EVENT_COLD}
+ expect 0 = CLI {^Wr 200 0 }
+ expect 0 = CLI {^Rd vcl.discard vcl1}
+ expect 0 = Debug {^test_priv_task.*new.$}
+ expect 0 = Debug {^test_priv_task.*update.$}
expect 0 = Debug {^test_priv_task.*exists.$}
expect 0 = Debug {^priv_task_free}
- expect * = VCL_Log {^func cleaning up}
- expect 0 = VCL_Log {^obj cleaning up}
+ expect 0 = VCL_Log {^func cleaning up}
+ expect 0 = Debug {^objc.priv_task.. = NULL}
+ expect 0 = VCL_Log {^obj }
+ expect 0 = CLI {^Wr 200 0 }
+} -start
+
+logexpect l1001 -v v1 -g vxid -q "vxid == 1001" {
+ expect * 1001 VCL_call {^RECV}
+ expect 0 = ReqHeader {^x0: /foobar}
+ expect 0 = Debug {^objc.priv_task.. = NULL}
+ expect 0 = VCL_Log {^objc }
+ expect 0 = Debug {^objb.priv_task.. = NULL}
+ expect 0 = VCL_Log {^objb }
+ expect 0 = Debug {^objc.priv_task.. =.*"c1001". .new.}
+
+ expect * = VCL_call {^DELIVER}
+ expect 0 = Debug {^objc.priv_task.. =.*"c1001".}
+ expect 0 = VCL_Log {^objc c1001}
+ expect 0 = Debug {^objb.priv_task.. = NULL}
+ expect 0 = VCL_Log {^objb }
+ expect 0 = Debug {^objc.priv_task.. =.*"d1001". .update.}
+ expect 0 = RespHeader {^x0: /foobar}
+ expect 0 = RespHeader {^x1: /foobar bazz}
+ expect 0 = Debug {^objc.priv_task.. =.*"d1001".}
+ expect 0 = RespHeader {^objc: d1001}
+ expect 0 = VCL_return {^deliver}
+} -start
+
+logexpect l1002 -v v1 -g vxid -q "vxid == 1002" {
+ expect * 1002 VCL_call {^BACKEND_FETCH}
+ expect 0 = Debug {^objc.priv_task.. = NULL}
+ expect 0 = VCL_Log {^objc }
+ expect 0 = Debug {^objb.priv_task.. = NULL}
+ expect 0 = VCL_Log {^objb }
+ expect 0 = Debug {^objb.priv_task.. =.*"f1002". .new.}
+ expect 0 = BereqHeader {^bx0: b /foobar}
+ expect 0 = VCL_return {^fetch}
+
+ expect * = VCL_call {^BACKEND_RESPONSE}
+ expect 0 = Debug {^objc.priv_task.. = NULL}
+ expect 0 = VCL_Log {^objc }
+ expect 0 = Debug {^objb.priv_task.. =.*"f1002".}
+ expect 0 = VCL_Log {^objb f1002}
+ expect 0 = Debug {^objb.priv_task.. =.*"r1002". .update.}
+ expect 0 = BerespHeader {^bx0: b /foobar}
+ expect 0 = BerespHeader {^bx1: b /foobar}
+ expect 0 = Debug {^objb.priv_task.. =.*"r1002".}
+ expect 0 = BerespHeader {^objb: r1002}
+ expect 0 = VCL_return {^deliver}
+} -start
+
+logexpect l1006 -v v1 -g vxid -q "vxid == 1006" {
+ expect * 1006 VCL_call {^RECV}
+ expect 0 = ReqHeader {^x0: /pipe}
+ expect 0 = Debug {^objc.priv_task.. = NULL}
+ expect 0 = VCL_Log {^objc }
+ expect 0 = Debug {^objb.priv_task.. = NULL}
+ expect 0 = VCL_Log {^objb }
+ expect 0 = Debug {^objc.priv_task.. =.*"c1006". .new.}
+ expect 0 = VCL_return {^pipe}
+
+ expect 0 = VCL_call {^HASH}
+ expect 0 = VCL_return {^lookup}
+
+ expect 0 = Link {^bereq 1007 pipe}
+ expect 0 = VCL_call {^PIPE}
+ expect 0 = Debug {^objc.priv_task.. =.*"c1006".}
+ expect 0 = VCL_Log {^objc c1006}
+ expect 0 = Debug {^objb.priv_task.. = NULL}
+ expect 0 = VCL_Log {^objb }
+ expect 0 = Debug {^objc.priv_task.. =.*"p1006". .update.}
+ expect 0 = ReqUnset {^x0: /pipe}
+ expect 0 = ReqHeader {^x0: /pipe bazz /pipe}
+ expect 0 = VCL_return {^pipe}
} -start
client c1 {
@@ -125,19 +231,19 @@ client c1 {
rxresp
expect resp.http.x0 == /foobar
expect resp.http.x1 == "/foobar bazz"
- expect resp.http.o1 == "/foobar bazz"
+ expect resp.http.objc == "d1001"
expect resp.http.bx0 == "b /foobar"
expect resp.http.bx1 == "b /foobar"
- expect resp.http.bo1 == "b /foobar"
+ expect resp.http.objb == "r1002"
txreq -url /snafu
rxresp
expect resp.http.x0 == /snafu
expect resp.http.x1 == "/snafu bazz"
- expect resp.http.o1 == "/snafu bazz"
+ expect resp.http.objc == "d1003"
expect resp.http.bx0 == "b /snafu"
expect resp.http.bx1 == "b /snafu"
- expect resp.http.bo1 == "b /snafu"
+ expect resp.http.objb == "r1004"
txreq -url /perf
rxresp
@@ -161,4 +267,7 @@ client c1 {
varnish v1 -cliok "vcl.list"
-logexpect l1 -wait
+logexpect l0 -wait
+logexpect l1001 -wait
+logexpect l1002 -wait
+logexpect l1006 -wait
diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c
index bb663ea94..2be114a4f 100644
--- a/vmod/vmod_debug.c
+++ b/vmod/vmod_debug.c
@@ -64,6 +64,7 @@ static struct VSC_debug *vsc = NULL;
static int loads;
static const int store_ip_token;
static const int fail_rollback_token;
+extern void mylog(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...);
/**********************************************************************/
@@ -819,8 +820,7 @@ xyzzy_sethdr(VRT_CTX, VCL_HEADER hs, VCL_STRANDS s)
}
}
-// coverage
-static void
+void
mylog(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...)
{
va_list ap;
diff --git a/vmod/vmod_debug.vcc b/vmod/vmod_debug.vcc
index fa81c8cf8..a787bb2c8 100644
--- a/vmod/vmod_debug.vcc
+++ b/vmod/vmod_debug.vcc
@@ -112,12 +112,9 @@ Test method for VCL private pointers
Objects share the ``PRIV_*`` state with other objects and methods from
the same vmod - IOW the ``PRIV_*`` state is per vmod, not per object.
-$Method STRING .test_priv_task(PRIV_TASK, STRING s="")
+$Method STRING .test_priv_task(STRING s="")
-Test method for TASK private pointers
-
-Objects share the ``PRIV_*`` state with other objects and methods from
-the same vmod - IOW the ``PRIV_*`` state is per vmod, not per object.
+Test per-object priv_task via VRT_priv_task() / VRT_priv_get()
$Method STRING .test_priv_top(PRIV_TOP, STRING)
diff --git a/vmod/vmod_debug_obj.c b/vmod/vmod_debug_obj.c
index 8bc328290..1ccb2f826 100644
--- a/vmod/vmod_debug_obj.c
+++ b/vmod/vmod_debug_obj.c
@@ -37,12 +37,16 @@
#include "vcc_debug_if.h"
+// vmod_debug.c
+extern void mylog(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...);
+
struct xyzzy_debug_obj {
unsigned magic;
#define VMOD_DEBUG_OBJ_MAGIC 0xccbd9b77
int foobar;
const char *string;
const char *number;
+ VCL_STRING vcl_name;
};
VCL_VOID
@@ -52,7 +56,6 @@ xyzzy_obj__init(VRT_CTX, struct xyzzy_debug_obj **op,
struct xyzzy_debug_obj *o;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
- (void)vcl_name;
AN(op);
AZ(*op);
ALLOC_OBJ(o, VMOD_DEBUG_OBJ_MAGIC);
@@ -61,6 +64,7 @@ xyzzy_obj__init(VRT_CTX, struct xyzzy_debug_obj **op,
o->foobar = 42;
o->string = s;
o->number = e;
+ o->vcl_name = vcl_name;
AN(*op);
}
@@ -147,12 +151,55 @@ xyzzy_obj_test_priv_vcl(VRT_CTX,
xyzzy_test_priv_vcl(ctx, priv);
}
+static void
+obj_priv_task_fini(void *ptr)
+{
+ AN(ptr);
+ VSL(SLT_Debug, 0, "obj_priv_task_fini(%p = \"%s\")", ptr, ptr);
+}
+
+static const struct vmod_priv_methods xyzzy_obj_test_priv_task_methods[1] = {{
+ .magic = VMOD_PRIV_METHODS_MAGIC,
+ .type = "debug_onk_test_priv_task",
+ .fini = obj_priv_task_fini
+}};
+
VCL_STRING v_matchproto_()
-xyzzy_obj_test_priv_task(VRT_CTX,
- struct xyzzy_debug_obj *o, struct vmod_priv *priv, VCL_STRING s)
+xyzzy_obj_test_priv_task(VRT_CTX, struct xyzzy_debug_obj *o, VCL_STRING s)
{
- (void)o;
- return (xyzzy_test_priv_task(ctx, priv, s));
+ struct vmod_priv *p;
+
+ if (s == NULL || *s == '\0') {
+ p = VRT_priv_task_get(ctx, o);
+ if (p == NULL) {
+ mylog(ctx->vsl, SLT_Debug, "%s.priv_task() = NULL",
+ o->vcl_name);
+ return ("");
+ }
+ mylog(ctx->vsl, SLT_Debug,
+ "%s.priv_task() = %p .priv = %p (\"%s\")",
+ o->vcl_name, p, p->priv, p->priv);
+ return (p->priv);
+ }
+
+ p = VRT_priv_task(ctx, o);
+
+ if (p == NULL) {
+ mylog(ctx->vsl, SLT_Debug, "%s.priv_task() = NULL [err]",
+ o->vcl_name);
+ VRT_fail(ctx, "no priv task - out of ws?");
+ return ("");
+ }
+
+ mylog(ctx->vsl, SLT_Debug,
+ "%s.priv_task() = %p .priv = %p (\"%s\") [%s]",
+ o->vcl_name, p, s, s, p->priv ? "update" : "new");
+
+ /* minimum scope of s and priv is the task - no need to copy */
+ p->priv = TRUST_ME(s);
+ p->methods = xyzzy_obj_test_priv_task_methods;
+
+ return (p->priv);
}
VCL_STRING v_matchproto_()
More information about the varnish-commit
mailing list