mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2025-01-08 22:57:42 +03:00
nixos/switchTest: Massively extend the test
This commit is contained in:
parent
393c721849
commit
efcdc01d62
@ -3,21 +3,138 @@
|
||||
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||
name = "switch-test";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ gleber ];
|
||||
maintainers = [ gleber das_j ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
machine = { ... }: {
|
||||
machine = { pkgs, lib, ... }: {
|
||||
users.mutableUsers = false;
|
||||
|
||||
specialisation = rec {
|
||||
simpleService.configuration = {
|
||||
systemd.services.test = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "${pkgs.coreutils}/bin/true";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
simpleServiceModified.configuration = {
|
||||
imports = [ simpleService.configuration ];
|
||||
systemd.services.test.serviceConfig.X-Test = true;
|
||||
};
|
||||
|
||||
simpleServiceNostop.configuration = {
|
||||
imports = [ simpleService.configuration ];
|
||||
systemd.services.test.stopIfChanged = false;
|
||||
};
|
||||
|
||||
simpleServiceReload.configuration = {
|
||||
imports = [ simpleService.configuration ];
|
||||
systemd.services.test = {
|
||||
reloadIfChanged = true;
|
||||
serviceConfig.ExecReload = "${pkgs.coreutils}/bin/true";
|
||||
};
|
||||
};
|
||||
|
||||
simpleServiceNorestart.configuration = {
|
||||
imports = [ simpleService.configuration ];
|
||||
systemd.services.test.restartIfChanged = false;
|
||||
};
|
||||
|
||||
mount.configuration = {
|
||||
systemd.mounts = [
|
||||
{
|
||||
description = "Testmount";
|
||||
what = "tmpfs";
|
||||
type = "tmpfs";
|
||||
where = "/testmount";
|
||||
options = "size=1M";
|
||||
wantedBy = [ "local-fs.target" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
mountModified.configuration = {
|
||||
systemd.mounts = [
|
||||
{
|
||||
description = "Testmount";
|
||||
what = "tmpfs";
|
||||
type = "tmpfs";
|
||||
where = "/testmount";
|
||||
options = "size=10M";
|
||||
wantedBy = [ "local-fs.target" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
timer.configuration = {
|
||||
systemd.timers.test-timer = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig.OnCalendar = "@1395716396"; # chosen by fair dice roll
|
||||
};
|
||||
systemd.services.test-timer = {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.coreutils}/bin/true";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
timerModified.configuration = {
|
||||
imports = [ timer.configuration ];
|
||||
systemd.timers.test-timer.timerConfig.OnCalendar = lib.mkForce "Fri 2012-11-23 16:00:00";
|
||||
};
|
||||
|
||||
path.configuration = {
|
||||
systemd.paths.test-watch = {
|
||||
wantedBy = [ "paths.target" ];
|
||||
pathConfig.PathExists = "/testpath";
|
||||
};
|
||||
systemd.services.test-watch = {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.coreutils}/bin/touch /testpath-modified";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pathModified.configuration = {
|
||||
imports = [ path.configuration ];
|
||||
systemd.paths.test-watch.pathConfig.PathExists = lib.mkForce "/testpath2";
|
||||
};
|
||||
|
||||
slice.configuration = {
|
||||
systemd.slices.testslice.sliceConfig.MemoryMax = "1"; # don't allow memory allocation
|
||||
systemd.services.testservice = {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "${pkgs.coreutils}/bin/true";
|
||||
Slice = "testslice.slice";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sliceModified.configuration = {
|
||||
imports = [ slice.configuration ];
|
||||
systemd.slices.testslice.sliceConfig.MemoryMax = lib.mkForce null;
|
||||
};
|
||||
};
|
||||
};
|
||||
other = { ... }: {
|
||||
|
||||
other = {
|
||||
users.mutableUsers = true;
|
||||
};
|
||||
};
|
||||
|
||||
testScript = {nodes, ...}: let
|
||||
testScript = { nodes, ... }: let
|
||||
originalSystem = nodes.machine.config.system.build.toplevel;
|
||||
otherSystem = nodes.other.config.system.build.toplevel;
|
||||
machine = nodes.machine.config.system.build.toplevel;
|
||||
|
||||
# Ensures failures pass through using pipefail, otherwise failing to
|
||||
# switch-to-configuration is hidden by the success of `tee`.
|
||||
@ -27,12 +144,186 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
||||
set -o pipefail
|
||||
exec env -i "$@" | tee /dev/stderr
|
||||
'';
|
||||
in ''
|
||||
in /* python */ ''
|
||||
def switch_to_specialisation(system, name, action="test"):
|
||||
if name == "":
|
||||
stc = f"{system}/bin/switch-to-configuration"
|
||||
else:
|
||||
stc = f"{system}/specialisation/{name}/bin/switch-to-configuration"
|
||||
out = machine.succeed(f"{stc} {action} 2>&1")
|
||||
assert_lacks(out, "switch-to-configuration line") # Perl warnings
|
||||
return out
|
||||
|
||||
def assert_contains(haystack, needle):
|
||||
if needle not in haystack:
|
||||
print("The haystack that will cause the following exception is:")
|
||||
print("---")
|
||||
print(haystack)
|
||||
print("---")
|
||||
raise Exception(f"Expected string '{needle}' was not found")
|
||||
|
||||
def assert_lacks(haystack, needle):
|
||||
if needle in haystack:
|
||||
print("The haystack that will cause the following exception is:")
|
||||
print("---")
|
||||
print(haystack, end="")
|
||||
print("---")
|
||||
raise Exception(f"Unexpected string '{needle}' was found")
|
||||
|
||||
|
||||
machine.succeed(
|
||||
"${stderrRunner} ${originalSystem}/bin/switch-to-configuration test"
|
||||
)
|
||||
machine.succeed(
|
||||
"${stderrRunner} ${otherSystem}/bin/switch-to-configuration test"
|
||||
)
|
||||
|
||||
with subtest("services"):
|
||||
switch_to_specialisation("${machine}", "")
|
||||
# Nothing happens when nothing is changed
|
||||
out = switch_to_specialisation("${machine}", "")
|
||||
assert_lacks(out, "stopping the following units:")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_lacks(out, "reloading the following units:")
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_lacks(out, "the following new units were started:")
|
||||
assert_lacks(out, "as well:")
|
||||
|
||||
# Start a simple service
|
||||
out = switch_to_specialisation("${machine}", "simpleService")
|
||||
assert_lacks(out, "stopping the following units:")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_contains(out, "reloading the following units: dbus.service\n") # huh
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_contains(out, "the following new units were started: test.service\n")
|
||||
assert_lacks(out, "as well:")
|
||||
|
||||
# Not changing anything doesn't do anything
|
||||
out = switch_to_specialisation("${machine}", "simpleService")
|
||||
assert_lacks(out, "stopping the following units:")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_lacks(out, "reloading the following units:")
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_lacks(out, "the following new units were started:")
|
||||
assert_lacks(out, "as well:")
|
||||
|
||||
# Restart the simple service
|
||||
out = switch_to_specialisation("${machine}", "simpleServiceModified")
|
||||
assert_contains(out, "stopping the following units: test.service\n")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_lacks(out, "reloading the following units:")
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_contains(out, "\nstarting the following units: test.service\n")
|
||||
assert_lacks(out, "the following new units were started:")
|
||||
assert_lacks(out, "as well:")
|
||||
|
||||
# Restart the service with stopIfChanged=false
|
||||
out = switch_to_specialisation("${machine}", "simpleServiceNostop")
|
||||
assert_lacks(out, "stopping the following units:")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_lacks(out, "reloading the following units:")
|
||||
assert_contains(out, "\nrestarting the following units: test.service\n")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_lacks(out, "the following new units were started:")
|
||||
assert_lacks(out, "as well:")
|
||||
|
||||
# Reload the service with reloadIfChanged=true
|
||||
out = switch_to_specialisation("${machine}", "simpleServiceReload")
|
||||
assert_lacks(out, "stopping the following units:")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_contains(out, "reloading the following units: test.service\n")
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_lacks(out, "the following new units were started:")
|
||||
assert_lacks(out, "as well:")
|
||||
|
||||
# Nothing happens when restartIfChanged=false
|
||||
out = switch_to_specialisation("${machine}", "simpleServiceNorestart")
|
||||
assert_lacks(out, "stopping the following units:")
|
||||
assert_contains(out, "NOT restarting the following changed units: test.service\n")
|
||||
assert_lacks(out, "reloading the following units:")
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_lacks(out, "the following new units were started:")
|
||||
assert_lacks(out, "as well:")
|
||||
|
||||
# Dry mode shows different messages
|
||||
out = switch_to_specialisation("${machine}", "simpleService", action="dry-activate")
|
||||
assert_lacks(out, "stopping the following units:")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_lacks(out, "reloading the following units:")
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_lacks(out, "the following new units were started:")
|
||||
assert_lacks(out, "as well:")
|
||||
assert_contains(out, "would start the following units: test.service\n")
|
||||
|
||||
with subtest("mounts"):
|
||||
switch_to_specialisation("${machine}", "mount")
|
||||
out = machine.succeed("mount | grep 'on /testmount'")
|
||||
assert_contains(out, "size=1024k")
|
||||
out = switch_to_specialisation("${machine}", "mountModified")
|
||||
assert_lacks(out, "stopping the following units:")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_contains(out, "reloading the following units: testmount.mount\n")
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_lacks(out, "the following new units were started:")
|
||||
assert_lacks(out, "as well:")
|
||||
# It changed
|
||||
out = machine.succeed("mount | grep 'on /testmount'")
|
||||
assert_contains(out, "size=10240k")
|
||||
|
||||
with subtest("timers"):
|
||||
switch_to_specialisation("${machine}", "timer")
|
||||
out = machine.succeed("systemctl show test-timer.timer")
|
||||
assert_contains(out, "OnCalendar=2014-03-25 02:59:56 UTC")
|
||||
out = switch_to_specialisation("${machine}", "timerModified")
|
||||
assert_lacks(out, "stopping the following units:")
|
||||
assert_lacks(out, "reloading the following units:")
|
||||
assert_contains(out, "restarting the following units: test-timer.timer\n")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_lacks(out, "the following new units were started:")
|
||||
assert_lacks(out, "as well:")
|
||||
# It changed
|
||||
out = machine.succeed("systemctl show test-timer.timer")
|
||||
assert_contains(out, "OnCalendar=Fri 2012-11-23 16:00:00")
|
||||
|
||||
with subtest("paths"):
|
||||
out = switch_to_specialisation("${machine}", "path")
|
||||
assert_contains(out, "stopping the following units: test-timer.timer\n")
|
||||
assert_lacks(out, "NOT restarting the following changed units:")
|
||||
assert_lacks(out, "reloading the following units:")
|
||||
assert_lacks(out, "\nrestarting the following units:")
|
||||
assert_lacks(out, "\nstarting the following units:")
|
||||
assert_contains(out, "the following new units were started: test-watch.path")
|
||||
assert_lacks(out, "as well:")
|
||||
machine.fail("test -f /testpath-modified")
|
||||
|
||||
# touch the file, unit should be triggered
|
||||
machine.succeed("touch /testpath")
|
||||
machine.wait_until_succeeds("test -f /testpath-modified")
|
||||
machine.succeed("rm /testpath /testpath-modified")
|
||||
switch_to_specialisation("${machine}", "pathModified")
|
||||
machine.succeed("touch /testpath")
|
||||
machine.fail("test -f /testpath-modified")
|
||||
machine.succeed("touch /testpath2")
|
||||
machine.wait_until_succeeds("test -f /testpath-modified")
|
||||
|
||||
# This test ensures that changes to slice configuration get applied.
|
||||
# We test this by having a slice that allows no memory allocation at
|
||||
# all and starting a service within it. If the service crashes, the slice
|
||||
# is applied and if we modify the slice to allow memory allocation, the
|
||||
# service should successfully start.
|
||||
with subtest("slices"):
|
||||
machine.succeed("echo 0 > /proc/sys/vm/panic_on_oom") # allow OOMing
|
||||
out = switch_to_specialisation("${machine}", "slice")
|
||||
machine.fail("systemctl start testservice.service")
|
||||
out = switch_to_specialisation("${machine}", "sliceModified")
|
||||
machine.succeed("systemctl start testservice.service")
|
||||
machine.succeed("echo 1 > /proc/sys/vm/panic_on_oom") # disallow OOMing
|
||||
'';
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user