| 
									
										
										
										
											2017-02-28 09:15:20 -06:00
										 |  |  | # verifies: | 
					
						
							|  |  |  | #   1. nginx generates config file with shared http context definitions above | 
					
						
							|  |  |  | #      generated virtual hosts config. | 
					
						
							| 
									
										
										
										
											2019-04-18 09:35:26 +02:00
										 |  |  | #   2. whether the ETag header is properly generated whenever we're serving | 
					
						
							|  |  |  | #      files in Nix store paths | 
					
						
							| 
									
										
										
										
											2019-08-21 16:52:46 +03:00
										 |  |  | #   3. nginx doesn't restart on configuration changes (only reloads) | 
					
						
							| 
									
										
										
										
											2019-11-24 20:42:54 +01:00
										 |  |  | import ./make-test-python.nix ({ pkgs, ... }: { | 
					
						
							| 
									
										
										
										
											2017-08-11 17:37:14 +02:00
										 |  |  |   name = "nginx"; | 
					
						
							| 
									
										
										
										
											2017-02-28 09:15:20 -06:00
										 |  |  |   meta = with pkgs.stdenv.lib.maintainers; { | 
					
						
							| 
									
										
										
										
											2020-01-05 00:39:23 +02:00
										 |  |  |     maintainers = [ mbbx6spp danbst ]; | 
					
						
							| 
									
										
										
										
											2017-02-28 09:15:20 -06:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-21 16:52:46 +03:00
										 |  |  |   nodes = { | 
					
						
							|  |  |  |     webserver = { pkgs, lib, ... }: { | 
					
						
							| 
									
										
										
										
											2019-04-18 09:35:26 +02:00
										 |  |  |       services.nginx.enable = true; | 
					
						
							|  |  |  |       services.nginx.commonHttpConfig = ''
 | 
					
						
							| 
									
										
										
										
											2017-02-28 09:15:20 -06:00
										 |  |  |         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"}'; | 
					
						
							| 
									
										
										
										
											2019-04-18 09:35:26 +02:00
										 |  |  |       '';
 | 
					
						
							|  |  |  |       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; } | 
					
						
							| 
									
										
										
										
											2017-02-28 09:15:20 -06:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2019-08-21 16:52:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-18 09:35:26 +02:00
										 |  |  |       services.nginx.virtualHosts.localhost = { | 
					
						
							|  |  |  |         root = pkgs.runCommand "testdir" {} ''
 | 
					
						
							|  |  |  |           mkdir "$out" | 
					
						
							|  |  |  |           echo hello world > "$out/index.html" | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-21 16:52:46 +03:00
										 |  |  |       services.nginx.enableReload = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       nesting.clone = [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           services.nginx.virtualHosts.localhost = { | 
					
						
							|  |  |  |             root = lib.mkForce (pkgs.runCommand "testdir2" {} ''
 | 
					
						
							|  |  |  |               mkdir "$out" | 
					
						
							|  |  |  |               echo content changed > "$out/index.html" | 
					
						
							|  |  |  |             '');
 | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           services.nginx.virtualHosts."1.my.test".listen = [ { addr = "127.0.0.1"; port = 8080; }]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           services.nginx.package = pkgs.nginxUnstable; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-01-05 00:39:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           services.nginx.package = pkgs.nginxUnstable; | 
					
						
							|  |  |  |           services.nginx.virtualHosts."!@$$(#*%".locations."~@#*$*!)".proxyPass = ";;;"; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-08-21 16:52:46 +03:00
										 |  |  |       ]; | 
					
						
							| 
									
										
										
										
											2019-04-18 09:35:26 +02:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2019-08-21 16:52:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-28 09:15:20 -06:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-18 09:35:26 +02:00
										 |  |  |   testScript = { nodes, ... }: let | 
					
						
							| 
									
										
										
										
											2019-08-21 16:52:46 +03:00
										 |  |  |     etagSystem = "${nodes.webserver.config.system.build.toplevel}/fine-tune/child-1"; | 
					
						
							|  |  |  |     justReloadSystem = "${nodes.webserver.config.system.build.toplevel}/fine-tune/child-2"; | 
					
						
							|  |  |  |     reloadRestartSystem = "${nodes.webserver.config.system.build.toplevel}/fine-tune/child-3"; | 
					
						
							| 
									
										
										
										
											2020-01-05 00:39:23 +02:00
										 |  |  |     reloadWithErrorsSystem = "${nodes.webserver.config.system.build.toplevel}/fine-tune/child-4"; | 
					
						
							| 
									
										
										
										
											2019-04-18 09:35:26 +02:00
										 |  |  |   in ''
 | 
					
						
							| 
									
										
										
										
											2019-11-24 20:42:54 +01:00
										 |  |  |     url = "http://localhost/index.html" | 
					
						
							| 
									
										
										
										
											2019-08-21 16:52:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-25 00:29:44 +01:00
										 |  |  |     def check_etag(): | 
					
						
							| 
									
										
										
										
											2019-12-26 18:03:39 +01:00
										 |  |  |         etag = webserver.succeed( | 
					
						
							|  |  |  |             f'curl -v {url} 2>&1 | sed -n -e "s/^< etag: *//ip"' | 
					
						
							|  |  |  |         ).rstrip() | 
					
						
							| 
									
										
										
										
											2019-11-25 00:29:44 +01:00
										 |  |  |         http_code = webserver.succeed( | 
					
						
							| 
									
										
										
										
											2019-12-26 18:03:39 +01:00
										 |  |  |             f"curl -w '%{{http_code}}' --head --fail -H 'If-None-Match: {etag}' {url}" | 
					
						
							| 
									
										
										
										
											2019-11-24 20:42:54 +01:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-12-26 18:03:39 +01:00
										 |  |  |         assert http_code.split("\n")[-1] == "304" | 
					
						
							| 
									
										
										
										
											2019-11-24 20:42:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return etag | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     webserver.wait_for_unit("nginx") | 
					
						
							| 
									
										
										
										
											2019-11-25 00:29:44 +01:00
										 |  |  |     webserver.wait_for_open_port(80) | 
					
						
							| 
									
										
										
										
											2019-11-24 20:42:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     with subtest("check ETag if serving Nix store paths"): | 
					
						
							| 
									
										
										
										
											2019-11-25 00:29:44 +01:00
										 |  |  |         old_etag = check_etag() | 
					
						
							| 
									
										
										
										
											2019-11-24 20:42:54 +01:00
										 |  |  |         webserver.succeed( | 
					
						
							|  |  |  |             "${etagSystem}/bin/switch-to-configuration test >&2" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-12-26 18:03:39 +01:00
										 |  |  |         webserver.sleep(1) | 
					
						
							| 
									
										
										
										
											2019-11-25 00:29:44 +01:00
										 |  |  |         new_etag = check_etag() | 
					
						
							|  |  |  |         assert old_etag != new_etag | 
					
						
							| 
									
										
										
										
											2019-11-24 20:42:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     with subtest("config is reloaded on nixos-rebuild switch"): | 
					
						
							|  |  |  |         webserver.succeed( | 
					
						
							|  |  |  |             "${justReloadSystem}/bin/switch-to-configuration test >&2" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-11-25 00:29:44 +01:00
										 |  |  |         webserver.wait_for_open_port(8080) | 
					
						
							| 
									
										
										
										
											2019-11-24 20:42:54 +01:00
										 |  |  |         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" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         webserver.wait_for_unit("nginx") | 
					
						
							|  |  |  |         webserver.succeed("journalctl -u nginx | grep -q -i stopped") | 
					
						
							| 
									
										
										
										
											2020-01-05 00:39:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2017-02-28 09:15:20 -06:00
										 |  |  |   '';
 | 
					
						
							|  |  |  | }) |