We are in upgrading from Varnish 3 to Varnish 4.1 and we have experienced a problem when comparing 'bereq.backend' or 'req.backend_hint' to a director or a backend.

We created Varnish Test Cases to demonstrate this behavior.

In Varnish 3 this tests runs successfully:

------------------------------------------------------------------------------------------------------
varnishtest "Test backends and directors"

server s1 {
  rxreq
  txresp -status 200
} -start


varnish v1 -vcl {
  backend b_1 {
    .host = "${s1_addr}";
    .port = "${s1_port}";
  }

  director d1 round-robin {
    { .backend = b_1; }
  }

  sub vcl_recv {
    set req.backend = d1;
  }

  sub vcl_fetch {
    if ( req.backend == d1 ) {
      set beresp.http.X-Backend-Fetch = "d1";
    }
  }

  sub vcl_deliver {
    if ( req.backend == d1 ) {
      set resp.http.X-Backend-Deliver = "d1";
    }
  }

} -start

client c1 {
  txreq
  rxresp
  expect resp.status == 200
  expect resp.http.X-Backend-Fetch == "d1"
  expect resp.http.X-Backend-Deliver == "d1"
} -run
------------------------------------------------------------------------------------------------------

In Varnish 4 the following adapted test:

------------------------------------------------------------------------------------------------------
varnishtest "Test backends and directors"

server s1 {
  rxreq
  txresp -status 200
} -start


varnish v1 -vcl {
  import std;
  import directors;
  backend b1 {
    .host = "${s1_addr}";
    .port = "${s1_port}";
  }

  sub vcl_init {
    new d1 = directors.round_robin();
    d1.add_backend(b1);
  }

  sub vcl_recv {
    set req.backend_hint = d1.backend();
  }

  sub vcl_backend_response {
    if ( bereq.backend == d1 ) {
      set beresp.http.X-Backend-Response = "d1";
    }
  }

  sub vcl_deliver {
    if ( req.backend_hint == d1 ) {
      set resp.http.X-Backend-Deliver = "d1";
    }
  }

} -start

client c1 {
  txreq
  rxresp
  expect resp.status == 200
  expect resp.http.X-Backend-Response == "d1"
  expect resp.http.X-Backend-Deliver == "d1"
} -run
------------------------------------------------------------------------------------------------------

fails with this message:

**** v1    0.4 CLI RX| Message from VCC-compiler:\n
**** v1    0.4 CLI RX| Backend not found: 'd1'\n
**** v1    0.4 CLI RX| ('<vcl.inline>' Line 21 Pos 27)\n
**** v1    0.4 CLI RX|     if ( bereq.backend == d1 ) {\n
**** v1    0.4 CLI RX| --------------------------##----\n

and when we comment out the 'vcl_backend_response' sub it fails with this message:

**** v1    0.5 CLI RX| Message from VCC-compiler:\n
**** v1    0.5 CLI RX| Backend not found: 'd1'\n
**** v1    0.5 CLI RX| ('<vcl.inline>' Line 28 Pos 30)\n
**** v1    0.5 CLI RX|     if ( req.backend_hint == d1 ) {\n
**** v1    0.5 CLI RX| -----------------------------##----\n


When we change this test to compare against the backend directly and not against the director the test compiles

------------------------------------------------------------------------------------------------------
varnishtest "Test backends and directors"

server s1 {
  rxreq
  txresp -status 200
} -start


varnish v1 -vcl {
  import std;
  import directors;
  backend b1 {
    .host = "${s1_addr}";
    .port = "${s1_port}";
  }

  sub vcl_init {
    new d1 = directors.round_robin();
    d1.add_backend(b1);
  }

  sub vcl_recv {
    set req.backend_hint = d1.backend();
  }

  sub vcl_backend_response {
    std.log("xxxxxxxx-vcl_backend_response: " + bereq.backend);
    if ( bereq.backend == b1 ) {
      set beresp.http.X-Backend-Response = "d1";
    }
  }

  sub vcl_deliver {
    std.log("xxxxxxxx-vcl_deliver: " + req.backend_hint);
    if ( req.backend_hint == b1 ) {
      set resp.http.X-Backend-Deliver = "d1";
    }
  }

} -start

client c1 {
  txreq
  rxresp
  expect resp.status == 200
  expect resp.http.X-Backend-Response == "d1"
  expect resp.http.X-Backend-Deliver == "d1"
} -run
------------------------------------------------------------------------------------------------------

The test also fails because the expectations of the client are not met:

**   c1    1.0 === expect resp.http.X-Backend-Response == "d1"
---- c1    1.0 EXPECT resp.http.X-Backend-Response (<undef>) == "d1" failed

and we can see in the log that 'bereq.backend' and 'req.backend_hint' are set to 'd1'

...
**** v1    1.0 vsl|       1002 VCL_call        b BACKEND_RESPONSE
**** v1 1.0 vsl| 1002 VCL_Log b xxxxxxxx-vcl_backend_response: d1
**** v1    1.0 vsl|       1002 VCL_return      b deliver
...
**** v1    1.0 vsl|       1001 VCL_call        c DELIVER
**** v1    1.0 vsl|       1001 VCL_Log         c xxxxxxxx-vcl_deliver: d1
**** v1    1.0 vsl|       1001 VCL_return      c deliver
...

The question is how to compare 'bereq.backend' and 'req.backend_hint' properly against a director/backend.
Are we missing something or is this a bug?


Thanks,

Ronald


_______________________________________________
varnish-misc mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-misc

Reply via email to