diff options
-rw-r--r-- | nix/module.nix | 16 | ||||
-rw-r--r-- | nix/test-socket-usage.nix | 16 | ||||
-rw-r--r-- | src/config.rs | 21 |
3 files changed, 53 insertions, 0 deletions
diff --git a/nix/module.nix b/nix/module.nix index 35eba4c..7ef1f98 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -86,6 +86,21 @@ in { type = types.path; readOnly = true; }; + + max-idle-time = mkOption { + description = '' + Maximum time the server should wait for a new connection before exiting. + + In conjunction with socket-activation, this ensures the server isn't + using any ressources in the (typically) long periods of time between + requests. + + The server will never exit, if this option is set to `null`. + ''; + type = with types; nullOr str; + default = null; + example = "20min"; + }; }; }; @@ -131,6 +146,7 @@ in { config = { "secret_path" = cfg.secret-path; "commands" = cfg.commands; + "max_idle_time" = cfg.max-idle-time; }; config-file = pkgs.writers.writeJSON "config.json" config; diff --git a/nix/test-socket-usage.nix b/nix/test-socket-usage.nix index 25aa5fc..409dd68 100644 --- a/nix/test-socket-usage.nix +++ b/nix/test-socket-usage.nix @@ -1,3 +1,8 @@ +let + # Normally the max-idle time would probably be a little longer than this, but + # I don't want to drag out this test for 10 minutes. + max-idle-secs = 20; +in { name = "socket-usage"; @@ -16,6 +21,8 @@ } ]; + max-idle-time = "${toString max-idle-secs}s"; + # The secret to be used when authenticating event's signature. secret-path = toString (pkgs.writeText "secret.txt" "mysecret"); }; @@ -69,6 +76,8 @@ }; testScript = '' + import time + machine.start() with subtest("Proper (lazy) socket activation"): @@ -87,6 +96,13 @@ exit_code, _ = machine.systemctl("is-active webhook-listener.service --quiet") assert exit_code == 0, "Event should be active" + with subtest("Service should exit after idle time"): + # Give it a little buffer to avoid false negatives. + time.sleep(${toString max-idle-secs} + 5) + + exit_code, _ = machine.systemctl("is-active webhook-listener.service --quiet") + assert exit_code == 3, "Event should be inactive" + # TODO: Send an invalid request (subtest). ''; } diff --git a/src/config.rs b/src/config.rs index b929be0..d048586 100644 --- a/src/config.rs +++ b/src/config.rs @@ -220,4 +220,25 @@ mod tests { }; assert_eq!(parsed_config, expected_config); } + + #[test] + fn max_idle_time_null_deserializes_to_none() { + let config_json = r#" + { + "secret_path": "/path/to/secret.txt", + + "max_idle_time": null, + + "commands": [ ] + } + "#; + let parsed_config = serde_json::from_str::<Config>(config_json).expect("valid config"); + let expected_config = Config { + secret_path: Path::new("/path/to/secret.txt").to_path_buf(), + secret: "".to_string(), // We didn't ask it to read file + max_idle_time: None, + commands: vec![], + }; + assert_eq!(parsed_config, expected_config); + } } |