Add tests for s6-svscan, sshd, supervisord

This commit is contained in:
Sander van der Burg 2021-03-30 21:03:39 +02:00 committed by Sander van der Burg
parent 92ac474678
commit 98e257790f
7 changed files with 293 additions and 0 deletions

View File

@ -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;
};

View File

@ -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 <<EOF
#!${pkgs.execline}/bin/execlineb -P
exec ${generateTestExecutable instanceName}
EOF
# Generate default bundle containing the above service
mkdir -p ../default
cd ../default
echo "bundle" > type
cat > contents <<EOF
test-${instanceName}
EOF
'';
};
in
testService {
exprFile = ./processes.nix;
systemPackages = [ pkgs.s6-rc ];
readiness = {instanceName, instance, runtimeDir, ...}:
''
machine.wait_for_file("${runtimeDir}/service${instance.instanceSuffix}/.s6-svscan")
'';
tests = {instanceName, instance, stateDir, runtimeDir, forceDisableUserChange, ...}:
let
liveDir = "${stateDir}/run/s6-rc${instance.instanceSuffix}";
compileDir = "${stateDir}/etc/s6${instance.instanceSuffix}/rc";
compiledDatabasePath = "${compileDir}/compiled";
in
''
# fmt: off
machine.succeed(
"${pkgs.lib.optionalString forceDisableUserChange "su unprivileged -c '"}mkdir -p ${compileDir}${pkgs.lib.optionalString forceDisableUserChange "'"}"
)
machine.succeed(
"${pkgs.lib.optionalString forceDisableUserChange "su unprivileged -c '"}s6-rc-compile ${compiledDatabasePath} ${generateTestConfigDir instanceName}${pkgs.lib.optionalString forceDisableUserChange "'"}"
)
machine.succeed(
"${pkgs.lib.optionalString forceDisableUserChange "su unprivileged -c '"}s6-rc-init -c ${compiledDatabasePath} -l ${liveDir} ${runtimeDir}/service${instance.instanceSuffix}${pkgs.lib.optionalString forceDisableUserChange "'"}"
)
machine.succeed(
"${pkgs.lib.optionalString forceDisableUserChange "su unprivileged -c '"}s6-rc -l ${liveDir} -u change default${pkgs.lib.optionalString forceDisableUserChange "'"}"
)
# fmt: on
machine.succeed("sleep 1")
machine.succeed(
"pgrep -f '${generateTestExecutable instanceName}'"
)
'';
inherit processManagers profiles;
}

View File

@ -0,0 +1,33 @@
{ pkgs ? import <nixpkgs> { 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;
};
};
}

41
tests/sshd/default.nix Normal file
View File

@ -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;
}

37
tests/sshd/processes.nix Normal file
View File

@ -0,0 +1,37 @@
{ pkgs ? import <nixpkgs> { 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;
};
};
}

View File

@ -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;
}

View File

@ -0,0 +1,38 @@
{ pkgs ? import <nixpkgs> { 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";
};
};
}