1{ ... }:
2{
3 name = "nginx-etag";
4
5 nodes = {
6 server =
7 { pkgs, lib, ... }:
8 {
9 networking.firewall.enable = false;
10 services.nginx.enable = true;
11 services.nginx.virtualHosts.server = {
12 root = pkgs.runCommandLocal "testdir" { } ''
13 mkdir "$out"
14 cat > "$out/test.js" <<EOF
15 document.getElementById('foobar').setAttribute('foo', 'bar');
16 EOF
17 cat > "$out/index.html" <<EOF
18 <!DOCTYPE html>
19 <div id="foobar">test</div>
20 <script src="test.js"></script>
21 EOF
22 '';
23 };
24
25 specialisation.pass-checks.configuration = {
26 services.nginx.virtualHosts.server = {
27 root = lib.mkForce (
28 pkgs.runCommandLocal "testdir2" { } ''
29 mkdir "$out"
30 cat > "$out/test.js" <<EOF
31 document.getElementById('foobar').setAttribute('foo', 'yay');
32 EOF
33 cat > "$out/index.html" <<EOF
34 <!DOCTYPE html>
35 <div id="foobar">test</div>
36 <script src="test.js"></script>
37 EOF
38 ''
39 );
40 };
41 };
42 };
43
44 client =
45 { pkgs, lib, ... }:
46 {
47 environment.systemPackages =
48 let
49 testRunner =
50 pkgs.writers.writePython3Bin "test-runner"
51 {
52 libraries = [ pkgs.python3Packages.selenium ];
53 }
54 ''
55 import os
56 import time
57
58 from selenium.webdriver import Firefox
59 from selenium.webdriver.firefox.options import Options
60
61 options = Options()
62 options.add_argument('--headless')
63 driver = Firefox(options=options)
64
65 driver.implicitly_wait(20)
66 driver.get('http://server/')
67 driver.find_element('xpath', '//div[@foo="bar"]')
68 open('/tmp/passed_stage1', 'w')
69
70 while not os.path.exists('/tmp/proceed'):
71 time.sleep(0.5)
72
73 driver.get('http://server/')
74 driver.find_element('xpath', '//div[@foo="yay"]')
75 open('/tmp/passed', 'w')
76 '';
77 in
78 [
79 pkgs.firefox-unwrapped
80 pkgs.geckodriver
81 testRunner
82 ];
83 };
84 };
85
86 testScript =
87 { nodes, ... }:
88 let
89 inherit (nodes.server.system.build) toplevel;
90 newSystem = "${toplevel}/specialisation/pass-checks";
91 in
92 ''
93 start_all()
94
95 server.wait_for_unit("nginx.service")
96 client.wait_for_unit("multi-user.target")
97 client.execute("test-runner >&2 &")
98 client.wait_for_file("/tmp/passed_stage1")
99
100 server.succeed(
101 "${newSystem}/bin/switch-to-configuration test >&2"
102 )
103 client.succeed("touch /tmp/proceed")
104
105 client.wait_for_file("/tmp/passed")
106 '';
107}