From 98e257790fa19817d11802eb0ffb9d8b49d19db0 Mon Sep 17 00:00:00 2001 From: Sander van der Burg Date: Tue, 30 Mar 2021 21:03:39 +0200 Subject: [PATCH] Add tests for s6-svscan, sshd, supervisord --- tests/default.nix | 12 +++++ tests/s6-svscan/default.nix | 81 +++++++++++++++++++++++++++++++++ tests/s6-svscan/processes.nix | 33 ++++++++++++++ tests/sshd/default.nix | 41 +++++++++++++++++ tests/sshd/processes.nix | 37 +++++++++++++++ tests/supervisord/default.nix | 51 +++++++++++++++++++++ tests/supervisord/processes.nix | 38 ++++++++++++++++ 7 files changed, 293 insertions(+) create mode 100644 tests/s6-svscan/default.nix create mode 100644 tests/s6-svscan/processes.nix create mode 100644 tests/sshd/default.nix create mode 100644 tests/sshd/processes.nix create mode 100644 tests/supervisord/default.nix create mode 100644 tests/supervisord/processes.nix diff --git a/tests/default.nix b/tests/default.nix index 63d7bb1..fc46fe4 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -39,6 +39,18 @@ in inherit pkgs processManagers profiles testService; }; + s6-svscan = import ./s6-svscan { + inherit pkgs processManagers profiles testService; + }; + + sshd = import ./sshd { + inherit pkgs processManagers profiles testService; + }; + + supervisord = import ./supervisord { + inherit pkgs processManagers profiles testService; + }; + svnserve = import ./svnserve { inherit pkgs processManagers profiles testService; }; diff --git a/tests/s6-svscan/default.nix b/tests/s6-svscan/default.nix new file mode 100644 index 0000000..d198cdb --- /dev/null +++ b/tests/s6-svscan/default.nix @@ -0,0 +1,81 @@ +{ pkgs, testService, processManagers, profiles }: + +let + generateTestExecutable = instanceName: + pkgs.writeTextFile { + name = "test-${instanceName}"; + text = '' + #! ${pkgs.stdenv.shell} -e + + while true + do + echo "Hello ${instanceName}!" >&2 + sleep 1 + done + ''; + executable = true; + }; + + generateTestConfigDir = instanceName: + pkgs.stdenv.mkDerivation { + name = "sv"; + buildCommand = '' + mkdir -p $out/test-${instanceName} + cd $out/test-${instanceName} + + # Generate longrun service for test process + echo "longrun" > type + cat > run < type + cat > contents < { inherit system; } +, system ? builtins.currentSystem +, stateDir ? "/var" +, runtimeDir ? "${stateDir}/run" +, logDir ? "${stateDir}/log" +, spoolDir ? "${stateDir}/spool" +, cacheDir ? "${stateDir}/cache" +, libDir ? "${stateDir}/lib" +, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp") +, forceDisableUserChange ? false +, processManager +}: + +let + constructors = import ../../services-agnostic/constructors.nix { + inherit pkgs stateDir runtimeDir logDir tmpDir cacheDir libDir spoolDir forceDisableUserChange processManager; + }; +in +rec { + s6-svscan-primary = rec { + instanceSuffix = "-primary"; + pkg = constructors.s6-svscan { + inherit instanceSuffix; + }; + }; + + s6-svscan-secondary = rec { + instanceSuffix = "-secondary"; + pkg = constructors.s6-svscan { + inherit instanceSuffix; + }; + }; +} diff --git a/tests/sshd/default.nix b/tests/sshd/default.nix new file mode 100644 index 0000000..622ce2a --- /dev/null +++ b/tests/sshd/default.nix @@ -0,0 +1,41 @@ +{ pkgs, testService, processManagers, profiles }: + +testService { + exprFile = ./processes.nix; + systemPackages = [ pkgs.openssh ]; + + initialTests = {forceDisableUserChange, ...}: + let + homeDir = if forceDisableUserChange then "/home/unprivileged" else "/root"; + in + '' + machine.succeed("cd ${homeDir}") + machine.succeed('ssh-keygen -t ecdsa -f key -N ""') + machine.succeed("mkdir -m 700 ${homeDir}/.ssh") + machine.succeed("cp key.pub ${homeDir}/.ssh/authorized_keys") + machine.succeed("chmod 600 ${homeDir}/.ssh/authorized_keys") + '' + + pkgs.lib.optionalString forceDisableUserChange '' + machine.succeed("chown unprivileged:users key") + machine.succeed("chown -R unprivileged:users ${homeDir}/.ssh") + ''; + + readiness = {instanceName, instance, ...}: + '' + machine.wait_for_open_port(${toString instance.port}) + ''; + + tests = {instanceName, instance, forceDisableUserChange, ...}: + # Make a special exception for the first instance running in privileged mode. It should be connectible with the default settings + if instanceName == "sshd" && !forceDisableUserChange then '' + machine.succeed( + "ssh -i key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost $(type -p ls) /" + ) + '' else '' + machine.succeed( + "${pkgs.lib.optionalString forceDisableUserChange "su unprivileged -c '"}ssh -p ${toString instance.port} -i key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost $(type -p ls) /${pkgs.lib.optionalString forceDisableUserChange "'"}" + ) + ''; + + inherit processManagers profiles; +} diff --git a/tests/sshd/processes.nix b/tests/sshd/processes.nix new file mode 100644 index 0000000..e4fd29f --- /dev/null +++ b/tests/sshd/processes.nix @@ -0,0 +1,37 @@ +{ pkgs ? import { inherit system; } +, system ? builtins.currentSystem +, stateDir ? "/var" +, runtimeDir ? "${stateDir}/run" +, logDir ? "${stateDir}/log" +, spoolDir ? "${stateDir}/spool" +, cacheDir ? "${stateDir}/cache" +, libDir ? "${stateDir}/lib" +, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp") +, forceDisableUserChange ? false +, processManager +}: + +let + constructors = import ../../services-agnostic/constructors.nix { + inherit pkgs stateDir runtimeDir logDir tmpDir cacheDir spoolDir libDir forceDisableUserChange processManager; + }; +in +rec { + sshd = rec { + port = if forceDisableUserChange then 2222 else 22; + instanceSuffix = ""; + + pkg = constructors.sshd { + inherit port instanceSuffix; + }; + }; + + sshd-secondary = rec { + port = if forceDisableUserChange then 2223 else 23; + instanceSuffix = "-secondary"; + + pkg = constructors.sshd { + inherit port instanceSuffix; + }; + }; +} diff --git a/tests/supervisord/default.nix b/tests/supervisord/default.nix new file mode 100644 index 0000000..ff5891d --- /dev/null +++ b/tests/supervisord/default.nix @@ -0,0 +1,51 @@ +{ pkgs, testService, processManagers, profiles }: + +let + generateTestExecutable = instanceName: + pkgs.writeTextFile { + name = "test-${instanceName}"; + text = '' + #! ${pkgs.stdenv.shell} -e + + while true + do + echo "Hello ${instanceName}!" >&2 + sleep 1 + done + ''; + executable = true; + }; + + generateTestConf = instanceName: + pkgs.writeTextFile { + name = "test-${instanceName}.conf"; + text = '' + [program:test-${instanceName}] + command=${generateTestExecutable instanceName} + ''; + }; +in +testService { + exprFile = ./processes.nix; + systemPackages = [ pkgs.pythonPackages.supervisor ]; + + readiness = {instanceName, instance, ...}: + '' + machine.wait_for_open_port(${toString instance.port}) + ''; + + tests = {instanceName, instance, stateDir, ...}: + '' + machine.succeed( + "cp ${generateTestConf instanceName} ${stateDir}/lib/${instanceName}/conf.d" + ) + machine.succeed("supervisorctl --serverurl http://localhost:${toString instance.port} reread") + machine.succeed("supervisorctl --serverurl http://localhost:${toString instance.port} update") + machine.succeed("sleep 1") + machine.succeed( + "pgrep -f '${generateTestExecutable instanceName}'" + ) + ''; + + inherit processManagers profiles; +} diff --git a/tests/supervisord/processes.nix b/tests/supervisord/processes.nix new file mode 100644 index 0000000..709c1d0 --- /dev/null +++ b/tests/supervisord/processes.nix @@ -0,0 +1,38 @@ +{ pkgs ? import { inherit system; } +, system ? builtins.currentSystem +, stateDir ? "/var" +, runtimeDir ? "${stateDir}/run" +, logDir ? "${stateDir}/log" +, spoolDir ? "${stateDir}/spool" +, cacheDir ? "${stateDir}/cache" +, libDir ? "${stateDir}/lib" +, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp") +, forceDisableUserChange ? false +, processManager +}: + +let + constructors = import ../../services-agnostic/constructors.nix { + inherit pkgs stateDir runtimeDir logDir tmpDir cacheDir libDir spoolDir forceDisableUserChange processManager; + }; +in +rec { + supervisord-primary = rec { + # Special situation: we can only bootstrap supervisord with supervisord if we don't conflict with the managing supervisord's port + port = if processManager == "supervisord" then 9003 else 9001; + + pkg = constructors.extendableSupervisord { + inetHTTPServerPort = port; + instanceSuffix = "-primary"; + }; + }; + + supervisord-secondary = rec { + port = 9002; + + pkg = constructors.extendableSupervisord { + inetHTTPServerPort = port; + instanceSuffix = "-secondary"; + }; + }; +}