1import ./make-test-python.nix ({ pkgs, ...} :
2
3let
4 backend = { pkgs, ... }: {
5 services.httpd = {
6 enable = true;
7 adminAddr = "foo@example.org";
8 virtualHosts.localhost.documentRoot = "${pkgs.valgrind.doc}/share/doc/valgrind/html";
9 };
10 networking.firewall.allowedTCPPorts = [ 80 ];
11 };
12in {
13 name = "proxy";
14 meta = with pkgs.lib.maintainers; {
15 maintainers = [ eelco ];
16 };
17
18 nodes = {
19 proxy = { nodes, ... }: {
20 services.httpd = {
21 enable = true;
22 adminAddr = "bar@example.org";
23 extraModules = [ "proxy_balancer" "lbmethod_byrequests" ];
24 extraConfig = ''
25 ExtendedStatus on
26 '';
27 virtualHosts.localhost = {
28 extraConfig = ''
29 <Location /server-status>
30 Require all granted
31 SetHandler server-status
32 </Location>
33
34 <Proxy balancer://cluster>
35 Require all granted
36 BalancerMember http://${nodes.backend1.config.networking.hostName} retry=0
37 BalancerMember http://${nodes.backend2.config.networking.hostName} retry=0
38 </Proxy>
39
40 ProxyStatus full
41 ProxyPass /server-status !
42 ProxyPass / balancer://cluster/
43 ProxyPassReverse / balancer://cluster/
44
45 # For testing; don't want to wait forever for dead backend servers.
46 ProxyTimeout 5
47 '';
48 };
49 };
50 networking.firewall.allowedTCPPorts = [ 80 ];
51 };
52
53 backend1 = backend;
54 backend2 = backend;
55
56 client = { ... }: { };
57 };
58
59 testScript = ''
60 start_all()
61
62 proxy.wait_for_unit("httpd")
63 backend1.wait_for_unit("httpd")
64 backend2.wait_for_unit("httpd")
65 client.wait_for_unit("network.target")
66
67 # With the back-ends up, the proxy should work.
68 client.succeed("curl --fail http://proxy/")
69
70 client.succeed("curl --fail http://proxy/server-status")
71
72 # Block the first back-end.
73 backend1.block()
74
75 # The proxy should still work.
76 client.succeed("curl --fail http://proxy/")
77 client.succeed("curl --fail http://proxy/")
78
79 # Block the second back-end.
80 backend2.block()
81
82 # Now the proxy should fail as well.
83 client.fail("curl --fail http://proxy/")
84
85 # But if the second back-end comes back, the proxy should start
86 # working again.
87 backend2.unblock()
88 client.succeed("curl --fail http://proxy/")
89 '';
90})