[master] 0a2c6dad4 vtc: varnish vNAME -expect PATTERN OP PATTERN
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Wed Dec 2 10:43:10 UTC 2020
commit 0a2c6dad4db82008e8bca67f8132589725c8a3e6
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Mon Nov 30 16:06:38 2020 +0100
vtc: varnish vNAME -expect PATTERN OP PATTERN
Make it possible to compare VSCs, to create a synchronization point
based on internal events (especially with custom VSCs).
For example:
# block until baz catches up
varnish v1 -expect FOO.bar == FOO.baz
This is still subject to roughly 5s before timing out.
diff --git a/bin/varnishtest/tests/b00052.vtc b/bin/varnishtest/tests/b00052.vtc
index 23cfcf5de..90cba6988 100644
--- a/bin/varnishtest/tests/b00052.vtc
+++ b/bin/varnishtest/tests/b00052.vtc
@@ -1,23 +1,27 @@
varnishtest "The cache_hit_grace counter"
server s1 {
- # normal fetch
rxreq
expect req.url == "/1"
+ expect req.http.bgfetch == false
txresp -hdr "Age: 1" -hdr "Cache-Control: max-age=2" -body "1"
- # background fetch:
rxreq
expect req.url == "/1"
+ expect req.http.bgfetch == true
txresp -body "2"
- # normal fetch
rxreq
expect req.url == "/2"
+ expect req.http.bgfetch == false
txresp
} -start
-varnish v1 -vcl+backend { } -start
+varnish v1 -vcl+backend {
+ sub vcl_backend_fetch {
+ set bereq.http.bgfetch = bereq.is_bgfetch;
+ }
+} -start
client c1 {
txreq -url "/1"
@@ -35,6 +39,8 @@ client c2 {
expect resp.body == "1"
} -run
+varnish v1 -expect cache_hit >= cache_hit_grace
+
delay 2
client c3 {
@@ -45,6 +51,8 @@ client c3 {
expect resp.body == "2"
} -run
+varnish v1 -expect cache_hit >= cache_hit_grace
+
# Check that counters are correct:
varnish v1 -expect cache_hit == 2
diff --git a/bin/varnishtest/tests/r02946.vtc b/bin/varnishtest/tests/r02946.vtc
index ecda00483..71872679a 100644
--- a/bin/varnishtest/tests/r02946.vtc
+++ b/bin/varnishtest/tests/r02946.vtc
@@ -44,4 +44,5 @@ client c1 {
delay 1
+varnish v1 -expect s_fetch > s_bgfetch
varnish v1 -expect n_objectcore == 1
diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c
index 9912da43b..d1f962919 100644
--- a/bin/varnishtest/vtc_varnish.c
+++ b/bin/varnishtest/vtc_varnish.c
@@ -910,12 +910,29 @@ varnish_vsc(const struct varnish *v, const char *arg)
* Check statistics
*/
+struct stat_arg {
+ const char *pattern;
+ uintmax_t val;
+ unsigned good;
+};
+
struct stat_priv {
- char target_pattern[256];
- uintmax_t val;
- const struct varnish *v;
+ struct stat_arg lhs;
+ struct stat_arg rhs;
};
+static int
+stat_match(const char *pattern, const char *name)
+{
+
+ if (strchr(pattern, '.') == NULL) {
+ if (fnmatch("MAIN.*", name, 0))
+ return (FNM_NOMATCH);
+ name += 5;
+ }
+ return (fnmatch(pattern, name, 0));
+}
+
static int
do_expect_cb(void *priv, const struct VSC_point * const pt)
{
@@ -924,13 +941,24 @@ do_expect_cb(void *priv, const struct VSC_point * const pt)
if (pt == NULL)
return (0);
- if (fnmatch(sp->target_pattern, pt->name, 0))
- return (0);
+ if (!sp->lhs.good && stat_match(sp->lhs.pattern, pt->name) == 0) {
+ AZ(strcmp(pt->ctype, "uint64_t"));
+ AN(pt->ptr);
+ sp->lhs.val = *pt->ptr;
+ sp->lhs.good = 1;
+ }
- AZ(strcmp(pt->ctype, "uint64_t"));
- AN(pt->ptr);
- sp->val = *pt->ptr;
- return (1);
+ if (sp->rhs.pattern == NULL) {
+ sp->rhs.good = 1;
+ } else if (!sp->rhs.good &&
+ stat_match(sp->rhs.pattern, pt->name) == 0) {
+ AZ(strcmp(pt->ctype, "uint64_t"));
+ AN(pt->ptr);
+ sp->rhs.val = *pt->ptr;
+ sp->rhs.good = 1;
+ }
+
+ return (sp->lhs.good && sp->rhs.good);
}
/**********************************************************************
@@ -939,55 +967,49 @@ do_expect_cb(void *priv, const struct VSC_point * const pt)
static void
varnish_expect(const struct varnish *v, char * const *av)
{
- uint64_t ref;
- int good;
- char *r;
- char *p;
- int i, not = 0;
struct stat_priv sp;
-
- r = av[0];
- if (r[0] == '!') {
- not = 1;
- r++;
+ int good, i, not;
+ uintmax_t u;
+ char *l, *p;
+
+ ZERO_OBJ(&sp, sizeof sp);
+ l = av[0];
+ not = (*l == '!');
+ if (not) {
+ l++;
AZ(av[1]);
} else {
AN(av[1]);
AN(av[2]);
- }
- p = strrchr(r, '.');
- if (p == NULL) {
- bprintf(sp.target_pattern, "MAIN.%s", r);
- } else {
- bprintf(sp.target_pattern, "%s", r);
+ u = strtoumax(av[2], &p, 0);
+ if (u != UINTMAX_MAX && *p == '\0')
+ sp.rhs.val = u;
+ else
+ sp.rhs.pattern = av[2];
}
- sp.val = 0;
- sp.v = v;
- ref = 0;
- good = 0;
+ sp.lhs.pattern = l;
+
for (i = 0; i < 50; i++, (void)usleep(100000)) {
(void)VSM_Status(v->vsm_vsc);
+ sp.lhs.good = sp.rhs.good = 0;
good = VSC_Iter(v->vsc, v->vsm_vsc, do_expect_cb, &sp);
- if (!good) {
+ if (!good)
good = -2;
+ if (good < 0)
continue;
- }
if (not)
- vtc_fatal(v->vl, "Found (not expected): %s", av[0]+1);
-
- good = 0;
- ref = strtoumax(av[2], &p, 0);
- if (ref == UINTMAX_MAX || *p)
- vtc_fatal(v->vl, "Syntax error in number (%s)", av[2]);
- if (!strcmp(av[1], "==")) { if (sp.val == ref) good = 1; }
- else if (!strcmp(av[1], "!=")) { if (sp.val != ref) good = 1; }
- else if (!strcmp(av[1], ">")) { if (sp.val > ref) good = 1; }
- else if (!strcmp(av[1], "<")) { if (sp.val < ref) good = 1; }
- else if (!strcmp(av[1], ">=")) { if (sp.val >= ref) good = 1; }
- else if (!strcmp(av[1], "<=")) { if (sp.val <= ref) good = 1; }
- else
+ vtc_fatal(v->vl, "Found (not expected): %s", l);
+
+ good = -1;
+ if (!strcmp(av[1], "==")) good = (sp.lhs.val == sp.rhs.val);
+ if (!strcmp(av[1], "!=")) good = (sp.lhs.val != sp.rhs.val);
+ if (!strcmp(av[1], ">" )) good = (sp.lhs.val > sp.rhs.val);
+ if (!strcmp(av[1], "<" )) good = (sp.lhs.val < sp.rhs.val);
+ if (!strcmp(av[1], ">=")) good = (sp.lhs.val >= sp.rhs.val);
+ if (!strcmp(av[1], "<=")) good = (sp.lhs.val <= sp.rhs.val);
+ if (good == -1)
vtc_fatal(v->vl, "comparison %s unknown", av[1]);
if (good)
break;
@@ -997,19 +1019,19 @@ varnish_expect(const struct varnish *v, char * const *av)
}
if (good == -2) {
if (not) {
- vtc_log(v->vl, 2, "not found (as expected): %s",
- av[0] + 1);
+ vtc_log(v->vl, 2, "not found (as expected): %s", l);
return;
}
- vtc_fatal(v->vl, "stats field %s unknown", av[0]);
+ vtc_fatal(v->vl, "stats field %s unknown",
+ sp.lhs.good ? sp.rhs.pattern : sp.lhs.pattern);
}
if (good == 1) {
- vtc_log(v->vl, 2, "as expected: %s (%ju) %s %s",
- av[0], sp.val, av[1], av[2]);
+ vtc_log(v->vl, 2, "as expected: %s (%ju) %s %s (%ju)",
+ av[0], sp.lhs.val, av[1], av[2], sp.rhs.val);
} else {
vtc_fatal(v->vl, "Not true: %s (%ju) %s %s (%ju)",
- av[0], (uintmax_t)sp.val, av[1], av[2], (uintmax_t)ref);
+ av[0], sp.lhs.val, av[1], av[2], sp.rhs.val);
}
}
@@ -1091,11 +1113,14 @@ varnish_expect(const struct varnish *v, char * const *av)
* Once Varnish is stopped, clean everything after it. This is only used
* in very few tests and you should never need it.
*
+ * \-expectexit NUMBER
+ * Expect varnishd to exit(3) with this value
+ *
* Once Varnish is started, you can talk to it (as you would through
* ``varnishadm``) with these additional switches::
*
* varnish vNAME [-cli STRING] [-cliok STRING] [-clierr STRING]
- * [-clijson STRING] [-expect STRING OP NUMBER]
+ * [-clijson STRING]
*
* \-cli STRING|-cliok STRING|-clierr STATUS STRING|-cliexpect REGEXP STRING
* All four of these will send STRING to the CLI, the only difference
@@ -1107,14 +1132,22 @@ varnish_expect(const struct varnish *v, char * const *av)
* Send STRING to the CLI, expect success (CLIS_OK/200) and check
* that the response is parsable JSON.
*
- * \-expect PATTERN OP NUMBER
+ * It is also possible to interact with its shared memory (as you would
+ * through tools like ``varnishstat``) with additional switches:
+ *
+ * \-expect \!PATTERN|PATTERN OP NUMBER|PATTERN OP PATTERN
* Look into the VSM and make sure the first VSC counter identified by
* PATTERN has a correct value. OP can be ==, >, >=, <, <=. For
* example::
*
* varnish v1 -expect SM?.s1.g_space > 1000000
- * \-expectexit NUMBER
- * Expect varnishd to exit(3) with this value
+ * varnish v1 -expect cache_hit >= cache_hit_grace
+ *
+ * In the \! form the test fails if a counter matches PATTERN.
+ *
+ * The ``MAIN.`` namespace can be omitted from PATTERN.
+ *
+ * The test takes up to 5 seconds before timing out.
*
* \-vsc PATTERN
* Dump VSC counters matching PATTERN.
More information about the varnish-commit
mailing list