varnishtest "Test priv_task"

feature !sanitizer

server s1 {
	rxreq
	txresp
	rxreq
	txresp

	rxreq
	txresp
	expect_close
	accept

	rxreq
	txresp
} -start

varnish v1 -arg "-p debug=+vclrel -p workspace_client=1m" -vcl+backend {
	import debug;
	import std;

	sub vcl_init {
		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());
		objc.test_priv_task("initX");
		objb.test_priv_task("initY");
		call log_obj;
	}

	sub vcl_recv {
		if (req.url == "/perf") {
			return (synth(200));
		}
		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));
		std.log("perf  100 " + debug.priv_perf(100));
		// std.log("perf 1000 " + debug.priv_perf(1000));
		return (deliver);
	}

	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.objc = objc.test_priv_task();
	}

	sub vcl_backend_fetch {
		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);
	}

	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.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 "  + objc.test_priv_task());
	}

} -start

logexpect l0 -v v1 -g raw -d 1 -m -q "vxid == 0" {
	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		{^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 ? =    Debug		{^priv_task_fini}
	expect ? =    Debug		{^obj_priv_task_fini}
	expect ? =    Debug		{^obj_priv_task_fini}
	expect 0 =    Debug		{^vcl1: VCL_EVENT_WARM}

	# need an anchor for the ? expects to begin
	expect * =    CLI               {^Rd debug.xid}
	expect 0 =    CLI               {^Wr 200}
	expect 0 =    CLI               {^Rd debug.listen_address}
	expect 0 =    CLI               {^Wr 200}

	# ...
	# 1006 pipe

	# vcl_fini
	expect * =    Debug		{^vcl1: VCL_EVENT_COLD}
	expect 0 =    CLI		{^Wr 200 0 }
	expect 0 =    CLI		{^Rd vcl.discard vcl1}
	expect ? =    Debug		{^test_priv_task.*new.$}
	expect ? =    Debug		{^test_priv_task.*update.$}
	expect ? =    Debug		{^test_priv_task.*exists.$}
	expect ? =    Debug		{^objc.priv_task.. = NULL}
	expect ? =    Debug		{^priv_task_fini}
	expect ? =    VCL_Log		{^func cleaning up}
	expect ? =    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 =    Debug		{^test_priv_task.*new.$}
	expect 0 =    Debug		{^test_priv_task.*exists.$}
	expect 0 =    ReqHeader		{^x0: /foobar}
	expect 0 =    Debug		{^test_priv_task.*update.$}
	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 =    Debug		{^test_priv_task.*exists.$}
	expect 0 =    RespHeader	{^x1: /foobar bazz}
	expect 0 =    Debug		{^objc.priv_task.. =.*"d1001".}
	expect 0 =    RespHeader	{^objc: d1001}
	expect 0 =    VCL_return	{^deliver}
	expect 9 =    Timestamp	{^Resp}
	expect ? =    Debug		{^priv_task_fini}
	expect ? =    Debug		{^obj_priv_task_fini}
} -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 =    Debug		{^test_priv_task.*new.$}
	expect 0 =    Debug		{^test_priv_task.*update.$}
	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 =    Debug		{^test_priv_task.*exists.$}
	expect 0 =    BerespHeader	{^bx1: b /foobar}
	expect 0 =    Debug		{^objb.priv_task.. =.*"r1002".}
	expect 0 =    BerespHeader	{^objb: r1002}
	expect 0 =    VCL_return	{^deliver}
	expect 9 =    Timestamp	{^BerespBody}
	expect ? =    Debug		{^priv_task_fini}
	expect ? =    Debug		{^obj_priv_task_fini}
} -start

logexpect l1006 -v v1 -g vxid -q "vxid == 1006" {
	expect * 1006 VCL_call		{^RECV}
	expect 0 =    Debug		{^test_priv_task.*new.$}
	expect 0 =    Debug		{^test_priv_task.*exists.$}
	expect 0 =    ReqHeader		{^x0: /pipe}
	expect 0 =    Debug		{^test_priv_task.*update.$}
	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 =    Debug		{^test_priv_task.*update.$}
	expect 0 =    Debug		{^test_priv_task.*exists.$}
	expect 0 =    ReqUnset		{^x0: /pipe}
	expect 0 =    ReqHeader		{^x0: /pipe bazz /pipe}
	expect 0 =    Debug		{^test_priv_task.*update.$}
	expect 0 =    VCL_return	{^pipe}
	expect 4 =    PipeAcct
	expect ? =    Debug		{^priv_task_fini}
	expect ? =    Debug		{^obj_priv_task_fini}
} -start

client c1 {
	txreq -url /foobar
	rxresp
	expect resp.http.x0 == /foobar
	expect resp.http.x1 == "/foobar bazz"
	expect resp.http.objc == "d1001"
	expect resp.http.bx0 == "b /foobar"
	expect resp.http.bx1 == "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.objc == "d1003"
	expect resp.http.bx0 == "b /snafu"
	expect resp.http.bx1 == "b /snafu"
	expect resp.http.objb == "r1004"

	txreq -url /perf
	rxresp

	txreq -url /pipe
	rxresp
} -run

shell "echo 'vcl 4.0; backend foo { .host = \"${s1_addr}\"; .port = \"${s1_port}\"; }' > ${tmpdir}/_b00014.vcl"

varnish v1 -cliok "vcl.load foo ${tmpdir}/_b00014.vcl" \
	-cliok "vcl.use foo" \
	-cliok "vcl.list" \
	-cliok "vcl.discard vcl1" \
	-cliok "vcl.list"

client c1 {
	txreq -url /foo
	rxresp
} -run

varnish v1 -cliok "vcl.list"

logexpect l0 -wait
logexpect l1001 -wait
logexpect l1002 -wait
logexpect l1006 -wait
