diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index a2de5b12612d..f459cf4611d2 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -797,15 +797,15 @@ in { nfs3 = handleTest ./nfs { version = 3; }; nfs4 = handleTest ./nfs { version = 4; }; nghttpx = handleTest ./nghttpx.nix {}; - nginx = handleTest ./nginx.nix {}; - nginx-auth = handleTest ./nginx-auth.nix {}; - nginx-etag = handleTest ./nginx-etag.nix {}; - nginx-etag-compression = handleTest ./nginx-etag-compression.nix {}; - nginx-globalredirect = handleTest ./nginx-globalredirect.nix {}; + nginx = runTest ./nginx.nix; + nginx-auth = runTest ./nginx-auth.nix; + nginx-etag = runTest ./nginx-etag.nix; + nginx-etag-compression = runTest ./nginx-etag-compression.nix; + nginx-globalredirect = runTest ./nginx-globalredirect.nix; nginx-http3 = handleTest ./nginx-http3.nix {}; - nginx-mime = handleTest ./nginx-mime.nix {}; - nginx-modsecurity = handleTest ./nginx-modsecurity.nix {}; - nginx-moreheaders = handleTest ./nginx-moreheaders.nix {}; + nginx-mime = runTest ./nginx-mime.nix; + nginx-modsecurity = runTest ./nginx-modsecurity.nix; + nginx-moreheaders = runTest ./nginx-moreheaders.nix; nginx-njs = handleTest ./nginx-njs.nix {}; nginx-proxyprotocol = handleTest ./nginx-proxyprotocol {}; nginx-pubhtml = handleTest ./nginx-pubhtml.nix {}; diff --git a/nixos/tests/nginx-auth.nix b/nixos/tests/nginx-auth.nix index eb04b2571941..1042eee2e0ab 100644 --- a/nixos/tests/nginx-auth.nix +++ b/nixos/tests/nginx-auth.nix @@ -1,54 +1,52 @@ -import ./make-test-python.nix ( - { pkgs, ... }: - { - name = "nginx-auth"; +{ pkgs, ... }: +{ + name = "nginx-auth"; - nodes = { - webserver = - { pkgs, lib, ... }: - { - services.nginx = - let - root = pkgs.runCommand "testdir" { } '' - mkdir "$out" - echo hello world > "$out/index.html" - ''; - in - { - enable = true; + nodes = { + webserver = + { pkgs, lib, ... }: + { + services.nginx = + let + root = pkgs.runCommand "testdir" { } '' + mkdir "$out" + echo hello world > "$out/index.html" + ''; + in + { + enable = true; - virtualHosts.lockedroot = { - inherit root; - basicAuth.alice = "pwofa"; - }; + virtualHosts.lockedroot = { + inherit root; + basicAuth.alice = "pwofa"; + }; - virtualHosts.lockedsubdir = { - inherit root; - locations."/sublocation/" = { - alias = "${root}/"; - basicAuth.bob = "pwofb"; - }; + virtualHosts.lockedsubdir = { + inherit root; + locations."/sublocation/" = { + alias = "${root}/"; + basicAuth.bob = "pwofb"; }; }; - }; - }; + }; + }; + }; - testScript = '' - webserver.wait_for_unit("nginx") - webserver.wait_for_open_port(80) + testScript = '' + webserver.wait_for_unit("nginx") + webserver.wait_for_open_port(80) - webserver.fail("curl --fail --resolve lockedroot:80:127.0.0.1 http://lockedroot") - webserver.succeed( - "curl --fail --resolve lockedroot:80:127.0.0.1 http://alice:pwofa@lockedroot" - ) + webserver.fail("curl --fail --resolve lockedroot:80:127.0.0.1 http://lockedroot") + webserver.succeed( + "curl --fail --resolve lockedroot:80:127.0.0.1 http://alice:pwofa@lockedroot" + ) - webserver.succeed("curl --fail --resolve lockedsubdir:80:127.0.0.1 http://lockedsubdir") - webserver.fail( - "curl --fail --resolve lockedsubdir:80:127.0.0.1 http://lockedsubdir/sublocation/index.html" - ) - webserver.succeed( - "curl --fail --resolve lockedsubdir:80:127.0.0.1 http://bob:pwofb@lockedsubdir/sublocation/index.html" - ) - ''; - } -) + webserver.succeed("curl --fail --resolve lockedsubdir:80:127.0.0.1 http://lockedsubdir") + webserver.fail( + "curl --fail --resolve lockedsubdir:80:127.0.0.1 http://lockedsubdir/sublocation/index.html" + ) + webserver.succeed( + "curl --fail --resolve lockedsubdir:80:127.0.0.1 http://bob:pwofb@lockedsubdir/sublocation/index.html" + ) + ''; +} diff --git a/nixos/tests/nginx-etag-compression.nix b/nixos/tests/nginx-etag-compression.nix index b012c8b1c15c..a194c6fd26b4 100644 --- a/nixos/tests/nginx-etag-compression.nix +++ b/nixos/tests/nginx-etag-compression.nix @@ -1,4 +1,5 @@ -import ./make-test-python.nix { +{ ... }: +{ name = "nginx-etag-compression"; nodes.machine = diff --git a/nixos/tests/nginx-etag.nix b/nixos/tests/nginx-etag.nix index e1154466d796..88aaefd0e476 100644 --- a/nixos/tests/nginx-etag.nix +++ b/nixos/tests/nginx-etag.nix @@ -1,4 +1,5 @@ -import ./make-test-python.nix { +{ ... }: +{ name = "nginx-etag"; nodes = { @@ -85,7 +86,7 @@ import ./make-test-python.nix { testScript = { nodes, ... }: let - inherit (nodes.server.config.system.build) toplevel; + inherit (nodes.server.system.build) toplevel; newSystem = "${toplevel}/specialisation/pass-checks"; in '' diff --git a/nixos/tests/nginx-globalredirect.nix b/nixos/tests/nginx-globalredirect.nix index 42dda6ccaab5..ba1c0623593b 100644 --- a/nixos/tests/nginx-globalredirect.nix +++ b/nixos/tests/nginx-globalredirect.nix @@ -1,29 +1,27 @@ -import ./make-test-python.nix ( - { pkgs, ... }: - { - name = "nginx-globalredirect"; +{ ... }: +{ + name = "nginx-globalredirect"; - nodes = { - webserver = - { pkgs, lib, ... }: - { - services.nginx = { - enable = true; - virtualHosts.localhost = { - globalRedirect = "other.example.com"; - # Add an exception - locations."/noredirect".return = "200 'foo'"; - }; + nodes = { + webserver = + { pkgs, lib, ... }: + { + services.nginx = { + enable = true; + virtualHosts.localhost = { + globalRedirect = "other.example.com"; + # Add an exception + locations."/noredirect".return = "200 'foo'"; }; }; - }; + }; + }; - testScript = '' - webserver.wait_for_unit("nginx") - webserver.wait_for_open_port(80) + testScript = '' + webserver.wait_for_unit("nginx") + webserver.wait_for_open_port(80) - webserver.succeed("curl --fail -si http://localhost/alf | grep '^Location:.*/alf'") - webserver.fail("curl --fail -si http://localhost/noredirect | grep '^Location:'") - ''; - } -) + webserver.succeed("curl --fail -si http://localhost/alf | grep '^Location:.*/alf'") + webserver.fail("curl --fail -si http://localhost/noredirect | grep '^Location:'") + ''; +} diff --git a/nixos/tests/nginx-mime.nix b/nixos/tests/nginx-mime.nix index 157b9f13f142..9752fc01370b 100644 --- a/nixos/tests/nginx-mime.nix +++ b/nixos/tests/nginx-mime.nix @@ -1,26 +1,24 @@ -import ./make-test-python.nix ( - { lib, pkgs, ... }: - { - name = "nginx-mime"; - meta.maintainers = with pkgs.lib.maintainers; [ izorkin ]; +{ lib, pkgs, ... }: +{ + name = "nginx-mime"; + meta.maintainers = with pkgs.lib.maintainers; [ izorkin ]; - nodes = { - server = - { pkgs, ... }: - { - services.nginx = { - enable = true; - virtualHosts."localhost" = { }; - }; + nodes = { + server = + { pkgs, ... }: + { + services.nginx = { + enable = true; + virtualHosts."localhost" = { }; }; - }; + }; + }; - testScript = '' - server.start() - server.wait_for_unit("nginx") - # Check optimal size of types_hash - server.fail("journalctl --unit nginx --grep 'could not build optimal types_hash'") - server.shutdown() - ''; - } -) + testScript = '' + server.start() + server.wait_for_unit("nginx") + # Check optimal size of types_hash + server.fail("journalctl --unit nginx --grep 'could not build optimal types_hash'") + server.shutdown() + ''; +} diff --git a/nixos/tests/nginx-modsecurity.nix b/nixos/tests/nginx-modsecurity.nix index 892180f1cf73..f6aa58b79859 100644 --- a/nixos/tests/nginx-modsecurity.nix +++ b/nixos/tests/nginx-modsecurity.nix @@ -1,51 +1,49 @@ -import ./make-test-python.nix ( - { pkgs, lib, ... }: - { - name = "nginx-modsecurity"; +{ ... }: +{ + name = "nginx-modsecurity"; - nodes.machine = - { - config, - lib, - pkgs, - ... - }: - { - services.nginx = { - enable = true; - additionalModules = [ pkgs.nginxModules.modsecurity ]; - virtualHosts.localhost = - let - modsecurity_conf = pkgs.writeText "modsecurity.conf" '' - SecRuleEngine On - SecDefaultAction "phase:1,log,auditlog,deny,status:403" - SecDefaultAction "phase:2,log,auditlog,deny,status:403" - SecRule REQUEST_METHOD "HEAD" "id:100, phase:1, block" - SecRule REQUEST_FILENAME "secret.html" "id:101, phase:2, block" - ''; - testroot = pkgs.runCommand "testroot" { } '' - mkdir -p $out - echo "Hello World!" > $out/index.html - echo "s3cret" > $out/secret.html - ''; - in - { - root = testroot; - extraConfig = '' - modsecurity on; - modsecurity_rules_file ${modsecurity_conf}; - ''; - }; - }; + nodes.machine = + { + config, + lib, + pkgs, + ... + }: + { + services.nginx = { + enable = true; + additionalModules = [ pkgs.nginxModules.modsecurity ]; + virtualHosts.localhost = + let + modsecurity_conf = pkgs.writeText "modsecurity.conf" '' + SecRuleEngine On + SecDefaultAction "phase:1,log,auditlog,deny,status:403" + SecDefaultAction "phase:2,log,auditlog,deny,status:403" + SecRule REQUEST_METHOD "HEAD" "id:100, phase:1, block" + SecRule REQUEST_FILENAME "secret.html" "id:101, phase:2, block" + ''; + testroot = pkgs.runCommand "testroot" { } '' + mkdir -p $out + echo "Hello World!" > $out/index.html + echo "s3cret" > $out/secret.html + ''; + in + { + root = testroot; + extraConfig = '' + modsecurity on; + modsecurity_rules_file ${modsecurity_conf}; + ''; + }; }; - testScript = '' - machine.wait_for_unit("nginx") + }; + testScript = '' + machine.wait_for_unit("nginx") - response = machine.wait_until_succeeds("curl -fvvv -s http://127.0.0.1/") - assert "Hello World!" in response + response = machine.wait_until_succeeds("curl -fvvv -s http://127.0.0.1/") + assert "Hello World!" in response - machine.fail("curl -fvvv -X HEAD -s http://127.0.0.1/") - machine.fail("curl -fvvv -s http://127.0.0.1/secret.html") - ''; - } -) + machine.fail("curl -fvvv -X HEAD -s http://127.0.0.1/") + machine.fail("curl -fvvv -s http://127.0.0.1/secret.html") + ''; +} diff --git a/nixos/tests/nginx-moreheaders.nix b/nixos/tests/nginx-moreheaders.nix index 34bbb211dc9d..446f0ed179e2 100644 --- a/nixos/tests/nginx-moreheaders.nix +++ b/nixos/tests/nginx-moreheaders.nix @@ -1,4 +1,5 @@ -import ./make-test-python.nix { +{ ... }: +{ name = "nginx-more-headers"; nodes = { diff --git a/nixos/tests/nginx.nix b/nixos/tests/nginx.nix index 8b1f921ec520..476824e3a9ec 100644 --- a/nixos/tests/nginx.nix +++ b/nixos/tests/nginx.nix @@ -4,134 +4,150 @@ # 2. whether the ETag header is properly generated whenever we're serving # files in Nix store paths # 3. nginx doesn't restart on configuration changes (only reloads) -import ./make-test-python.nix ({ pkgs, ... }: { +{ pkgs, ... }: +{ name = "nginx"; meta = with pkgs.lib.maintainers; { - maintainers = [ mbbx6spp danbst ]; + maintainers = [ + mbbx6spp + danbst + ]; }; nodes = { - webserver = { pkgs, lib, ... }: { - services.nginx.enable = true; - services.nginx.commonHttpConfig = '' - log_format ceeformat '@cee: {"status":"$status",' - '"request_time":$request_time,' - '"upstream_response_time":$upstream_response_time,' - '"pipe":"$pipe","bytes_sent":$bytes_sent,' - '"connection":"$connection",' - '"remote_addr":"$remote_addr",' - '"host":"$host",' - '"timestamp":"$time_iso8601",' - '"request":"$request",' - '"http_referer":"$http_referer",' - '"upstream_addr":"$upstream_addr"}'; - ''; - services.nginx.virtualHosts."0.my.test" = { - extraConfig = '' - access_log syslog:server=unix:/dev/log,facility=user,tag=mytag,severity=info ceeformat; - location /favicon.ico { allow all; access_log off; log_not_found off; } + webserver = + { pkgs, lib, ... }: + { + services.nginx.enable = true; + services.nginx.commonHttpConfig = '' + log_format ceeformat '@cee: {"status":"$status",' + '"request_time":$request_time,' + '"upstream_response_time":$upstream_response_time,' + '"pipe":"$pipe","bytes_sent":$bytes_sent,' + '"connection":"$connection",' + '"remote_addr":"$remote_addr",' + '"host":"$host",' + '"timestamp":"$time_iso8601",' + '"request":"$request",' + '"http_referer":"$http_referer",' + '"upstream_addr":"$upstream_addr"}'; ''; - }; + services.nginx.virtualHosts."0.my.test" = { + extraConfig = '' + access_log syslog:server=unix:/dev/log,facility=user,tag=mytag,severity=info ceeformat; + location /favicon.ico { allow all; access_log off; log_not_found off; } + ''; + }; - services.nginx.virtualHosts.localhost = { - root = pkgs.runCommand "testdir" {} '' - mkdir "$out" - echo hello world > "$out/index.html" - ''; - }; - - services.nginx.enableReload = true; - - specialisation.etagSystem.configuration = { services.nginx.virtualHosts.localhost = { - root = lib.mkForce (pkgs.runCommand "testdir2" {} '' + root = pkgs.runCommand "testdir" { } '' mkdir "$out" - echo content changed > "$out/index.html" - ''); + echo hello world > "$out/index.html" + ''; + }; + + services.nginx.enableReload = true; + + specialisation.etagSystem.configuration = { + services.nginx.virtualHosts.localhost = { + root = lib.mkForce ( + pkgs.runCommand "testdir2" { } '' + mkdir "$out" + echo content changed > "$out/index.html" + '' + ); + }; + }; + + specialisation.justReloadSystem.configuration = { + services.nginx.virtualHosts."1.my.test".listen = [ + { + addr = "127.0.0.1"; + port = 8080; + } + ]; + }; + + specialisation.reloadRestartSystem.configuration = { + services.nginx.package = pkgs.nginxMainline; + }; + + specialisation.reloadWithErrorsSystem.configuration = { + services.nginx.package = pkgs.nginxMainline; + services.nginx.virtualHosts."!@$$(#*%".locations."~@#*$*!)".proxyPass = ";;;"; }; }; - - specialisation.justReloadSystem.configuration = { - services.nginx.virtualHosts."1.my.test".listen = [ { addr = "127.0.0.1"; port = 8080; }]; - }; - - specialisation.reloadRestartSystem.configuration = { - services.nginx.package = pkgs.nginxMainline; - }; - - specialisation.reloadWithErrorsSystem.configuration = { - services.nginx.package = pkgs.nginxMainline; - services.nginx.virtualHosts."!@$$(#*%".locations."~@#*$*!)".proxyPass = ";;;"; - }; - }; }; - testScript = { nodes, ... }: let - etagSystem = "${nodes.webserver.system.build.toplevel}/specialisation/etagSystem"; - justReloadSystem = "${nodes.webserver.system.build.toplevel}/specialisation/justReloadSystem"; - reloadRestartSystem = "${nodes.webserver.system.build.toplevel}/specialisation/reloadRestartSystem"; - reloadWithErrorsSystem = "${nodes.webserver.system.build.toplevel}/specialisation/reloadWithErrorsSystem"; - in '' - url = "http://localhost/index.html" + testScript = + { nodes, ... }: + let + etagSystem = "${nodes.webserver.system.build.toplevel}/specialisation/etagSystem"; + justReloadSystem = "${nodes.webserver.system.build.toplevel}/specialisation/justReloadSystem"; + reloadRestartSystem = "${nodes.webserver.system.build.toplevel}/specialisation/reloadRestartSystem"; + reloadWithErrorsSystem = "${nodes.webserver.system.build.toplevel}/specialisation/reloadWithErrorsSystem"; + in + '' + url = "http://localhost/index.html" - def check_etag(): - etag = webserver.succeed( - f'curl -v {url} 2>&1 | sed -n -e "s/^< etag: *//ip"' - ).rstrip() - http_code = webserver.succeed( - f"curl -w '%{{http_code}}' --head --fail -H 'If-None-Match: {etag}' {url}" - ) - assert http_code.split("\n")[-1] == "304" + def check_etag(): + etag = webserver.succeed( + f'curl -v {url} 2>&1 | sed -n -e "s/^< etag: *//ip"' + ).rstrip() + http_code = webserver.succeed( + f"curl -w '%{{http_code}}' --head --fail -H 'If-None-Match: {etag}' {url}" + ) + assert http_code.split("\n")[-1] == "304" - return etag + return etag - def wait_for_nginx_on_port(port): - webserver.wait_for_unit("nginx") - webserver.wait_for_open_port(port) + def wait_for_nginx_on_port(port): + webserver.wait_for_unit("nginx") + webserver.wait_for_open_port(port) - # nginx can be ready before multi-user.target, in which case switching to - # a different configuration might not realize it needs to restart nginx. - webserver.wait_for_unit("multi-user.target") + # nginx can be ready before multi-user.target, in which case switching to + # a different configuration might not realize it needs to restart nginx. + webserver.wait_for_unit("multi-user.target") - wait_for_nginx_on_port(80) + wait_for_nginx_on_port(80) - with subtest("check ETag if serving Nix store paths"): - old_etag = check_etag() - webserver.succeed( - "${etagSystem}/bin/switch-to-configuration test >&2" - ) - wait_for_nginx_on_port(80) - new_etag = check_etag() - assert old_etag != new_etag + with subtest("check ETag if serving Nix store paths"): + old_etag = check_etag() + webserver.succeed( + "${etagSystem}/bin/switch-to-configuration test >&2" + ) + wait_for_nginx_on_port(80) + new_etag = check_etag() + assert old_etag != new_etag - with subtest("config is reloaded on nixos-rebuild switch"): - webserver.succeed( - "${justReloadSystem}/bin/switch-to-configuration test >&2" - ) - wait_for_nginx_on_port(8080) - webserver.fail("journalctl -u nginx | grep -q -i stopped") - webserver.succeed("journalctl -u nginx | grep -q -i reloaded") + with subtest("config is reloaded on nixos-rebuild switch"): + webserver.succeed( + "${justReloadSystem}/bin/switch-to-configuration test >&2" + ) + wait_for_nginx_on_port(8080) + webserver.fail("journalctl -u nginx | grep -q -i stopped") + webserver.succeed("journalctl -u nginx | grep -q -i reloaded") - with subtest("restart when nginx package changes"): - webserver.succeed( - "${reloadRestartSystem}/bin/switch-to-configuration test >&2" - ) - wait_for_nginx_on_port(80) - webserver.succeed("journalctl -u nginx | grep -q -i stopped") + with subtest("restart when nginx package changes"): + webserver.succeed( + "${reloadRestartSystem}/bin/switch-to-configuration test >&2" + ) + wait_for_nginx_on_port(80) + webserver.succeed("journalctl -u nginx | grep -q -i stopped") - with subtest("nixos-rebuild --switch should fail when there are configuration errors"): - webserver.fail( - "${reloadWithErrorsSystem}/bin/switch-to-configuration test >&2" - ) - webserver.succeed("[[ $(systemctl is-failed nginx-config-reload) == failed ]]") - webserver.succeed("[[ $(systemctl is-failed nginx) == active ]]") - # just to make sure operation is idempotent. During development I had a situation - # when first time it shows error, but stops showing it on subsequent rebuilds - webserver.fail( - "${reloadWithErrorsSystem}/bin/switch-to-configuration test >&2" - ) - ''; -}) + with subtest("nixos-rebuild --switch should fail when there are configuration errors"): + webserver.fail( + "${reloadWithErrorsSystem}/bin/switch-to-configuration test >&2" + ) + webserver.succeed("[[ $(systemctl is-failed nginx-config-reload) == failed ]]") + webserver.succeed("[[ $(systemctl is-failed nginx) == active ]]") + # just to make sure operation is idempotent. During development I had a situation + # when first time it shows error, but stops showing it on subsequent rebuilds + webserver.fail( + "${reloadWithErrorsSystem}/bin/switch-to-configuration test >&2" + ) + ''; +}