1 # Test configuration switching.
3 import ./make-test-python.nix ({ lib, pkgs, ng, ...} : let
5 # Simple service that can either be socket-activated or that will
6 # listen on port 1234 if not socket-activated.
7 # A connection to the socket causes 'hello' to be written to the client.
8 socketTest = pkgs.writeScript "socket-test.py" /* python */ ''
9 #!${pkgs.python3}/bin/python3
11 from socketserver import TCPServer, StreamRequestHandler
16 class Handler(StreamRequestHandler):
18 self.wfile.write("hello".encode("utf-8"))
21 class Server(TCPServer):
22 def __init__(self, server_address, handler_cls):
23 listenFds = os.getenv('LISTEN_FDS')
24 if listenFds is None or int(listenFds) < 1:
25 print(f'Binding to {server_address}')
27 self, server_address, handler_cls, bind_and_activate=True)
30 self, server_address, handler_cls, bind_and_activate=False)
32 print(f'Got activated by {os.getenv("LISTEN_FDNAMES")} '
33 f'with {listenFds} FDs')
34 self.socket = socket.fromfd(3, self.address_family,
38 if __name__ == "__main__":
39 server = Server(("localhost", 1234), Handler)
40 server.serve_forever()
45 meta = with pkgs.lib.maintainers; {
46 maintainers = [ gleber das_j ];
50 machine = { pkgs, lib, ... }: {
51 system.switch.enableNg = ng;
53 environment.systemPackages = [ pkgs.socat ]; # for the socket activation stuff
54 users.mutableUsers = false;
56 # Test that no boot loader still switches, e.g. in the ISO
57 boot.loader.grub.enable = false;
59 specialisation = rec {
60 brokenInitInterface.configuration.config.system.extraSystemBuilderCmds = ''
61 echo "systemd 0" > $out/init-interface-version
64 modifiedSystemConf.configuration.systemd.extraConfig = ''
68 addedMount.configuration.virtualisation.fileSystems."/test" = {
73 addedMountOptsModified.configuration = {
74 imports = [ addedMount.configuration ];
75 virtualisation.fileSystems."/test".options = [ "x-test" ];
78 addedMountDevModified.configuration = {
79 imports = [ addedMountOptsModified.configuration ];
80 virtualisation.fileSystems."/test".device = lib.mkForce "ramfs";
83 storeMountModified.configuration = {
84 virtualisation.fileSystems."/".device = lib.mkForce "auto";
87 swap.configuration.swapDevices = lib.mkVMOverride [
88 { device = "/swapfile"; size = 1; }
91 simpleService.configuration = {
92 systemd.services.test = {
93 wantedBy = [ "multi-user.target" ];
96 RemainAfterExit = true;
97 ExecStart = "${pkgs.coreutils}/bin/true";
98 ExecReload = "${pkgs.coreutils}/bin/true";
103 simpleServiceSeparateActivationScript.configuration = {
104 system.activatable = false;
105 systemd.services.test = {
106 wantedBy = [ "multi-user.target" ];
109 RemainAfterExit = true;
110 ExecStart = "${pkgs.coreutils}/bin/true";
111 ExecReload = "${pkgs.coreutils}/bin/true";
116 simpleServiceDifferentDescription.configuration = {
117 imports = [ simpleService.configuration ];
118 systemd.services.test.description = "Test unit";
121 simpleServiceModified.configuration = {
122 imports = [ simpleService.configuration ];
123 systemd.services.test.serviceConfig.X-Test = true;
126 simpleServiceNostop.configuration = {
127 imports = [ simpleService.configuration ];
128 systemd.services.test.stopIfChanged = false;
131 simpleServiceReload.configuration = {
132 imports = [ simpleService.configuration ];
133 systemd.services.test = {
134 reloadIfChanged = true;
135 serviceConfig.ExecReload = "${pkgs.coreutils}/bin/true";
139 simpleServiceNorestart.configuration = {
140 imports = [ simpleService.configuration ];
141 systemd.services.test.restartIfChanged = false;
144 simpleServiceFailing.configuration = {
145 imports = [ simpleServiceModified.configuration ];
146 systemd.services.test.serviceConfig.ExecStart = lib.mkForce "${pkgs.coreutils}/bin/false";
149 autorestartService.configuration = {
150 # A service that immediately goes into restarting (but without failing)
151 systemd.services.autorestart = {
152 wantedBy = [ "multi-user.target" ];
156 RestartSec = "20y"; # Should be long enough
157 ExecStart = "${pkgs.coreutils}/bin/true";
162 autorestartServiceFailing.configuration = {
163 imports = [ autorestartService.configuration ];
164 systemd.services.autorestart.serviceConfig = {
165 ExecStart = lib.mkForce "${pkgs.coreutils}/bin/false";
169 simpleServiceWithExtraSection.configuration = {
170 imports = [ simpleServiceNostop.configuration ];
171 systemd.packages = [ (pkgs.writeTextFile {
172 name = "systemd-extra-section";
173 destination = "/etc/systemd/system/test.service";
181 simpleServiceWithExtraSectionOtherName.configuration = {
182 imports = [ simpleServiceNostop.configuration ];
183 systemd.packages = [ (pkgs.writeTextFile {
184 name = "systemd-extra-section";
185 destination = "/etc/systemd/system/test.service";
193 simpleServiceWithInstallSection.configuration = {
194 imports = [ simpleServiceNostop.configuration ];
195 systemd.packages = [ (pkgs.writeTextFile {
196 name = "systemd-extra-section";
197 destination = "/etc/systemd/system/test.service";
200 WantedBy=multi-user.target
205 simpleServiceWithExtraKey.configuration = {
206 imports = [ simpleServiceNostop.configuration ];
207 systemd.services.test.serviceConfig."X-Test" = "test";
210 simpleServiceWithExtraKeyOtherValue.configuration = {
211 imports = [ simpleServiceNostop.configuration ];
212 systemd.services.test.serviceConfig."X-Test" = "test2";
215 simpleServiceWithExtraKeyOtherName.configuration = {
216 imports = [ simpleServiceNostop.configuration ];
217 systemd.services.test.serviceConfig."X-Test2" = "test";
220 simpleServiceReloadTrigger.configuration = {
221 imports = [ simpleServiceNostop.configuration ];
222 systemd.services.test.reloadTriggers = [ "/dev/null" ];
225 simpleServiceReloadTriggerModified.configuration = {
226 imports = [ simpleServiceNostop.configuration ];
227 systemd.services.test.reloadTriggers = [ "/dev/zero" ];
230 simpleServiceReloadTriggerModifiedAndSomethingElse.configuration = {
231 imports = [ simpleServiceNostop.configuration ];
232 systemd.services.test = {
233 reloadTriggers = [ "/dev/zero" ];
234 serviceConfig."X-Test" = "test";
238 simpleServiceReloadTriggerModifiedSomethingElse.configuration = {
239 imports = [ simpleServiceNostop.configuration ];
240 systemd.services.test.serviceConfig."X-Test" = "test";
243 unitWithBackslash.configuration = {
244 systemd.services."escaped\\x2ddash" = {
245 wantedBy = [ "multi-user.target" ];
248 RemainAfterExit = true;
249 ExecStart = "${pkgs.coreutils}/bin/true";
250 ExecReload = "${pkgs.coreutils}/bin/true";
255 unitWithBackslashModified.configuration = {
256 imports = [ unitWithBackslash.configuration ];
257 systemd.services."escaped\\x2ddash".serviceConfig.X-Test = "test";
260 unitWithMultilineValue.configuration = {
261 systemd.services.test.serviceConfig.ExecStart = ''
262 ${pkgs.coreutils}/bin/true \
269 unitStartingWithDash.configuration = {
270 systemd.services."-" = {
271 wantedBy = [ "multi-user.target" ];
274 RemainAfterExit = true;
275 ExecStart = "${pkgs.coreutils}/bin/true";
280 unitStartingWithDashModified.configuration = {
281 imports = [ unitStartingWithDash.configuration ];
282 systemd.services."-" = {
283 reloadIfChanged = true;
284 serviceConfig.ExecReload = "${pkgs.coreutils}/bin/true";
288 unitWithRequirement.configuration = {
289 systemd.services.required-service = {
290 wantedBy = [ "multi-user.target" ];
293 RemainAfterExit = true;
294 ExecStart = "${pkgs.coreutils}/bin/true";
295 ExecReload = "${pkgs.coreutils}/bin/true";
298 systemd.services.test-service = {
299 wantedBy = [ "multi-user.target" ];
300 requires = [ "required-service.service" ];
303 RemainAfterExit = true;
304 ExecStart = "${pkgs.coreutils}/bin/true";
305 ExecReload = "${pkgs.coreutils}/bin/true";
310 unitWithRequirementModified.configuration = {
311 imports = [ unitWithRequirement.configuration ];
312 systemd.services.required-service.serviceConfig.X-Test = "test";
313 systemd.services.test-service.reloadTriggers = [ "test" ];
316 unitWithRequirementModifiedNostart.configuration = {
317 imports = [ unitWithRequirement.configuration ];
318 systemd.services.test-service.unitConfig.RefuseManualStart = true;
321 unitWithTemplate.configuration = {
322 systemd.services."instantiated@".serviceConfig = {
324 RemainAfterExit = true;
325 ExecStart = "${pkgs.coreutils}/bin/true";
326 ExecReload = "${pkgs.coreutils}/bin/true";
328 systemd.services."instantiated@one" = {
329 wantedBy = [ "multi-user.target" ];
330 overrideStrategy = "asDropin";
332 systemd.services."instantiated@two" = {
333 wantedBy = [ "multi-user.target" ];
334 overrideStrategy = "asDropin";
338 unitWithTemplateModified.configuration = {
339 imports = [ unitWithTemplate.configuration ];
340 systemd.services."instantiated@".serviceConfig.X-Test = "test";
343 restart-and-reload-by-activation-script.configuration = {
344 systemd.services = rec {
346 # No wantedBy so we can check if the activation script restart triggers them
349 RemainAfterExit = true;
350 ExecStart = "${pkgs.coreutils}/bin/true";
351 ExecReload = "${pkgs.coreutils}/bin/true";
354 "templated-simple-service@" = simple-service;
355 "templated-simple-service@instance".overrideStrategy = "asDropin";
357 simple-restart-service = simple-service // {
358 stopIfChanged = false;
360 "templated-simple-restart-service@" = simple-restart-service;
361 "templated-simple-restart-service@instance".overrideStrategy = "asDropin";
363 simple-reload-service = simple-service // {
364 reloadIfChanged = true;
366 "templated-simple-reload-service@" = simple-reload-service;
367 "templated-simple-reload-service@instance".overrideStrategy = "asDropin";
369 no-restart-service = simple-service // {
370 restartIfChanged = false;
372 "templated-no-restart-service@" = no-restart-service;
373 "templated-no-restart-service@instance".overrideStrategy = "asDropin";
375 reload-triggers = simple-service // {
376 wantedBy = [ "multi-user.target" ];
378 "templated-reload-triggers@" = simple-service;
379 "templated-reload-triggers@instance" = {
380 overrideStrategy = "asDropin";
381 wantedBy = [ "multi-user.target" ];
384 reload-triggers-and-restart-by-as = simple-service;
385 "templated-reload-triggers-and-restart-by-as@" = reload-triggers-and-restart-by-as;
386 "templated-reload-triggers-and-restart-by-as@instance".overrideStrategy = "asDropin";
388 reload-triggers-and-restart = simple-service // {
389 stopIfChanged = false; # easier to check for this
390 wantedBy = [ "multi-user.target" ];
392 "templated-reload-triggers-and-restart@" = simple-service;
393 "templated-reload-triggers-and-restart@instance" = {
394 overrideStrategy = "asDropin";
395 stopIfChanged = false; # easier to check for this
396 wantedBy = [ "multi-user.target" ];
400 system.activationScripts.restart-and-reload-test = {
401 supportsDryActivation = true;
404 if [ "$NIXOS_ACTION" = dry-activate ]; then
405 f=/run/nixos/dry-activation-restart-list
406 g=/run/nixos/dry-activation-reload-list
408 f=/run/nixos/activation-restart-list
409 g=/run/nixos/activation-reload-list
412 simple-service.service
413 simple-restart-service.service
414 simple-reload-service.service
415 no-restart-service.service
416 reload-triggers-and-restart-by-as.service
417 templated-simple-service@instance.service
418 templated-simple-restart-service@instance.service
419 templated-simple-reload-service@instance.service
420 templated-no-restart-service@instance.service
421 templated-reload-triggers-and-restart-by-as@instance.service
425 reload-triggers.service
426 reload-triggers-and-restart-by-as.service
427 reload-triggers-and-restart.service
428 templated-reload-triggers@instance.service
429 templated-reload-triggers-and-restart-by-as@instance.service
430 templated-reload-triggers-and-restart@instance.service
436 restart-and-reload-by-activation-script-modified.configuration = {
437 imports = [ restart-and-reload-by-activation-script.configuration ];
438 systemd.services.reload-triggers-and-restart.serviceConfig.X-Modified = "test";
439 systemd.services."templated-reload-triggers-and-restart@instance" = {
440 overrideStrategy = "asDropin";
441 serviceConfig.X-Modified = "test";
445 simple-socket.configuration = {
446 systemd.services.socket-activated = {
447 description = "A socket-activated service";
448 stopIfChanged = lib.mkDefault false;
450 ExecStart = socketTest;
451 ExecReload = "${pkgs.coreutils}/bin/true";
454 systemd.sockets.socket-activated = {
455 wantedBy = [ "sockets.target" ];
456 listenStreams = [ "/run/test.sock" ];
457 socketConfig.SocketMode = lib.mkDefault "0777";
461 simple-socket-service-modified.configuration = {
462 imports = [ simple-socket.configuration ];
463 systemd.services.socket-activated.serviceConfig.X-Test = "test";
466 simple-socket-stop-if-changed.configuration = {
467 imports = [ simple-socket.configuration ];
468 systemd.services.socket-activated.stopIfChanged = true;
471 simple-socket-stop-if-changed-and-reloadtrigger.configuration = {
472 imports = [ simple-socket.configuration ];
473 systemd.services.socket-activated = {
474 stopIfChanged = true;
475 reloadTriggers = [ "test" ];
479 mount.configuration = {
482 description = "Testmount";
485 where = "/testmount";
487 wantedBy = [ "local-fs.target" ];
492 mountOptionsModified.configuration = {
495 description = "Testmount";
498 where = "/testmount";
499 options = "size=10M";
500 wantedBy = [ "local-fs.target" ];
505 mountModified.configuration = {
508 description = "Testmount";
511 where = "/testmount";
512 options = "size=10M";
513 wantedBy = [ "local-fs.target" ];
518 timer.configuration = {
519 systemd.timers.test-timer = {
520 wantedBy = [ "timers.target" ];
521 timerConfig.OnCalendar = "@1395716396"; # chosen by fair dice roll
523 systemd.services.test-timer = {
526 ExecStart = "${pkgs.coreutils}/bin/true";
531 timerModified.configuration = {
532 imports = [ timer.configuration ];
533 systemd.timers.test-timer.timerConfig.OnCalendar = lib.mkForce "Fri 2012-11-23 16:00:00";
536 hybridSleepModified.configuration = {
537 systemd.targets.hybrid-sleep.unitConfig.X-Test = true;
540 target.configuration = {
541 systemd.targets.test-target.wantedBy = [ "multi-user.target" ];
542 # We use this service to figure out whether the target was modified.
543 # This is the only way because targets are filtered and therefore not
544 # printed when they are started/stopped.
545 systemd.services.test-service = {
546 bindsTo = [ "test-target.target" ];
547 serviceConfig.ExecStart = "${pkgs.coreutils}/bin/sleep infinity";
551 targetModified.configuration = {
552 imports = [ target.configuration ];
553 systemd.targets.test-target.unitConfig.X-Test = true;
556 targetModifiedStopOnReconfig.configuration = {
557 imports = [ target.configuration ];
558 systemd.targets.test-target.unitConfig.X-StopOnReconfiguration = true;
561 path.configuration = {
562 systemd.paths.test-watch = {
563 wantedBy = [ "paths.target" ];
564 pathConfig.PathExists = "/testpath";
566 systemd.services.test-watch = {
569 RemainAfterExit = true;
570 ExecStart = "${pkgs.coreutils}/bin/touch /testpath-modified";
575 pathModified.configuration = {
576 imports = [ path.configuration ];
577 systemd.paths.test-watch.pathConfig.PathExists = lib.mkForce "/testpath2";
580 slice.configuration = {
581 systemd.slices.testslice.sliceConfig.MemoryMax = "1"; # don't allow memory allocation
582 systemd.services.testservice = {
585 RemainAfterExit = true;
586 ExecStart = "${pkgs.coreutils}/bin/true";
587 Slice = "testslice.slice";
592 sliceModified.configuration = {
593 imports = [ slice.configuration ];
594 systemd.slices.testslice.sliceConfig.MemoryMax = lib.mkForce null;
597 dbusReload.configuration = { config, ... }: let
600 "broker" = "dbus-broker";
601 }.${config.services.dbus.implementation};
603 # We want to make sure that stc catches this as a reload,
605 systemd.services.${dbusService}.restartTriggers = [
606 (pkgs.writeText "dbus-reload-dummy" "dbus reload dummy")
613 system.switch.enable = true;
614 users.mutableUsers = true;
618 testScript = { nodes, ... }: let
619 originalSystem = nodes.machine.system.build.toplevel;
620 otherSystem = nodes.other.system.build.toplevel;
621 machine = nodes.machine.system.build.toplevel;
623 # Ensures failures pass through using pipefail, otherwise failing to
624 # switch-to-configuration is hidden by the success of `tee`.
625 stderrRunner = pkgs.writeScript "stderr-runner" ''
626 #! ${pkgs.runtimeShell}
629 exec env -i "$@" | tee /dev/stderr
632 # Returns a comma separated representation of the given list in sorted
633 # order, that matches the output format of switch-to-configuration.pl
634 sortedUnits = xs: lib.concatStringsSep ", " (builtins.sort builtins.lessThan xs);
637 "dbus" = "dbus.service";
638 "broker" = "dbus-broker.service";
639 }.${nodes.machine.services.dbus.implementation};
641 def switch_to_specialisation(system, name, action="test", fail=False):
643 switcher = f"{system}/bin/switch-to-configuration"
645 switcher = f"{system}/specialisation/{name}/bin/switch-to-configuration"
646 return run_switch(switcher, action, fail)
648 # like above but stc = switcher
649 def run_switch(switcher, action="test", fail=False):
650 out = machine.fail(f"{switcher} {action} 2>&1") if fail \
651 else machine.succeed(f"{switcher} {action} 2>&1")
652 assert_lacks(out, "switch-to-configuration line") # Perl warnings
655 def assert_contains(haystack, needle):
656 if needle not in haystack:
657 print("The haystack that will cause the following exception is:")
661 raise Exception(f"Expected string '{needle}' was not found")
663 def assert_lacks(haystack, needle):
664 if needle in haystack:
665 print("The haystack that will cause the following exception is:")
667 print(haystack, end="")
669 raise Exception(f"Unexpected string '{needle}' was found")
672 machine.wait_for_unit("multi-user.target")
675 "${stderrRunner} ${originalSystem}/bin/switch-to-configuration test"
677 # This tests whether the /etc/os-release parser works which is a fallback
678 # when /etc/NIXOS is missing. If the parser does not work, switch-to-configuration
680 machine.succeed("rm /etc/NIXOS")
682 "${stderrRunner} ${otherSystem}/bin/switch-to-configuration test"
685 boot_loader_text = "Warning: do not know how to make this configuration bootable; please enable a boot loader."
687 with subtest("actions"):
689 out = switch_to_specialisation("${machine}", "simpleService", action="boot")
690 assert_contains(out, boot_loader_text)
691 assert_lacks(out, "activating the configuration...") # good indicator of a system activation
694 out = switch_to_specialisation("${machine}", "", action="switch")
695 assert_contains(out, boot_loader_text)
696 assert_contains(out, "activating the configuration...") # good indicator of a system activation
698 # test and dry-activate actions are tested further down below
700 # invalid action fails the script
701 switch_to_specialisation("${machine}", "", action="broken-action", fail=True)
702 # no action fails the script
703 assert "Usage:" in machine.fail("${machine}/bin/switch-to-configuration 2>&1")
705 with subtest("init interface version"):
706 # Do not try to switch to an invalid init interface version
707 assert "incompatible" in switch_to_specialisation("${machine}", "brokenInitInterface", fail=True)
709 with subtest("systemd restarts"):
710 # systemd is restarted when its system.conf changes
711 out = switch_to_specialisation("${machine}", "modifiedSystemConf")
712 assert_contains(out, "restarting systemd...")
714 with subtest("continuing from an aborted switch"):
715 # An aborted switch will write into a file what it tried to start
716 # and a second switch should continue from this
717 machine.succeed("echo ${dbusService} > /run/nixos/start-list")
718 out = switch_to_specialisation("${machine}", "modifiedSystemConf")
719 assert_contains(out, "starting the following units: ${dbusService}\n")
721 with subtest("fstab mounts"):
722 switch_to_specialisation("${machine}", "")
724 out = switch_to_specialisation("${machine}", "addedMount")
725 assert_lacks(out, "stopping the following units:")
726 assert_lacks(out, "NOT restarting the following changed units:")
727 assert_lacks(out, "\nrestarting the following units:")
728 assert_lacks(out, "\nstarting the following units:")
729 assert_contains(out, "the following new units were started: test.mount\n")
730 # modify the mountpoint's options
731 out = switch_to_specialisation("${machine}", "addedMountOptsModified")
732 assert_lacks(out, "stopping the following units:")
733 assert_lacks(out, "NOT restarting the following changed units:")
734 assert_contains(out, "reloading the following units: test.mount\n")
735 assert_lacks(out, "\nrestarting the following units:")
736 assert_lacks(out, "\nstarting the following units:")
737 assert_lacks(out, "the following new units were started:")
739 out = switch_to_specialisation("${machine}", "addedMountDevModified")
740 assert_lacks(out, "stopping the following units:")
741 assert_lacks(out, "NOT restarting the following changed units:")
742 assert_lacks(out, "reloading the following units:")
743 assert_contains(out, "\nrestarting the following units: test.mount\n")
744 assert_lacks(out, "\nstarting the following units:")
745 assert_lacks(out, "the following new units were started:")
747 out = switch_to_specialisation("${machine}", "addedMount")
748 assert_lacks(out, "stopping the following units:")
749 assert_lacks(out, "NOT restarting the following changed units:")
750 assert_lacks(out, "reloading the following units:")
751 assert_contains(out, "\nrestarting the following units: test.mount\n")
752 assert_lacks(out, "\nstarting the following units:")
753 assert_lacks(out, "the following new units were started:")
755 out = switch_to_specialisation("${machine}", "")
756 assert_contains(out, "stopping the following units: test.mount\n")
757 assert_lacks(out, "NOT restarting the following changed units:")
758 assert_lacks(out, "reloading the following units:")
759 assert_lacks(out, "\nrestarting the following units:")
760 assert_lacks(out, "\nstarting the following units:")
761 assert_lacks(out, "the following new units were started:")
762 # change something about the / mount
763 out = switch_to_specialisation("${machine}", "storeMountModified")
764 assert_lacks(out, "stopping the following units:")
765 assert_contains(out, "NOT restarting the following changed units: -.mount")
766 assert_lacks(out, "reloading the following units:")
767 assert_lacks(out, "\nrestarting the following units:")
768 assert_lacks(out, "\nstarting the following units:")
769 assert_lacks(out, "the following new units were started:")
771 with subtest("swaps"):
772 switch_to_specialisation("${machine}", "")
774 out = switch_to_specialisation("${machine}", "swap")
775 assert_lacks(out, "stopping the following units:")
776 assert_lacks(out, "NOT restarting the following changed units:")
777 assert_lacks(out, "reloading the following units:")
778 assert_lacks(out, "\nrestarting the following units:")
779 assert_lacks(out, "\nstarting the following units:")
780 assert_contains(out, "the following new units were started: swapfile.swap")
782 out = switch_to_specialisation("${machine}", "")
783 assert_contains(out, "stopping swap device: /swapfile")
784 assert_lacks(out, "stopping the following units:")
785 assert_lacks(out, "NOT restarting the following changed units:")
786 assert_lacks(out, "reloading the following units:")
787 assert_lacks(out, "\nrestarting the following units:")
788 assert_lacks(out, "\nstarting the following units:")
789 assert_lacks(out, "the following new units were started:")
791 with subtest("services"):
792 switch_to_specialisation("${machine}", "")
793 # Nothing happens when nothing is changed
794 out = switch_to_specialisation("${machine}", "")
795 assert_lacks(out, "stopping the following units:")
796 assert_lacks(out, "NOT restarting the following changed units:")
797 assert_lacks(out, "reloading the following units:")
798 assert_lacks(out, "\nrestarting the following units:")
799 assert_lacks(out, "\nstarting the following units:")
800 assert_lacks(out, "the following new units were started:")
802 # Start a simple service
803 out = switch_to_specialisation("${machine}", "simpleService")
804 assert_lacks(out, boot_loader_text) # test does not install a bootloader
805 assert_lacks(out, "stopping the following units:")
806 assert_lacks(out, "NOT restarting the following changed units:")
807 assert_lacks(out, "reloading the following units:")
808 assert_lacks(out, "\nrestarting the following units:")
809 assert_lacks(out, "\nstarting the following units:")
810 assert_contains(out, "the following new units were started: test.service\n")
812 # Not changing anything doesn't do anything
813 out = switch_to_specialisation("${machine}", "simpleService")
814 assert_lacks(out, "stopping the following units:")
815 assert_lacks(out, "NOT restarting the following changed units:")
816 assert_lacks(out, "reloading the following units:")
817 assert_lacks(out, "\nrestarting the following units:")
818 assert_lacks(out, "\nstarting the following units:")
819 assert_lacks(out, "the following new units were started:")
821 # Only changing the description does nothing
822 out = switch_to_specialisation("${machine}", "simpleServiceDifferentDescription")
823 assert_lacks(out, "stopping the following units:")
824 assert_lacks(out, "NOT restarting the following changed units:")
825 assert_lacks(out, "reloading the following units:")
826 assert_lacks(out, "\nrestarting the following units:")
827 assert_lacks(out, "\nstarting the following units:")
828 assert_lacks(out, "the following new units were started:")
830 # Restart the simple service
831 out = switch_to_specialisation("${machine}", "simpleServiceModified")
832 assert_contains(out, "stopping the following units: test.service\n")
833 assert_lacks(out, "NOT restarting the following changed units:")
834 assert_lacks(out, "reloading the following units:")
835 assert_lacks(out, "\nrestarting the following units:")
836 assert_contains(out, "\nstarting the following units: test.service\n")
837 assert_lacks(out, "the following new units were started:")
839 # Restart the service with stopIfChanged=false
840 out = switch_to_specialisation("${machine}", "simpleServiceNostop")
841 assert_lacks(out, "stopping the following units:")
842 assert_lacks(out, "NOT restarting the following changed units:")
843 assert_lacks(out, "reloading the following units:")
844 assert_contains(out, "\nrestarting the following units: test.service\n")
845 assert_lacks(out, "\nstarting the following units:")
846 assert_lacks(out, "the following new units were started:")
848 # Reload the service with reloadIfChanged=true
849 out = switch_to_specialisation("${machine}", "simpleServiceReload")
850 assert_lacks(out, "stopping the following units:")
851 assert_lacks(out, "NOT restarting the following changed units:")
852 assert_contains(out, "reloading the following units: test.service\n")
853 assert_lacks(out, "\nrestarting the following units:")
854 assert_lacks(out, "\nstarting the following units:")
855 assert_lacks(out, "the following new units were started:")
857 # Nothing happens when restartIfChanged=false
858 out = switch_to_specialisation("${machine}", "simpleServiceNorestart")
859 assert_lacks(out, "stopping the following units:")
860 assert_contains(out, "NOT restarting the following changed units: test.service\n")
861 assert_lacks(out, "reloading the following units:")
862 assert_lacks(out, "\nrestarting the following units:")
863 assert_lacks(out, "\nstarting the following units:")
864 assert_lacks(out, "the following new units were started:")
866 # Dry mode shows different messages
867 out = switch_to_specialisation("${machine}", "simpleService", action="dry-activate")
868 assert_lacks(out, "stopping the following units:")
869 assert_lacks(out, "NOT restarting the following changed units:")
870 assert_lacks(out, "reloading the following units:")
871 assert_lacks(out, "\nrestarting the following units:")
872 assert_lacks(out, "\nstarting the following units:")
873 assert_lacks(out, "the following new units were started:")
874 assert_contains(out, "would start the following units: test.service\n")
876 out = switch_to_specialisation("${machine}", "", action="test")
878 # Ensure the service can be started when the activation script isn't in toplevel
879 # This is a lot like "Start a simple service", except activation-only deps could be gc-ed
880 out = run_switch("${nodes.machine.specialisation.simpleServiceSeparateActivationScript.configuration.system.build.separateActivationScript}/bin/switch-to-configuration");
881 assert_lacks(out, boot_loader_text) # test does not install a bootloader
882 assert_lacks(out, "stopping the following units:")
883 assert_lacks(out, "NOT restarting the following changed units:")
884 assert_lacks(out, "reloading the following units:")
885 assert_lacks(out, "\nrestarting the following units:")
886 assert_lacks(out, "\nstarting the following units:")
887 assert_contains(out, "the following new units were started: test.service\n")
888 machine.succeed("! test -e /run/current-system/activate")
889 machine.succeed("! test -e /run/current-system/dry-activate")
890 machine.succeed("! test -e /run/current-system/bin/switch-to-configuration")
892 # Ensure units with multiline values work
893 out = switch_to_specialisation("${machine}", "unitWithMultilineValue")
894 assert_lacks(out, "NOT restarting the following changed units:")
895 assert_lacks(out, "reloading the following units:")
896 assert_lacks(out, "restarting the following units:")
897 assert_lacks(out, "the following new units were started:")
898 assert_contains(out, "starting the following units: test.service")
900 # Ensure \ works in unit names
901 out = switch_to_specialisation("${machine}", "unitWithBackslash")
902 assert_lacks(out, "NOT restarting the following changed units:")
903 assert_lacks(out, "reloading the following units:")
904 assert_lacks(out, "\nrestarting the following units:")
905 assert_lacks(out, "\nstarting the following units:")
906 assert_contains(out, "the following new units were started: escaped\\x2ddash.service\n")
908 out = switch_to_specialisation("${machine}", "unitWithBackslashModified")
909 assert_contains(out, "stopping the following units: escaped\\x2ddash.service\n")
910 assert_lacks(out, "NOT restarting the following changed units:")
911 assert_lacks(out, "reloading the following units:")
912 assert_lacks(out, "\nrestarting the following units:")
913 assert_contains(out, "\nstarting the following units: escaped\\x2ddash.service\n")
914 assert_lacks(out, "the following new units were started:")
916 # Ensure units can start with a dash
917 out = switch_to_specialisation("${machine}", "unitStartingWithDash")
918 assert_contains(out, "stopping the following units: escaped\\x2ddash.service\n")
919 assert_lacks(out, "NOT restarting the following changed units:")
920 assert_lacks(out, "reloading the following units:")
921 assert_lacks(out, "\nrestarting the following units:")
922 assert_lacks(out, "\nstarting the following units:")
923 assert_contains(out, "the following new units were started: -.service\n")
925 # The regression only occurs when reloading units
926 out = switch_to_specialisation("${machine}", "unitStartingWithDashModified")
927 assert_lacks(out, "stopping the following units:")
928 assert_lacks(out, "NOT restarting the following changed units:")
929 assert_contains(out, "reloading the following units: -.service")
930 assert_lacks(out, "\nrestarting the following units:")
931 assert_lacks(out, "\nstarting the following units:")
932 assert_lacks(out, "the following new units were started:")
934 # Ensure units that require changed units are properly reloaded
935 out = switch_to_specialisation("${machine}", "unitWithRequirement")
936 assert_contains(out, "stopping the following units: -.service\n")
937 assert_lacks(out, "NOT restarting the following changed units:")
938 assert_lacks(out, "reloading the following units:")
939 assert_lacks(out, "\nrestarting the following units:")
940 assert_lacks(out, "\nstarting the following units:")
941 assert_contains(out, "the following new units were started: required-service.service, test-service.service\n")
943 out = switch_to_specialisation("${machine}", "unitWithRequirementModified")
944 assert_contains(out, "stopping the following units: required-service.service\n")
945 assert_lacks(out, "NOT restarting the following changed units:")
946 assert_lacks(out, "reloading the following units:")
947 assert_lacks(out, "\nrestarting the following units:")
948 assert_contains(out, "\nstarting the following units: required-service.service, test-service.service\n")
949 assert_lacks(out, "the following new units were started:")
951 # Unless the unit asks to be not restarted
952 out = switch_to_specialisation("${machine}", "unitWithRequirementModifiedNostart")
953 assert_contains(out, "stopping the following units: required-service.service\n")
954 assert_lacks(out, "NOT restarting the following changed units:")
955 assert_lacks(out, "reloading the following units:")
956 assert_lacks(out, "\nrestarting the following units:")
957 assert_contains(out, "\nstarting the following units: required-service.service\n")
958 assert_lacks(out, "the following new units were started:")
960 # Ensure templated units are restarted when the base unit changes
961 switch_to_specialisation("${machine}", "unitWithTemplate")
962 out = switch_to_specialisation("${machine}", "unitWithTemplateModified")
963 assert_contains(out, "stopping the following units: instantiated@one.service, instantiated@two.service\n")
964 assert_lacks(out, "NOT restarting the following changed units:")
965 assert_lacks(out, "reloading the following units:")
966 assert_lacks(out, "\nrestarting the following units:")
967 assert_contains(out, "\nstarting the following units: instantiated@one.service, instantiated@two.service\n")
968 assert_lacks(out, "the following new units were started:")
970 with subtest("failing units"):
971 # Let the simple service fail
972 switch_to_specialisation("${machine}", "simpleServiceModified")
973 out = switch_to_specialisation("${machine}", "simpleServiceFailing", fail=True)
974 assert_contains(out, "stopping the following units: test.service\n")
975 assert_lacks(out, "NOT restarting the following changed units:")
976 assert_lacks(out, "reloading the following units:")
977 assert_lacks(out, "\nrestarting the following units:")
978 assert_contains(out, "\nstarting the following units: test.service\n")
979 assert_lacks(out, "the following new units were started:")
980 assert_contains(out, "warning: the following units failed: test.service\n")
981 assert_contains(out, "Main PID:") # output of systemctl
983 # A unit that gets into autorestart without failing is not treated as failed
984 out = switch_to_specialisation("${machine}", "autorestartService")
985 assert_lacks(out, "stopping the following units:")
986 assert_lacks(out, "NOT restarting the following changed units:")
987 assert_lacks(out, "reloading the following units:")
988 assert_lacks(out, "\nrestarting the following units:")
989 assert_lacks(out, "\nstarting the following units:")
990 assert_contains(out, "the following new units were started: autorestart.service\n")
991 machine.systemctl('stop autorestart.service') # cancel the 20y timer
993 # Switching to the same system should do nothing (especially not treat the unit as failed)
994 out = switch_to_specialisation("${machine}", "autorestartService")
995 assert_lacks(out, "stopping the following units:")
996 assert_lacks(out, "NOT restarting the following changed units:")
997 assert_lacks(out, "reloading the following units:")
998 assert_lacks(out, "\nrestarting the following units:")
999 assert_lacks(out, "\nstarting the following units:")
1000 assert_contains(out, "the following new units were started: autorestart.service\n")
1001 machine.systemctl('stop autorestart.service') # cancel the 20y timer
1003 # If systemd thinks the unit has failed and is in autorestart, we should show it as failed
1004 out = switch_to_specialisation("${machine}", "autorestartServiceFailing", fail=True)
1005 assert_lacks(out, "stopping the following units:")
1006 assert_lacks(out, "NOT restarting the following changed units:")
1007 assert_lacks(out, "reloading the following units:")
1008 assert_lacks(out, "\nrestarting the following units:")
1009 assert_lacks(out, "\nstarting the following units:")
1010 assert_lacks(out, "the following new units were started:")
1011 assert_contains(out, "warning: the following units failed: autorestart.service\n")
1012 assert_contains(out, "Main PID:") # output of systemctl
1014 with subtest("unit file parser"):
1015 # Switch to a well-known state
1016 switch_to_specialisation("${machine}", "simpleServiceNostop")
1019 out = switch_to_specialisation("${machine}", "simpleServiceWithExtraSection")
1020 assert_lacks(out, "stopping the following units:")
1021 assert_lacks(out, "NOT restarting the following changed units:")
1022 assert_lacks(out, "reloading the following units:")
1023 assert_contains(out, "\nrestarting the following units: test.service\n")
1024 assert_lacks(out, "\nstarting the following units:")
1025 assert_lacks(out, "the following new units were started:")
1028 out = switch_to_specialisation("${machine}", "simpleServiceWithExtraSectionOtherName")
1029 assert_lacks(out, "stopping the following units:")
1030 assert_lacks(out, "NOT restarting the following changed units:")
1031 assert_lacks(out, "reloading the following units:")
1032 assert_contains(out, "\nrestarting the following units: test.service\n")
1033 assert_lacks(out, "\nstarting the following units:")
1034 assert_lacks(out, "the following new units were started:")
1037 out = switch_to_specialisation("${machine}", "simpleServiceNostop")
1038 assert_lacks(out, "stopping the following units:")
1039 assert_lacks(out, "NOT restarting the following changed units:")
1040 assert_lacks(out, "reloading the following units:")
1041 assert_contains(out, "\nrestarting the following units: test.service\n")
1042 assert_lacks(out, "\nstarting the following units:")
1043 assert_lacks(out, "the following new units were started:")
1045 # [Install] section is ignored
1046 out = switch_to_specialisation("${machine}", "simpleServiceWithInstallSection")
1047 assert_lacks(out, "stopping the following units:")
1048 assert_lacks(out, "NOT restarting the following changed units:")
1049 assert_lacks(out, "reloading the following units:")
1050 assert_lacks(out, "\nrestarting the following units:")
1051 assert_lacks(out, "\nstarting the following units:")
1052 assert_lacks(out, "the following new units were started:")
1055 out = switch_to_specialisation("${machine}", "simpleServiceWithExtraKey")
1056 assert_lacks(out, "stopping the following units:")
1057 assert_lacks(out, "NOT restarting the following changed units:")
1058 assert_lacks(out, "reloading the following units:")
1059 assert_contains(out, "\nrestarting the following units: test.service\n")
1060 assert_lacks(out, "\nstarting the following units:")
1061 assert_lacks(out, "the following new units were started:")
1064 out = switch_to_specialisation("${machine}", "simpleServiceWithExtraKeyOtherValue")
1065 assert_lacks(out, "stopping the following units:")
1066 assert_lacks(out, "NOT restarting the following changed units:")
1067 assert_lacks(out, "reloading the following units:")
1068 assert_contains(out, "\nrestarting the following units: test.service\n")
1069 assert_lacks(out, "\nstarting the following units:")
1070 assert_lacks(out, "the following new units were started:")
1073 out = switch_to_specialisation("${machine}", "simpleServiceWithExtraKeyOtherName")
1074 assert_lacks(out, "stopping the following units:")
1075 assert_lacks(out, "NOT restarting the following changed units:")
1076 assert_lacks(out, "reloading the following units:")
1077 assert_contains(out, "\nrestarting the following units: test.service\n")
1078 assert_lacks(out, "\nstarting the following units:")
1079 assert_lacks(out, "the following new units were started:")
1082 out = switch_to_specialisation("${machine}", "simpleServiceNostop")
1083 assert_lacks(out, "stopping the following units:")
1084 assert_lacks(out, "NOT restarting the following changed units:")
1085 assert_lacks(out, "reloading the following units:")
1086 assert_contains(out, "\nrestarting the following units: test.service\n")
1087 assert_lacks(out, "\nstarting the following units:")
1088 assert_lacks(out, "the following new units were started:")
1090 # Add a reload trigger
1091 out = switch_to_specialisation("${machine}", "simpleServiceReloadTrigger")
1092 assert_lacks(out, "stopping the following units:")
1093 assert_lacks(out, "NOT restarting the following changed units:")
1094 assert_contains(out, "reloading the following units: test.service\n")
1095 assert_lacks(out, "\nrestarting the following units:")
1096 assert_lacks(out, "\nstarting the following units:")
1097 assert_lacks(out, "the following new units were started:")
1099 # Modify the reload trigger
1100 out = switch_to_specialisation("${machine}", "simpleServiceReloadTriggerModified")
1101 assert_lacks(out, "stopping the following units:")
1102 assert_lacks(out, "NOT restarting the following changed units:")
1103 assert_contains(out, "reloading the following units: test.service\n")
1104 assert_lacks(out, "\nrestarting the following units:")
1105 assert_lacks(out, "\nstarting the following units:")
1106 assert_lacks(out, "the following new units were started:")
1108 # Modify the reload trigger and something else
1109 out = switch_to_specialisation("${machine}", "simpleServiceReloadTriggerModifiedAndSomethingElse")
1110 assert_lacks(out, "stopping the following units:")
1111 assert_lacks(out, "NOT restarting the following changed units:")
1112 assert_lacks(out, "reloading the following units:")
1113 assert_contains(out, "\nrestarting the following units: test.service\n")
1114 assert_lacks(out, "\nstarting the following units:")
1115 assert_lacks(out, "the following new units were started:")
1117 # Remove the reload trigger
1118 out = switch_to_specialisation("${machine}", "simpleServiceReloadTriggerModifiedSomethingElse")
1119 assert_lacks(out, "stopping the following units:")
1120 assert_lacks(out, "NOT restarting the following changed units:")
1121 assert_lacks(out, "reloading the following units:")
1122 assert_lacks(out, "\nrestarting the following units:")
1123 assert_lacks(out, "\nstarting the following units:")
1124 assert_lacks(out, "the following new units were started:")
1126 with subtest("restart and reload by activation script"):
1127 switch_to_specialisation("${machine}", "simpleServiceNorestart")
1128 out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script")
1129 assert_contains(out, "stopping the following units: test.service\n")
1130 assert_lacks(out, "NOT restarting the following changed units:")
1131 assert_lacks(out, "reloading the following units:")
1132 assert_lacks(out, "restarting the following units:")
1133 assert_contains(out, "\nstarting the following units: ${sortedUnits [
1134 "no-restart-service.service"
1135 "reload-triggers-and-restart-by-as.service"
1136 "simple-reload-service.service"
1137 "simple-restart-service.service"
1138 "simple-service.service"
1139 "templated-no-restart-service@instance.service"
1140 "templated-reload-triggers-and-restart-by-as@instance.service"
1141 "templated-simple-reload-service@instance.service"
1142 "templated-simple-restart-service@instance.service"
1143 "templated-simple-service@instance.service"
1145 assert_contains(out, "the following new units were started: ${sortedUnits [
1146 "no-restart-service.service"
1147 "reload-triggers-and-restart-by-as.service"
1148 "reload-triggers-and-restart.service"
1149 "reload-triggers.service"
1150 "simple-reload-service.service"
1151 "simple-restart-service.service"
1152 "simple-service.service"
1153 "system-templated\\\\x2dno\\\\x2drestart\\\\x2dservice.slice"
1154 "system-templated\\\\x2dreload\\\\x2dtriggers.slice"
1155 "system-templated\\\\x2dreload\\\\x2dtriggers\\\\x2dand\\\\x2drestart.slice"
1156 "system-templated\\\\x2dreload\\\\x2dtriggers\\\\x2dand\\\\x2drestart\\\\x2dby\\\\x2das.slice"
1157 "system-templated\\\\x2dsimple\\\\x2dreload\\\\x2dservice.slice"
1158 "system-templated\\\\x2dsimple\\\\x2drestart\\\\x2dservice.slice"
1159 "system-templated\\\\x2dsimple\\\\x2dservice.slice"
1160 "templated-no-restart-service@instance.service"
1161 "templated-reload-triggers-and-restart-by-as@instance.service"
1162 "templated-reload-triggers-and-restart@instance.service"
1163 "templated-reload-triggers@instance.service"
1164 "templated-simple-reload-service@instance.service"
1165 "templated-simple-restart-service@instance.service"
1166 "templated-simple-service@instance.service"
1168 # Switch to the same system where the example services get restarted
1169 # and reloaded by the activation script
1170 out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script")
1171 assert_lacks(out, "stopping the following units:")
1172 assert_lacks(out, "NOT restarting the following changed units:")
1173 assert_contains(out, "reloading the following units: ${sortedUnits [
1174 "reload-triggers-and-restart.service"
1175 "reload-triggers.service"
1176 "simple-reload-service.service"
1177 "templated-reload-triggers-and-restart@instance.service"
1178 "templated-reload-triggers@instance.service"
1179 "templated-simple-reload-service@instance.service"
1181 assert_contains(out, "restarting the following units: ${sortedUnits [
1182 "reload-triggers-and-restart-by-as.service"
1183 "simple-restart-service.service"
1184 "simple-service.service"
1185 "templated-reload-triggers-and-restart-by-as@instance.service"
1186 "templated-simple-restart-service@instance.service"
1187 "templated-simple-service@instance.service"
1189 assert_lacks(out, "\nstarting the following units:")
1190 assert_lacks(out, "the following new units were started:")
1191 # Switch to the same system and see if the service gets restarted when it's modified
1192 # while the fact that it's supposed to be reloaded by the activation script is ignored.
1193 out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script-modified")
1194 assert_lacks(out, "stopping the following units:")
1195 assert_lacks(out, "NOT restarting the following changed units:")
1196 assert_contains(out, "reloading the following units: ${sortedUnits [
1197 "reload-triggers.service"
1198 "simple-reload-service.service"
1199 "templated-reload-triggers@instance.service"
1200 "templated-simple-reload-service@instance.service"
1202 assert_contains(out, "restarting the following units: ${sortedUnits [
1203 "reload-triggers-and-restart-by-as.service"
1204 "reload-triggers-and-restart.service"
1205 "simple-restart-service.service"
1206 "simple-service.service"
1207 "templated-reload-triggers-and-restart-by-as@instance.service"
1208 "templated-reload-triggers-and-restart@instance.service"
1209 "templated-simple-restart-service@instance.service"
1210 "templated-simple-service@instance.service"
1212 assert_lacks(out, "\nstarting the following units:")
1213 assert_lacks(out, "the following new units were started:")
1214 # The same, but in dry mode
1215 out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script", action="dry-activate")
1216 assert_lacks(out, "would stop the following units:")
1217 assert_lacks(out, "would NOT stop the following changed units:")
1218 assert_contains(out, "would reload the following units: ${sortedUnits [
1219 "reload-triggers.service"
1220 "simple-reload-service.service"
1221 "templated-reload-triggers@instance.service"
1222 "templated-simple-reload-service@instance.service"
1224 assert_contains(out, "would restart the following units: ${sortedUnits [
1225 "reload-triggers-and-restart-by-as.service"
1226 "reload-triggers-and-restart.service"
1227 "simple-restart-service.service"
1228 "simple-service.service"
1229 "templated-reload-triggers-and-restart-by-as@instance.service"
1230 "templated-reload-triggers-and-restart@instance.service"
1231 "templated-simple-restart-service@instance.service"
1232 "templated-simple-service@instance.service"
1234 assert_lacks(out, "\nwould start the following units:")
1236 with subtest("socket-activated services"):
1237 # Socket-activated services don't get started, just the socket
1238 machine.fail("[ -S /run/test.sock ]")
1239 out = switch_to_specialisation("${machine}", "simple-socket")
1240 # assert_lacks(out, "stopping the following units:") not relevant
1241 assert_lacks(out, "NOT restarting the following changed units:")
1242 assert_lacks(out, "reloading the following units:")
1243 assert_lacks(out, "\nrestarting the following units:")
1244 assert_lacks(out, "\nstarting the following units:")
1245 assert_contains(out, "the following new units were started: socket-activated.socket\n")
1246 machine.succeed("[ -S /run/test.sock ]")
1248 # Changing a non-activated service does nothing
1249 out = switch_to_specialisation("${machine}", "simple-socket-service-modified")
1250 assert_lacks(out, "stopping the following units:")
1251 assert_lacks(out, "NOT restarting the following changed units:")
1252 assert_lacks(out, "reloading the following units:")
1253 assert_lacks(out, "\nrestarting the following units:")
1254 assert_lacks(out, "\nstarting the following units:")
1255 assert_lacks(out, "the following new units were started:")
1256 machine.succeed("[ -S /run/test.sock ]")
1257 # The unit is properly activated when the socket is accessed
1258 if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello":
1259 raise Exception("Socket was not properly activated") # idk how that would happen tbh
1261 # Changing an activated service with stopIfChanged=false restarts the service
1262 out = switch_to_specialisation("${machine}", "simple-socket")
1263 assert_lacks(out, "stopping the following units:")
1264 assert_lacks(out, "NOT restarting the following changed units:")
1265 assert_lacks(out, "reloading the following units:")
1266 assert_contains(out, "\nrestarting the following units: socket-activated.service\n")
1267 assert_lacks(out, "\nstarting the following units:")
1268 assert_lacks(out, "the following new units were started:")
1269 machine.succeed("[ -S /run/test.sock ]")
1270 # Socket-activation of the unit still works
1271 if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello":
1272 raise Exception("Socket was not properly activated after the service was restarted")
1274 # Changing an activated service with stopIfChanged=true stops the service and
1275 # socket and starts the socket
1276 out = switch_to_specialisation("${machine}", "simple-socket-stop-if-changed")
1277 assert_contains(out, "stopping the following units: socket-activated.service, socket-activated.socket\n")
1278 assert_lacks(out, "NOT restarting the following changed units:")
1279 assert_lacks(out, "reloading the following units:")
1280 assert_lacks(out, "\nrestarting the following units:")
1281 assert_contains(out, "\nstarting the following units: socket-activated.socket\n")
1282 assert_lacks(out, "the following new units were started:")
1283 machine.succeed("[ -S /run/test.sock ]")
1284 # Socket-activation of the unit still works
1285 if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello":
1286 raise Exception("Socket was not properly activated after the service was restarted")
1288 # Changing a reload trigger of a socket-activated unit only reloads it
1289 out = switch_to_specialisation("${machine}", "simple-socket-stop-if-changed-and-reloadtrigger")
1290 assert_lacks(out, "stopping the following units:")
1291 assert_lacks(out, "NOT restarting the following changed units:")
1292 assert_contains(out, "reloading the following units: socket-activated.service\n")
1293 assert_lacks(out, "\nrestarting the following units:")
1294 assert_lacks(out, "\nstarting the following units: socket-activated.socket")
1295 assert_lacks(out, "the following new units were started:")
1296 machine.succeed("[ -S /run/test.sock ]")
1297 # Socket-activation of the unit still works
1298 if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello":
1299 raise Exception("Socket was not properly activated after the service was restarted")
1301 with subtest("mounts"):
1302 switch_to_specialisation("${machine}", "mount")
1303 out = machine.succeed("mount | grep 'on /testmount'")
1304 assert_contains(out, "size=1024k")
1305 # Changing options reloads the unit
1306 out = switch_to_specialisation("${machine}", "mountOptionsModified")
1307 assert_lacks(out, "stopping the following units:")
1308 assert_lacks(out, "NOT restarting the following changed units:")
1309 assert_contains(out, "reloading the following units: testmount.mount\n")
1310 assert_lacks(out, "\nrestarting the following units:")
1311 assert_lacks(out, "\nstarting the following units:")
1312 assert_lacks(out, "the following new units were started:")
1314 out = machine.succeed("mount | grep 'on /testmount'")
1315 assert_contains(out, "size=10240k")
1316 # Changing anything but `Options=` restarts the unit
1317 out = switch_to_specialisation("${machine}", "mountModified")
1318 assert_lacks(out, "stopping the following units:")
1319 assert_lacks(out, "NOT restarting the following changed units:")
1320 assert_lacks(out, "reloading the following units:")
1321 assert_contains(out, "\nrestarting the following units: testmount.mount\n")
1322 assert_lacks(out, "\nstarting the following units:")
1323 assert_lacks(out, "the following new units were started:")
1325 out = machine.succeed("mount | grep 'on /testmount'")
1326 assert_contains(out, "ramfs")
1328 with subtest("timers"):
1329 switch_to_specialisation("${machine}", "timer")
1330 out = machine.succeed("systemctl show test-timer.timer")
1331 assert_contains(out, "OnCalendar=2014-03-25 02:59:56 UTC")
1332 out = switch_to_specialisation("${machine}", "timerModified")
1333 assert_lacks(out, "stopping the following units:")
1334 assert_lacks(out, "NOT restarting the following units:")
1335 assert_lacks(out, "reloading the following units:")
1336 assert_contains(out, "\nrestarting the following units: test-timer.timer\n")
1337 assert_lacks(out, "\nstarting the following units:")
1338 assert_lacks(out, "the following new units were started:")
1340 out = machine.succeed("systemctl show test-timer.timer")
1341 assert_contains(out, "OnCalendar=Fri 2012-11-23 16:00:00")
1343 with subtest("targets"):
1344 # Modifying some special targets like hybrid-sleep.target does nothing
1345 out = switch_to_specialisation("${machine}", "hybridSleepModified")
1346 assert_contains(out, "stopping the following units: test-timer.timer\n")
1347 assert_lacks(out, "NOT restarting the following changed units:")
1348 assert_lacks(out, "reloading the following units:")
1349 assert_lacks(out, "\nrestarting the following units:")
1350 assert_lacks(out, "\nstarting the following units:")
1351 assert_lacks(out, "the following new units were started:")
1353 # Adding a new target starts it
1354 out = switch_to_specialisation("${machine}", "target")
1355 assert_lacks(out, "stopping the following units:")
1356 assert_lacks(out, "NOT restarting the following changed units:")
1357 assert_lacks(out, "reloading the following units:")
1358 assert_lacks(out, "\nrestarting the following units:")
1359 assert_lacks(out, "\nstarting the following units:")
1360 assert_contains(out, "the following new units were started: test-target.target\n")
1362 # Changing a target doesn't print anything because the unit is filtered
1363 machine.systemctl("start test-service.service")
1364 out = switch_to_specialisation("${machine}", "targetModified")
1365 assert_lacks(out, "stopping the following units:")
1366 assert_lacks(out, "NOT restarting the following changed units:")
1367 assert_lacks(out, "reloading the following units:")
1368 assert_lacks(out, "\nrestarting the following units:")
1369 assert_lacks(out, "\nstarting the following units:")
1370 assert_lacks(out, "the following new units were started:")
1371 machine.succeed("systemctl is-active test-service.service") # target was not restarted
1373 # With X-StopOnReconfiguration, the target gets stopped and started
1374 out = switch_to_specialisation("${machine}", "targetModifiedStopOnReconfig")
1375 assert_lacks(out, "stopping the following units:")
1376 assert_lacks(out, "NOT restarting the following changed units:")
1377 assert_lacks(out, "reloading the following units:")
1378 assert_lacks(out, "\nrestarting the following units:")
1379 assert_lacks(out, "\nstarting the following units:")
1380 assert_lacks(out, "the following new units were started:")
1381 machine.fail("systemctl is-active test-service.servce") # target was restarted
1383 # Remove the target by switching to the old specialisation
1384 out = switch_to_specialisation("${machine}", "timerModified")
1385 assert_contains(out, "stopping the following units: test-target.target\n")
1386 assert_lacks(out, "NOT restarting the following changed units:")
1387 assert_lacks(out, "reloading the following units:")
1388 assert_lacks(out, "\nrestarting the following units:")
1389 assert_lacks(out, "\nstarting the following units:")
1390 assert_contains(out, "the following new units were started: test-timer.timer\n")
1392 with subtest("paths"):
1393 out = switch_to_specialisation("${machine}", "path")
1394 assert_contains(out, "stopping the following units: test-timer.timer\n")
1395 assert_lacks(out, "NOT restarting the following changed units:")
1396 assert_lacks(out, "reloading the following units:")
1397 assert_lacks(out, "\nrestarting the following units:")
1398 assert_lacks(out, "\nstarting the following units:")
1399 assert_contains(out, "the following new units were started: test-watch.path\n")
1400 machine.fail("test -f /testpath-modified")
1402 # touch the file, unit should be triggered
1403 machine.succeed("touch /testpath")
1404 machine.wait_until_succeeds("test -f /testpath-modified")
1405 machine.succeed("rm /testpath /testpath-modified")
1406 machine.systemctl("stop test-watch.service")
1407 switch_to_specialisation("${machine}", "pathModified")
1408 machine.succeed("touch /testpath")
1409 machine.fail("test -f /testpath-modified")
1410 machine.succeed("touch /testpath2")
1411 machine.wait_until_succeeds("test -f /testpath-modified")
1413 # This test ensures that changes to slice configuration get applied.
1414 # We test this by having a slice that allows no memory allocation at
1415 # all and starting a service within it. If the service crashes, the slice
1416 # is applied and if we modify the slice to allow memory allocation, the
1417 # service should successfully start.
1418 with subtest("slices"):
1419 machine.succeed("echo 0 > /proc/sys/vm/panic_on_oom") # allow OOMing
1420 out = switch_to_specialisation("${machine}", "slice")
1421 # assert_lacks(out, "stopping the following units:") not relevant
1422 assert_lacks(out, "NOT restarting the following changed units:")
1423 assert_lacks(out, "reloading the following units:")
1424 assert_lacks(out, "\nrestarting the following units:")
1425 assert_lacks(out, "\nstarting the following units:")
1426 assert_lacks(out, "the following new units were started:")
1427 machine.fail("systemctl start testservice.service")
1429 out = switch_to_specialisation("${machine}", "sliceModified")
1430 assert_lacks(out, "stopping the following units:")
1431 assert_lacks(out, "NOT restarting the following changed units:")
1432 assert_lacks(out, "reloading the following units:")
1433 assert_lacks(out, "\nrestarting the following units:")
1434 assert_lacks(out, "\nstarting the following units:")
1435 assert_lacks(out, "the following new units were started:")
1436 machine.succeed("systemctl start testservice.service")
1437 machine.succeed("echo 1 > /proc/sys/vm/panic_on_oom") # disallow OOMing
1439 with subtest("dbus reloads"):
1440 out = switch_to_specialisation("${machine}", "")
1441 out = switch_to_specialisation("${machine}", "dbusReload")
1442 assert_lacks(out, "stopping the following units:")
1443 assert_lacks(out, "NOT restarting the following changed units:")
1444 assert_contains(out, "reloading the following units: ${dbusService}\n")
1445 assert_lacks(out, "\nrestarting the following units:")
1446 assert_lacks(out, "\nstarting the following units:")
1447 assert_lacks(out, "the following new units were started:")