diff --git a/main.c b/main.c index 7b5962c..1052dd9 100644 --- a/main.c +++ b/main.c @@ -149,8 +149,83 @@ flushout(struct VUT *v) return (0); } +static int process_probe(struct VSL_data *vsl, + struct VSL_transaction * const trans[], void *priv) +{ + cJSON *t= NULL; + double duration; + const uint32_t *p; + enum VSL_tag_e tag; + const char *data, *c; + struct VSL_transaction *tp = NULL; + + (void)vsl; + (void)priv; + + AN(trans); + AN(trans[0]); + AZ(trans[1]); + tp = trans[0]; + + t = cJSON_CreateObject(); + + AN(VSL_Next(tp->c)); + p = tp->c->rec.ptr; + tag = VSL_TAG(p); + if (tag != SLT_Backend_health) { + return (0); + } + data = VSL_CDATA(p); + + tok_init(&c, data); + AN(tok_next(&c, vsb)); + cJSON_AddStringToObject(t, "backend", VSB_data(vsb)); + AN(tok_next(&c, vsb)); + AN(tok_next(&c, vsb)); + if (strcmp(VSB_data(vsb), "healthy")) { + cJSON_AddBoolToObject(t, "healthy", false); + } else { + cJSON_AddBoolToObject(t, "healthy", true); + } + AN(tok_next(&c, vsb)); + assert(strlen(VSB_data(vsb)) == 8); + if (VSB_data(vsb)[7] == 'H') { + cJSON_AddBoolToObject(t, "happy", true); + } else { + cJSON_AddBoolToObject(t, "happy", false); + } + cJSON_AddStringToObject(t, "report", VSB_data(vsb)); + + AN(tok_next(&c, vsb)); + AN(tok_next(&c, vsb)); + AN(tok_next(&c, vsb)); + AN(tok_next(&c, vsb)); + duration = strtod(VSB_data(vsb), NULL); + cJSON_AddNumberToObject(t, "duration", duration); + + AN(tok_next(&c, vsb)); + while (!isspace(*c)) { + c++; + } + c++; + cJSON_AddRawToObject(t, "message", c); + + AZ(VSL_Next(tp->c)); + + char *s; + if (pretty) + s = cJSON_Print(t); + else + s = cJSON_PrintUnformatted(t); + printf("%s\n", s); + free(s); + cJSON_Delete(t); + + return (0); +} + static int process_group(struct VSL_data *vsl, - struct VSL_transaction * const trans[], void *priv) + struct VSL_transaction * const trans[], void *priv) { int i; bool req_done, resp_done; @@ -516,7 +591,7 @@ usage(int status) int main(int argc, char **argv) { - int opt; + int opt, probe = false; bool bc_set = false; vut = VUT_InitProg(argc, argv, &vopt_spec); @@ -533,16 +608,20 @@ int main(int argc, char **argv) AN(VUT_Arg(vut, opt, NULL)); break; case 'g': - if (!strcmp("vxid", optarg)) + probe = false; + if (!strcmp("vxid", optarg)) { arrays = false; - else if (!strcmp("request", optarg)) + VUT_Arg(vut, opt, optarg); + } else if (!strcmp("request", optarg)) { arrays = true; - else { + VUT_Arg(vut, opt, optarg); + } else if (!strcmp("probe", optarg)) { + probe = true; + VUT_Arg(vut, opt, "raw"); + } else { printf("Error: -g only supports \"vxid\" and \"request\"\n\n"); VUT_Usage(vut, &vopt_spec, 1); } - arrays = strcmp("vxid", optarg); - VUT_Arg(vut, opt, optarg); break; case 'h': VUT_Usage(vut, &vopt_spec, 0); @@ -582,7 +661,11 @@ int main(int argc, char **argv) LOG.fo = stdout; - vut->dispatch_f = process_group; + if (probe) { + vut->dispatch_f = process_probe; + } else { + vut->dispatch_f = process_group; + } vut->idle_f = flushout; vsb = VSB_new_auto();; diff --git a/tests/005.vtc b/tests/005.vtc new file mode 100644 index 0000000..052eaea --- /dev/null +++ b/tests/005.vtc @@ -0,0 +1,63 @@ +varnishtest "probe" + +feature cmd jq + +server s1 { + rxreq + delay 0.1 + txresp -hdr "connection: close" + + accept + + rxreq + txresp -status 400 -hdr "connection: close" + + accept + + rxreq + txresp -status 400 -hdr "connection: close" +} -start + +varnish v1 -vcl { + backend s1 { + .host = "${s1_sock}"; + .probe = { + .url = "/"; + .window = 2; + .threshold = 1; + .interval = 0.2s; + } + } +} -start + +server s1 -wait + +shell { + # arguments: LINE FIELD VALUE + t() { + set -ex + test "$(${varnishlog-json_bin} -n ${v1_name} -d -g probe | awk "NR == $1" | jq -r ".$2" )" = "$3" + } + + varnishlog -n ${v1_name} -g raw -d + ${varnishlog-json_bin} -n ${v1_name} -d -g probe + + # start at 3, we have 2 initial probes + t 3 backend s1 + t 3 healthy true + t 3 happy true + t 3 report 4---X-RH + t 3 message "HTTP/1.1 200 OK" + + t 4 backend s1 + t 4 healthy true + t 4 happy false + t 4 report 4---X-R- + t 4 message "HTTP/1.1 400 OK" + + t 5 backend s1 + t 5 healthy false + t 5 happy false + t 5 report 4---X-R- + t 5 message "HTTP/1.1 400 OK" +}