at 23.11-beta 68 kB view raw
1# Test configuration switching. 2 3import ./make-test-python.nix ({ lib, pkgs, ...} : let 4 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 10 11 from socketserver import TCPServer, StreamRequestHandler 12 import socket 13 import os 14 15 16 class Handler(StreamRequestHandler): 17 def handle(self): 18 self.wfile.write("hello".encode("utf-8")) 19 20 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}') 26 TCPServer.__init__( 27 self, server_address, handler_cls, bind_and_activate=True) 28 else: 29 TCPServer.__init__( 30 self, server_address, handler_cls, bind_and_activate=False) 31 # Override socket 32 print(f'Got activated by {os.getenv("LISTEN_FDNAMES")} ' 33 f'with {listenFds} FDs') 34 self.socket = socket.fromfd(3, self.address_family, 35 self.socket_type) 36 37 38 if __name__ == "__main__": 39 server = Server(("localhost", 1234), Handler) 40 server.serve_forever() 41 ''; 42 43in { 44 name = "switch-test"; 45 meta = with pkgs.lib.maintainers; { 46 maintainers = [ gleber das_j ]; 47 }; 48 49 nodes = { 50 machine = { pkgs, lib, ... }: { 51 environment.systemPackages = [ pkgs.socat ]; # for the socket activation stuff 52 users.mutableUsers = false; 53 54 # For boot/switch testing 55 system.build.installBootLoader = lib.mkForce (pkgs.writeShellScript "install-dummy-loader" '' 56 echo "installing dummy bootloader" 57 touch /tmp/bootloader-installed 58 ''); 59 60 specialisation = rec { 61 brokenInitInterface.configuration.config.system.extraSystemBuilderCmds = '' 62 echo "systemd 0" > $out/init-interface-version 63 ''; 64 65 modifiedSystemConf.configuration.systemd.extraConfig = '' 66 # Hello world! 67 ''; 68 69 addedMount.configuration.virtualisation.fileSystems."/test" = { 70 device = "tmpfs"; 71 fsType = "tmpfs"; 72 }; 73 74 addedMountOptsModified.configuration = { 75 imports = [ addedMount.configuration ]; 76 virtualisation.fileSystems."/test".options = [ "x-test" ]; 77 }; 78 79 addedMountDevModified.configuration = { 80 imports = [ addedMountOptsModified.configuration ]; 81 virtualisation.fileSystems."/test".device = lib.mkForce "ramfs"; 82 }; 83 84 storeMountModified.configuration = { 85 virtualisation.fileSystems."/".device = lib.mkForce "auto"; 86 }; 87 88 swap.configuration.swapDevices = lib.mkVMOverride [ 89 { device = "/swapfile"; size = 1; } 90 ]; 91 92 simpleService.configuration = { 93 systemd.services.test = { 94 wantedBy = [ "multi-user.target" ]; 95 serviceConfig = { 96 Type = "oneshot"; 97 RemainAfterExit = true; 98 ExecStart = "${pkgs.coreutils}/bin/true"; 99 ExecReload = "${pkgs.coreutils}/bin/true"; 100 }; 101 }; 102 }; 103 104 simpleServiceSeparateActivationScript.configuration = { 105 system.activatable = false; 106 systemd.services.test = { 107 wantedBy = [ "multi-user.target" ]; 108 serviceConfig = { 109 Type = "oneshot"; 110 RemainAfterExit = true; 111 ExecStart = "${pkgs.coreutils}/bin/true"; 112 ExecReload = "${pkgs.coreutils}/bin/true"; 113 }; 114 }; 115 }; 116 117 simpleServiceDifferentDescription.configuration = { 118 imports = [ simpleService.configuration ]; 119 systemd.services.test.description = "Test unit"; 120 }; 121 122 simpleServiceModified.configuration = { 123 imports = [ simpleService.configuration ]; 124 systemd.services.test.serviceConfig.X-Test = true; 125 }; 126 127 simpleServiceNostop.configuration = { 128 imports = [ simpleService.configuration ]; 129 systemd.services.test.stopIfChanged = false; 130 }; 131 132 simpleServiceReload.configuration = { 133 imports = [ simpleService.configuration ]; 134 systemd.services.test = { 135 reloadIfChanged = true; 136 serviceConfig.ExecReload = "${pkgs.coreutils}/bin/true"; 137 }; 138 }; 139 140 simpleServiceNorestart.configuration = { 141 imports = [ simpleService.configuration ]; 142 systemd.services.test.restartIfChanged = false; 143 }; 144 145 simpleServiceFailing.configuration = { 146 imports = [ simpleServiceModified.configuration ]; 147 systemd.services.test.serviceConfig.ExecStart = lib.mkForce "${pkgs.coreutils}/bin/false"; 148 }; 149 150 autorestartService.configuration = { 151 # A service that immediately goes into restarting (but without failing) 152 systemd.services.autorestart = { 153 wantedBy = [ "multi-user.target" ]; 154 serviceConfig = { 155 Type = "simple"; 156 Restart = "always"; 157 RestartSec = "20y"; # Should be long enough 158 ExecStart = "${pkgs.coreutils}/bin/true"; 159 }; 160 }; 161 }; 162 163 autorestartServiceFailing.configuration = { 164 imports = [ autorestartService.configuration ]; 165 systemd.services.autorestart.serviceConfig = { 166 ExecStart = lib.mkForce "${pkgs.coreutils}/bin/false"; 167 }; 168 }; 169 170 simpleServiceWithExtraSection.configuration = { 171 imports = [ simpleServiceNostop.configuration ]; 172 systemd.packages = [ (pkgs.writeTextFile { 173 name = "systemd-extra-section"; 174 destination = "/etc/systemd/system/test.service"; 175 text = '' 176 [X-Test] 177 X-Test-Value=a 178 ''; 179 }) ]; 180 }; 181 182 simpleServiceWithExtraSectionOtherName.configuration = { 183 imports = [ simpleServiceNostop.configuration ]; 184 systemd.packages = [ (pkgs.writeTextFile { 185 name = "systemd-extra-section"; 186 destination = "/etc/systemd/system/test.service"; 187 text = '' 188 [X-Test2] 189 X-Test-Value=a 190 ''; 191 }) ]; 192 }; 193 194 simpleServiceWithInstallSection.configuration = { 195 imports = [ simpleServiceNostop.configuration ]; 196 systemd.packages = [ (pkgs.writeTextFile { 197 name = "systemd-extra-section"; 198 destination = "/etc/systemd/system/test.service"; 199 text = '' 200 [Install] 201 WantedBy=multi-user.target 202 ''; 203 }) ]; 204 }; 205 206 simpleServiceWithExtraKey.configuration = { 207 imports = [ simpleServiceNostop.configuration ]; 208 systemd.services.test.serviceConfig."X-Test" = "test"; 209 }; 210 211 simpleServiceWithExtraKeyOtherValue.configuration = { 212 imports = [ simpleServiceNostop.configuration ]; 213 systemd.services.test.serviceConfig."X-Test" = "test2"; 214 }; 215 216 simpleServiceWithExtraKeyOtherName.configuration = { 217 imports = [ simpleServiceNostop.configuration ]; 218 systemd.services.test.serviceConfig."X-Test2" = "test"; 219 }; 220 221 simpleServiceReloadTrigger.configuration = { 222 imports = [ simpleServiceNostop.configuration ]; 223 systemd.services.test.reloadTriggers = [ "/dev/null" ]; 224 }; 225 226 simpleServiceReloadTriggerModified.configuration = { 227 imports = [ simpleServiceNostop.configuration ]; 228 systemd.services.test.reloadTriggers = [ "/dev/zero" ]; 229 }; 230 231 simpleServiceReloadTriggerModifiedAndSomethingElse.configuration = { 232 imports = [ simpleServiceNostop.configuration ]; 233 systemd.services.test = { 234 reloadTriggers = [ "/dev/zero" ]; 235 serviceConfig."X-Test" = "test"; 236 }; 237 }; 238 239 simpleServiceReloadTriggerModifiedSomethingElse.configuration = { 240 imports = [ simpleServiceNostop.configuration ]; 241 systemd.services.test.serviceConfig."X-Test" = "test"; 242 }; 243 244 unitWithBackslash.configuration = { 245 systemd.services."escaped\\x2ddash" = { 246 wantedBy = [ "multi-user.target" ]; 247 serviceConfig = { 248 Type = "oneshot"; 249 RemainAfterExit = true; 250 ExecStart = "${pkgs.coreutils}/bin/true"; 251 ExecReload = "${pkgs.coreutils}/bin/true"; 252 }; 253 }; 254 }; 255 256 unitWithBackslashModified.configuration = { 257 imports = [ unitWithBackslash.configuration ]; 258 systemd.services."escaped\\x2ddash".serviceConfig.X-Test = "test"; 259 }; 260 261 unitStartingWithDash.configuration = { 262 systemd.services."-" = { 263 wantedBy = [ "multi-user.target" ]; 264 serviceConfig = { 265 Type = "oneshot"; 266 RemainAfterExit = true; 267 ExecStart = "${pkgs.coreutils}/bin/true"; 268 }; 269 }; 270 }; 271 272 unitStartingWithDashModified.configuration = { 273 imports = [ unitStartingWithDash.configuration ]; 274 systemd.services."-" = { 275 reloadIfChanged = true; 276 serviceConfig.ExecReload = "${pkgs.coreutils}/bin/true"; 277 }; 278 }; 279 280 unitWithRequirement.configuration = { 281 systemd.services.required-service = { 282 wantedBy = [ "multi-user.target" ]; 283 serviceConfig = { 284 Type = "oneshot"; 285 RemainAfterExit = true; 286 ExecStart = "${pkgs.coreutils}/bin/true"; 287 ExecReload = "${pkgs.coreutils}/bin/true"; 288 }; 289 }; 290 systemd.services.test-service = { 291 wantedBy = [ "multi-user.target" ]; 292 requires = [ "required-service.service" ]; 293 serviceConfig = { 294 Type = "oneshot"; 295 RemainAfterExit = true; 296 ExecStart = "${pkgs.coreutils}/bin/true"; 297 ExecReload = "${pkgs.coreutils}/bin/true"; 298 }; 299 }; 300 }; 301 302 unitWithRequirementModified.configuration = { 303 imports = [ unitWithRequirement.configuration ]; 304 systemd.services.required-service.serviceConfig.X-Test = "test"; 305 systemd.services.test-service.reloadTriggers = [ "test" ]; 306 }; 307 308 unitWithRequirementModifiedNostart.configuration = { 309 imports = [ unitWithRequirement.configuration ]; 310 systemd.services.test-service.unitConfig.RefuseManualStart = true; 311 }; 312 313 unitWithTemplate.configuration = { 314 systemd.services."instantiated@".serviceConfig = { 315 Type = "oneshot"; 316 RemainAfterExit = true; 317 ExecStart = "${pkgs.coreutils}/bin/true"; 318 ExecReload = "${pkgs.coreutils}/bin/true"; 319 }; 320 systemd.services."instantiated@one" = { 321 wantedBy = [ "multi-user.target" ]; 322 overrideStrategy = "asDropin"; 323 }; 324 systemd.services."instantiated@two" = { 325 wantedBy = [ "multi-user.target" ]; 326 overrideStrategy = "asDropin"; 327 }; 328 }; 329 330 unitWithTemplateModified.configuration = { 331 imports = [ unitWithTemplate.configuration ]; 332 systemd.services."instantiated@".serviceConfig.X-Test = "test"; 333 }; 334 335 restart-and-reload-by-activation-script.configuration = { 336 systemd.services = rec { 337 simple-service = { 338 # No wantedBy so we can check if the activation script restart triggers them 339 serviceConfig = { 340 Type = "oneshot"; 341 RemainAfterExit = true; 342 ExecStart = "${pkgs.coreutils}/bin/true"; 343 ExecReload = "${pkgs.coreutils}/bin/true"; 344 }; 345 }; 346 "templated-simple-service@" = simple-service; 347 "templated-simple-service@instance".overrideStrategy = "asDropin"; 348 349 simple-restart-service = simple-service // { 350 stopIfChanged = false; 351 }; 352 "templated-simple-restart-service@" = simple-restart-service; 353 "templated-simple-restart-service@instance".overrideStrategy = "asDropin"; 354 355 simple-reload-service = simple-service // { 356 reloadIfChanged = true; 357 }; 358 "templated-simple-reload-service@" = simple-reload-service; 359 "templated-simple-reload-service@instance".overrideStrategy = "asDropin"; 360 361 no-restart-service = simple-service // { 362 restartIfChanged = false; 363 }; 364 "templated-no-restart-service@" = no-restart-service; 365 "templated-no-restart-service@instance".overrideStrategy = "asDropin"; 366 367 reload-triggers = simple-service // { 368 wantedBy = [ "multi-user.target" ]; 369 }; 370 "templated-reload-triggers@" = simple-service; 371 "templated-reload-triggers@instance" = { 372 overrideStrategy = "asDropin"; 373 wantedBy = [ "multi-user.target" ]; 374 }; 375 376 reload-triggers-and-restart-by-as = simple-service; 377 "templated-reload-triggers-and-restart-by-as@" = reload-triggers-and-restart-by-as; 378 "templated-reload-triggers-and-restart-by-as@instance".overrideStrategy = "asDropin"; 379 380 reload-triggers-and-restart = simple-service // { 381 stopIfChanged = false; # easier to check for this 382 wantedBy = [ "multi-user.target" ]; 383 }; 384 "templated-reload-triggers-and-restart@" = simple-service; 385 "templated-reload-triggers-and-restart@instance" = { 386 overrideStrategy = "asDropin"; 387 stopIfChanged = false; # easier to check for this 388 wantedBy = [ "multi-user.target" ]; 389 }; 390 }; 391 392 system.activationScripts.restart-and-reload-test = { 393 supportsDryActivation = true; 394 deps = []; 395 text = '' 396 if [ "$NIXOS_ACTION" = dry-activate ]; then 397 f=/run/nixos/dry-activation-restart-list 398 g=/run/nixos/dry-activation-reload-list 399 else 400 f=/run/nixos/activation-restart-list 401 g=/run/nixos/activation-reload-list 402 fi 403 cat <<EOF >> "$f" 404 simple-service.service 405 simple-restart-service.service 406 simple-reload-service.service 407 no-restart-service.service 408 reload-triggers-and-restart-by-as.service 409 templated-simple-service@instance.service 410 templated-simple-restart-service@instance.service 411 templated-simple-reload-service@instance.service 412 templated-no-restart-service@instance.service 413 templated-reload-triggers-and-restart-by-as@instance.service 414 EOF 415 416 cat <<EOF >> "$g" 417 reload-triggers.service 418 reload-triggers-and-restart-by-as.service 419 reload-triggers-and-restart.service 420 templated-reload-triggers@instance.service 421 templated-reload-triggers-and-restart-by-as@instance.service 422 templated-reload-triggers-and-restart@instance.service 423 EOF 424 ''; 425 }; 426 }; 427 428 restart-and-reload-by-activation-script-modified.configuration = { 429 imports = [ restart-and-reload-by-activation-script.configuration ]; 430 systemd.services.reload-triggers-and-restart.serviceConfig.X-Modified = "test"; 431 systemd.services."templated-reload-triggers-and-restart@instance" = { 432 overrideStrategy = "asDropin"; 433 serviceConfig.X-Modified = "test"; 434 }; 435 }; 436 437 simple-socket.configuration = { 438 systemd.services.socket-activated = { 439 description = "A socket-activated service"; 440 stopIfChanged = lib.mkDefault false; 441 serviceConfig = { 442 ExecStart = socketTest; 443 ExecReload = "${pkgs.coreutils}/bin/true"; 444 }; 445 }; 446 systemd.sockets.socket-activated = { 447 wantedBy = [ "sockets.target" ]; 448 listenStreams = [ "/run/test.sock" ]; 449 socketConfig.SocketMode = lib.mkDefault "0777"; 450 }; 451 }; 452 453 simple-socket-service-modified.configuration = { 454 imports = [ simple-socket.configuration ]; 455 systemd.services.socket-activated.serviceConfig.X-Test = "test"; 456 }; 457 458 simple-socket-stop-if-changed.configuration = { 459 imports = [ simple-socket.configuration ]; 460 systemd.services.socket-activated.stopIfChanged = true; 461 }; 462 463 simple-socket-stop-if-changed-and-reloadtrigger.configuration = { 464 imports = [ simple-socket.configuration ]; 465 systemd.services.socket-activated = { 466 stopIfChanged = true; 467 reloadTriggers = [ "test" ]; 468 }; 469 }; 470 471 mount.configuration = { 472 systemd.mounts = [ 473 { 474 description = "Testmount"; 475 what = "tmpfs"; 476 type = "tmpfs"; 477 where = "/testmount"; 478 options = "size=1M"; 479 wantedBy = [ "local-fs.target" ]; 480 } 481 ]; 482 }; 483 484 mountOptionsModified.configuration = { 485 systemd.mounts = [ 486 { 487 description = "Testmount"; 488 what = "tmpfs"; 489 type = "tmpfs"; 490 where = "/testmount"; 491 options = "size=10M"; 492 wantedBy = [ "local-fs.target" ]; 493 } 494 ]; 495 }; 496 497 mountModified.configuration = { 498 systemd.mounts = [ 499 { 500 description = "Testmount"; 501 what = "ramfs"; 502 type = "ramfs"; 503 where = "/testmount"; 504 options = "size=10M"; 505 wantedBy = [ "local-fs.target" ]; 506 } 507 ]; 508 }; 509 510 timer.configuration = { 511 systemd.timers.test-timer = { 512 wantedBy = [ "timers.target" ]; 513 timerConfig.OnCalendar = "@1395716396"; # chosen by fair dice roll 514 }; 515 systemd.services.test-timer = { 516 serviceConfig = { 517 Type = "oneshot"; 518 ExecStart = "${pkgs.coreutils}/bin/true"; 519 }; 520 }; 521 }; 522 523 timerModified.configuration = { 524 imports = [ timer.configuration ]; 525 systemd.timers.test-timer.timerConfig.OnCalendar = lib.mkForce "Fri 2012-11-23 16:00:00"; 526 }; 527 528 hybridSleepModified.configuration = { 529 systemd.targets.hybrid-sleep.unitConfig.X-Test = true; 530 }; 531 532 target.configuration = { 533 systemd.targets.test-target.wantedBy = [ "multi-user.target" ]; 534 # We use this service to figure out whether the target was modified. 535 # This is the only way because targets are filtered and therefore not 536 # printed when they are started/stopped. 537 systemd.services.test-service = { 538 bindsTo = [ "test-target.target" ]; 539 serviceConfig.ExecStart = "${pkgs.coreutils}/bin/sleep infinity"; 540 }; 541 }; 542 543 targetModified.configuration = { 544 imports = [ target.configuration ]; 545 systemd.targets.test-target.unitConfig.X-Test = true; 546 }; 547 548 targetModifiedStopOnReconfig.configuration = { 549 imports = [ target.configuration ]; 550 systemd.targets.test-target.unitConfig.X-StopOnReconfiguration = true; 551 }; 552 553 path.configuration = { 554 systemd.paths.test-watch = { 555 wantedBy = [ "paths.target" ]; 556 pathConfig.PathExists = "/testpath"; 557 }; 558 systemd.services.test-watch = { 559 serviceConfig = { 560 Type = "oneshot"; 561 RemainAfterExit = true; 562 ExecStart = "${pkgs.coreutils}/bin/touch /testpath-modified"; 563 }; 564 }; 565 }; 566 567 pathModified.configuration = { 568 imports = [ path.configuration ]; 569 systemd.paths.test-watch.pathConfig.PathExists = lib.mkForce "/testpath2"; 570 }; 571 572 slice.configuration = { 573 systemd.slices.testslice.sliceConfig.MemoryMax = "1"; # don't allow memory allocation 574 systemd.services.testservice = { 575 serviceConfig = { 576 Type = "oneshot"; 577 RemainAfterExit = true; 578 ExecStart = "${pkgs.coreutils}/bin/true"; 579 Slice = "testslice.slice"; 580 }; 581 }; 582 }; 583 584 sliceModified.configuration = { 585 imports = [ slice.configuration ]; 586 systemd.slices.testslice.sliceConfig.MemoryMax = lib.mkForce null; 587 }; 588 }; 589 }; 590 591 other = { 592 users.mutableUsers = true; 593 }; 594 }; 595 596 testScript = { nodes, ... }: let 597 originalSystem = nodes.machine.system.build.toplevel; 598 otherSystem = nodes.other.system.build.toplevel; 599 machine = nodes.machine.system.build.toplevel; 600 601 # Ensures failures pass through using pipefail, otherwise failing to 602 # switch-to-configuration is hidden by the success of `tee`. 603 stderrRunner = pkgs.writeScript "stderr-runner" '' 604 #! ${pkgs.runtimeShell} 605 set -e 606 set -o pipefail 607 exec env -i "$@" | tee /dev/stderr 608 ''; 609 610 # Returns a comma separated representation of the given list in sorted 611 # order, that matches the output format of switch-to-configuration.pl 612 sortedUnits = xs: lib.concatStringsSep ", " (builtins.sort builtins.lessThan xs); 613 in /* python */ '' 614 def switch_to_specialisation(system, name, action="test", fail=False): 615 if name == "": 616 switcher = f"{system}/bin/switch-to-configuration" 617 else: 618 switcher = f"{system}/specialisation/{name}/bin/switch-to-configuration" 619 return run_switch(switcher, action, fail) 620 621 # like above but stc = switcher 622 def run_switch(switcher, action="test", fail=False): 623 out = machine.fail(f"{switcher} {action} 2>&1") if fail \ 624 else machine.succeed(f"{switcher} {action} 2>&1") 625 assert_lacks(out, "switch-to-configuration line") # Perl warnings 626 return out 627 628 def assert_contains(haystack, needle): 629 if needle not in haystack: 630 print("The haystack that will cause the following exception is:") 631 print("---") 632 print(haystack) 633 print("---") 634 raise Exception(f"Expected string '{needle}' was not found") 635 636 def assert_lacks(haystack, needle): 637 if needle in haystack: 638 print("The haystack that will cause the following exception is:") 639 print("---") 640 print(haystack, end="") 641 print("---") 642 raise Exception(f"Unexpected string '{needle}' was found") 643 644 645 machine.wait_for_unit("multi-user.target") 646 647 machine.succeed( 648 "${stderrRunner} ${originalSystem}/bin/switch-to-configuration test" 649 ) 650 # This tests whether the /etc/os-release parser works which is a fallback 651 # when /etc/NIXOS is missing. If the parser does not work, switch-to-configuration 652 # would fail. 653 machine.succeed("rm /etc/NIXOS") 654 machine.succeed( 655 "${stderrRunner} ${otherSystem}/bin/switch-to-configuration test" 656 ) 657 658 659 with subtest("actions"): 660 # boot action 661 machine.fail("test -f /tmp/bootloader-installed") 662 out = switch_to_specialisation("${machine}", "simpleService", action="boot") 663 assert_contains(out, "installing dummy bootloader") 664 assert_lacks(out, "activating the configuration...") # good indicator of a system activation 665 machine.succeed("test -f /tmp/bootloader-installed") 666 machine.succeed("rm /tmp/bootloader-installed") 667 668 # switch action 669 machine.fail("test -f /tmp/bootloader-installed") 670 out = switch_to_specialisation("${machine}", "", action="switch") 671 assert_contains(out, "installing dummy bootloader") 672 assert_contains(out, "activating the configuration...") # good indicator of a system activation 673 machine.succeed("test -f /tmp/bootloader-installed") 674 675 # test and dry-activate actions are tested further down below 676 677 # invalid action fails the script 678 switch_to_specialisation("${machine}", "", action="broken-action", fail=True) 679 # no action fails the script 680 assert "Usage:" in machine.fail("${machine}/bin/switch-to-configuration 2>&1") 681 682 with subtest("init interface version"): 683 # Do not try to switch to an invalid init interface version 684 assert "incompatible" in switch_to_specialisation("${machine}", "brokenInitInterface", fail=True) 685 686 with subtest("systemd restarts"): 687 # systemd is restarted when its system.conf changes 688 out = switch_to_specialisation("${machine}", "modifiedSystemConf") 689 assert_contains(out, "restarting systemd...") 690 691 with subtest("continuing from an aborted switch"): 692 # An aborted switch will write into a file what it tried to start 693 # and a second switch should continue from this 694 machine.succeed("echo dbus.service > /run/nixos/start-list") 695 out = switch_to_specialisation("${machine}", "modifiedSystemConf") 696 assert_contains(out, "starting the following units: dbus.service\n") 697 698 with subtest("fstab mounts"): 699 switch_to_specialisation("${machine}", "") 700 # add a mountpoint 701 out = switch_to_specialisation("${machine}", "addedMount") 702 assert_lacks(out, "stopping the following units:") 703 assert_lacks(out, "NOT restarting the following changed units:") 704 assert_lacks(out, "\nrestarting the following units:") 705 assert_lacks(out, "\nstarting the following units:") 706 assert_contains(out, "the following new units were started: test.mount\n") 707 # modify the mountpoint's options 708 out = switch_to_specialisation("${machine}", "addedMountOptsModified") 709 assert_lacks(out, "stopping the following units:") 710 assert_lacks(out, "NOT restarting the following changed units:") 711 assert_contains(out, "reloading the following units: test.mount\n") 712 assert_lacks(out, "\nrestarting the following units:") 713 assert_lacks(out, "\nstarting the following units:") 714 assert_lacks(out, "the following new units were started:") 715 # modify the device 716 out = switch_to_specialisation("${machine}", "addedMountDevModified") 717 assert_lacks(out, "stopping the following units:") 718 assert_lacks(out, "NOT restarting the following changed units:") 719 assert_lacks(out, "reloading the following units:") 720 assert_contains(out, "\nrestarting the following units: test.mount\n") 721 assert_lacks(out, "\nstarting the following units:") 722 assert_lacks(out, "the following new units were started:") 723 # modify both 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, "reloading the following units:") 728 assert_contains(out, "\nrestarting the following units: test.mount\n") 729 assert_lacks(out, "\nstarting the following units:") 730 assert_lacks(out, "the following new units were started:") 731 # remove the mount 732 out = switch_to_specialisation("${machine}", "") 733 assert_contains(out, "stopping the following units: test.mount\n") 734 assert_lacks(out, "NOT restarting the following changed units:") 735 assert_contains(out, "reloading the following units: dbus.service\n") 736 assert_lacks(out, "\nrestarting the following units:") 737 assert_lacks(out, "\nstarting the following units:") 738 assert_lacks(out, "the following new units were started:") 739 # change something about the / mount 740 out = switch_to_specialisation("${machine}", "storeMountModified") 741 assert_lacks(out, "stopping the following units:") 742 assert_contains(out, "NOT restarting the following changed units: -.mount") 743 assert_contains(out, "reloading the following units: dbus.service\n") 744 assert_lacks(out, "\nrestarting the following units:") 745 assert_lacks(out, "\nstarting the following units:") 746 assert_lacks(out, "the following new units were started:") 747 748 with subtest("swaps"): 749 switch_to_specialisation("${machine}", "") 750 # add a swap 751 out = switch_to_specialisation("${machine}", "swap") 752 assert_lacks(out, "stopping the following units:") 753 assert_lacks(out, "NOT restarting the following changed units:") 754 assert_contains(out, "reloading the following units: dbus.service\n") 755 assert_lacks(out, "\nrestarting the following units:") 756 assert_lacks(out, "\nstarting the following units:") 757 assert_contains(out, "the following new units were started: swapfile.swap") 758 # remove it 759 out = switch_to_specialisation("${machine}", "") 760 assert_contains(out, "stopping swap device: /swapfile") 761 assert_lacks(out, "stopping the following units:") 762 assert_lacks(out, "NOT restarting the following changed units:") 763 assert_contains(out, "reloading the following units: dbus.service\n") 764 assert_lacks(out, "\nrestarting the following units:") 765 assert_lacks(out, "\nstarting the following units:") 766 assert_lacks(out, "the following new units were started:") 767 768 with subtest("services"): 769 switch_to_specialisation("${machine}", "") 770 # Nothing happens when nothing is changed 771 out = switch_to_specialisation("${machine}", "") 772 assert_lacks(out, "stopping the following units:") 773 assert_lacks(out, "NOT restarting the following changed units:") 774 assert_lacks(out, "reloading the following units:") 775 assert_lacks(out, "\nrestarting the following units:") 776 assert_lacks(out, "\nstarting the following units:") 777 assert_lacks(out, "the following new units were started:") 778 779 # Start a simple service 780 out = switch_to_specialisation("${machine}", "simpleService") 781 assert_lacks(out, "installing dummy bootloader") # test does not install a bootloader 782 assert_lacks(out, "stopping the following units:") 783 assert_lacks(out, "NOT restarting the following changed units:") 784 assert_contains(out, "reloading the following units: dbus.service\n") # huh 785 assert_lacks(out, "\nrestarting the following units:") 786 assert_lacks(out, "\nstarting the following units:") 787 assert_contains(out, "the following new units were started: test.service\n") 788 789 # Not changing anything doesn't do anything 790 out = switch_to_specialisation("${machine}", "simpleService") 791 assert_lacks(out, "stopping the following units:") 792 assert_lacks(out, "NOT restarting the following changed units:") 793 assert_lacks(out, "reloading the following units:") 794 assert_lacks(out, "\nrestarting the following units:") 795 assert_lacks(out, "\nstarting the following units:") 796 assert_lacks(out, "the following new units were started:") 797 798 # Only changing the description does nothing 799 out = switch_to_specialisation("${machine}", "simpleServiceDifferentDescription") 800 assert_lacks(out, "stopping the following units:") 801 assert_lacks(out, "NOT restarting the following changed units:") 802 assert_lacks(out, "reloading the following units:") 803 assert_lacks(out, "\nrestarting the following units:") 804 assert_lacks(out, "\nstarting the following units:") 805 assert_lacks(out, "the following new units were started:") 806 807 # Restart the simple service 808 out = switch_to_specialisation("${machine}", "simpleServiceModified") 809 assert_contains(out, "stopping the following units: test.service\n") 810 assert_lacks(out, "NOT restarting the following changed units:") 811 assert_lacks(out, "reloading the following units:") 812 assert_lacks(out, "\nrestarting the following units:") 813 assert_contains(out, "\nstarting the following units: test.service\n") 814 assert_lacks(out, "the following new units were started:") 815 816 # Restart the service with stopIfChanged=false 817 out = switch_to_specialisation("${machine}", "simpleServiceNostop") 818 assert_lacks(out, "stopping the following units:") 819 assert_lacks(out, "NOT restarting the following changed units:") 820 assert_lacks(out, "reloading the following units:") 821 assert_contains(out, "\nrestarting the following units: test.service\n") 822 assert_lacks(out, "\nstarting the following units:") 823 assert_lacks(out, "the following new units were started:") 824 825 # Reload the service with reloadIfChanged=true 826 out = switch_to_specialisation("${machine}", "simpleServiceReload") 827 assert_lacks(out, "stopping the following units:") 828 assert_lacks(out, "NOT restarting the following changed units:") 829 assert_contains(out, "reloading the following units: test.service\n") 830 assert_lacks(out, "\nrestarting the following units:") 831 assert_lacks(out, "\nstarting the following units:") 832 assert_lacks(out, "the following new units were started:") 833 834 # Nothing happens when restartIfChanged=false 835 out = switch_to_specialisation("${machine}", "simpleServiceNorestart") 836 assert_lacks(out, "stopping the following units:") 837 assert_contains(out, "NOT restarting the following changed units: test.service\n") 838 assert_lacks(out, "reloading the following units:") 839 assert_lacks(out, "\nrestarting the following units:") 840 assert_lacks(out, "\nstarting the following units:") 841 assert_lacks(out, "the following new units were started:") 842 843 # Dry mode shows different messages 844 out = switch_to_specialisation("${machine}", "simpleService", action="dry-activate") 845 assert_lacks(out, "stopping the following units:") 846 assert_lacks(out, "NOT restarting the following changed units:") 847 assert_lacks(out, "reloading the following units:") 848 assert_lacks(out, "\nrestarting the following units:") 849 assert_lacks(out, "\nstarting the following units:") 850 assert_lacks(out, "the following new units were started:") 851 assert_contains(out, "would start the following units: test.service\n") 852 853 out = switch_to_specialisation("${machine}", "", action="test") 854 855 # Ensure the service can be started when the activation script isn't in toplevel 856 # This is a lot like "Start a simple service", except activation-only deps could be gc-ed 857 out = run_switch("${nodes.machine.specialisation.simpleServiceSeparateActivationScript.configuration.system.build.separateActivationScript}/bin/switch-to-configuration"); 858 assert_lacks(out, "installing dummy bootloader") # test does not install a bootloader 859 assert_lacks(out, "stopping the following units:") 860 assert_lacks(out, "NOT restarting the following changed units:") 861 assert_contains(out, "reloading the following units: dbus.service\n") # huh 862 assert_lacks(out, "\nrestarting the following units:") 863 assert_lacks(out, "\nstarting the following units:") 864 assert_contains(out, "the following new units were started: test.service\n") 865 machine.succeed("! test -e /run/current-system/activate") 866 machine.succeed("! test -e /run/current-system/dry-activate") 867 machine.succeed("! test -e /run/current-system/bin/switch-to-configuration") 868 869 # Ensure \ works in unit names 870 out = switch_to_specialisation("${machine}", "unitWithBackslash") 871 assert_contains(out, "stopping the following units: test.service\n") 872 assert_lacks(out, "NOT restarting the following changed units:") 873 assert_lacks(out, "reloading the following units:") 874 assert_lacks(out, "\nrestarting the following units:") 875 assert_lacks(out, "\nstarting the following units:") 876 assert_contains(out, "the following new units were started: escaped\\x2ddash.service\n") 877 878 out = switch_to_specialisation("${machine}", "unitWithBackslashModified") 879 assert_contains(out, "stopping the following units: escaped\\x2ddash.service\n") 880 assert_lacks(out, "NOT restarting the following changed units:") 881 assert_lacks(out, "reloading the following units:") 882 assert_lacks(out, "\nrestarting the following units:") 883 assert_contains(out, "\nstarting the following units: escaped\\x2ddash.service\n") 884 assert_lacks(out, "the following new units were started:") 885 886 # Ensure units can start with a dash 887 out = switch_to_specialisation("${machine}", "unitStartingWithDash") 888 assert_contains(out, "stopping the following units: escaped\\x2ddash.service\n") 889 assert_lacks(out, "NOT restarting the following changed units:") 890 assert_lacks(out, "reloading the following units:") 891 assert_lacks(out, "\nrestarting the following units:") 892 assert_lacks(out, "\nstarting the following units:") 893 assert_contains(out, "the following new units were started: -.service\n") 894 895 # The regression only occurs when reloading units 896 out = switch_to_specialisation("${machine}", "unitStartingWithDashModified") 897 assert_lacks(out, "stopping the following units:") 898 assert_lacks(out, "NOT restarting the following changed units:") 899 assert_contains(out, "reloading the following units: -.service") 900 assert_lacks(out, "\nrestarting the following units:") 901 assert_lacks(out, "\nstarting the following units:") 902 assert_lacks(out, "the following new units were started:") 903 904 # Ensure units that require changed units are properly reloaded 905 out = switch_to_specialisation("${machine}", "unitWithRequirement") 906 assert_contains(out, "stopping the following units: -.service\n") 907 assert_lacks(out, "NOT restarting the following changed units:") 908 assert_lacks(out, "reloading the following units:") 909 assert_lacks(out, "\nrestarting the following units:") 910 assert_lacks(out, "\nstarting the following units:") 911 assert_contains(out, "the following new units were started: required-service.service, test-service.service\n") 912 913 out = switch_to_specialisation("${machine}", "unitWithRequirementModified") 914 assert_contains(out, "stopping the following units: required-service.service\n") 915 assert_lacks(out, "NOT restarting the following changed units:") 916 assert_lacks(out, "reloading the following units:") 917 assert_lacks(out, "\nrestarting the following units:") 918 assert_contains(out, "\nstarting the following units: required-service.service, test-service.service\n") 919 assert_lacks(out, "the following new units were started:") 920 921 # Unless the unit asks to be not restarted 922 out = switch_to_specialisation("${machine}", "unitWithRequirementModifiedNostart") 923 assert_contains(out, "stopping the following units: required-service.service\n") 924 assert_lacks(out, "NOT restarting the following changed units:") 925 assert_lacks(out, "reloading the following units:") 926 assert_lacks(out, "\nrestarting the following units:") 927 assert_contains(out, "\nstarting the following units: required-service.service\n") 928 assert_lacks(out, "the following new units were started:") 929 930 # Ensure templated units are restarted when the base unit changes 931 switch_to_specialisation("${machine}", "unitWithTemplate") 932 out = switch_to_specialisation("${machine}", "unitWithTemplateModified") 933 assert_contains(out, "stopping the following units: instantiated@one.service, instantiated@two.service\n") 934 assert_lacks(out, "NOT restarting the following changed units:") 935 assert_lacks(out, "reloading the following units:") 936 assert_lacks(out, "\nrestarting the following units:") 937 assert_contains(out, "\nstarting the following units: instantiated@one.service, instantiated@two.service\n") 938 assert_lacks(out, "the following new units were started:") 939 940 with subtest("failing units"): 941 # Let the simple service fail 942 switch_to_specialisation("${machine}", "simpleServiceModified") 943 out = switch_to_specialisation("${machine}", "simpleServiceFailing", fail=True) 944 assert_contains(out, "stopping the following units: test.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: test.service\n") 949 assert_lacks(out, "the following new units were started:") 950 assert_contains(out, "warning: the following units failed: test.service\n") 951 assert_contains(out, "Main PID:") # output of systemctl 952 953 # A unit that gets into autorestart without failing is not treated as failed 954 out = switch_to_specialisation("${machine}", "autorestartService") 955 assert_lacks(out, "stopping the following units:") 956 assert_lacks(out, "NOT restarting the following changed units:") 957 assert_lacks(out, "reloading the following units:") 958 assert_lacks(out, "\nrestarting the following units:") 959 assert_lacks(out, "\nstarting the following units:") 960 assert_contains(out, "the following new units were started: autorestart.service\n") 961 machine.systemctl('stop autorestart.service') # cancel the 20y timer 962 963 # Switching to the same system should do nothing (especially not treat the unit as failed) 964 out = switch_to_specialisation("${machine}", "autorestartService") 965 assert_lacks(out, "stopping the following units:") 966 assert_lacks(out, "NOT restarting the following changed units:") 967 assert_lacks(out, "reloading the following units:") 968 assert_lacks(out, "\nrestarting the following units:") 969 assert_lacks(out, "\nstarting the following units:") 970 assert_contains(out, "the following new units were started: autorestart.service\n") 971 machine.systemctl('stop autorestart.service') # cancel the 20y timer 972 973 # If systemd thinks the unit has failed and is in autorestart, we should show it as failed 974 out = switch_to_specialisation("${machine}", "autorestartServiceFailing", fail=True) 975 assert_lacks(out, "stopping the following units:") 976 assert_lacks(out, "NOT restarting the following changed units:") 977 assert_lacks(out, "reloading the following units:") 978 assert_lacks(out, "\nrestarting the following units:") 979 assert_lacks(out, "\nstarting the following units:") 980 assert_lacks(out, "the following new units were started:") 981 assert_contains(out, "warning: the following units failed: autorestart.service\n") 982 assert_contains(out, "Main PID:") # output of systemctl 983 984 with subtest("unit file parser"): 985 # Switch to a well-known state 986 switch_to_specialisation("${machine}", "simpleServiceNostop") 987 988 # Add a section 989 out = switch_to_specialisation("${machine}", "simpleServiceWithExtraSection") 990 assert_lacks(out, "stopping the following units:") 991 assert_lacks(out, "NOT restarting the following changed units:") 992 assert_lacks(out, "reloading the following units:") 993 assert_contains(out, "\nrestarting the following units: test.service\n") 994 assert_lacks(out, "\nstarting the following units:") 995 assert_lacks(out, "the following new units were started:") 996 997 # Rename it 998 out = switch_to_specialisation("${machine}", "simpleServiceWithExtraSectionOtherName") 999 assert_lacks(out, "stopping the following units:") 1000 assert_lacks(out, "NOT restarting the following changed units:") 1001 assert_lacks(out, "reloading the following units:") 1002 assert_contains(out, "\nrestarting the following units: test.service\n") 1003 assert_lacks(out, "\nstarting the following units:") 1004 assert_lacks(out, "the following new units were started:") 1005 1006 # Remove it 1007 out = switch_to_specialisation("${machine}", "simpleServiceNostop") 1008 assert_lacks(out, "stopping the following units:") 1009 assert_lacks(out, "NOT restarting the following changed units:") 1010 assert_lacks(out, "reloading the following units:") 1011 assert_contains(out, "\nrestarting the following units: test.service\n") 1012 assert_lacks(out, "\nstarting the following units:") 1013 assert_lacks(out, "the following new units were started:") 1014 1015 # [Install] section is ignored 1016 out = switch_to_specialisation("${machine}", "simpleServiceWithInstallSection") 1017 assert_lacks(out, "stopping the following units:") 1018 assert_lacks(out, "NOT restarting the following changed units:") 1019 assert_lacks(out, "reloading the following units:") 1020 assert_lacks(out, "\nrestarting the following units:") 1021 assert_lacks(out, "\nstarting the following units:") 1022 assert_lacks(out, "the following new units were started:") 1023 1024 # Add a key 1025 out = switch_to_specialisation("${machine}", "simpleServiceWithExtraKey") 1026 assert_lacks(out, "stopping the following units:") 1027 assert_lacks(out, "NOT restarting the following changed units:") 1028 assert_lacks(out, "reloading the following units:") 1029 assert_contains(out, "\nrestarting the following units: test.service\n") 1030 assert_lacks(out, "\nstarting the following units:") 1031 assert_lacks(out, "the following new units were started:") 1032 1033 # Change its value 1034 out = switch_to_specialisation("${machine}", "simpleServiceWithExtraKeyOtherValue") 1035 assert_lacks(out, "stopping the following units:") 1036 assert_lacks(out, "NOT restarting the following changed units:") 1037 assert_lacks(out, "reloading the following units:") 1038 assert_contains(out, "\nrestarting the following units: test.service\n") 1039 assert_lacks(out, "\nstarting the following units:") 1040 assert_lacks(out, "the following new units were started:") 1041 1042 # Rename it 1043 out = switch_to_specialisation("${machine}", "simpleServiceWithExtraKeyOtherName") 1044 assert_lacks(out, "stopping the following units:") 1045 assert_lacks(out, "NOT restarting the following changed units:") 1046 assert_lacks(out, "reloading the following units:") 1047 assert_contains(out, "\nrestarting the following units: test.service\n") 1048 assert_lacks(out, "\nstarting the following units:") 1049 assert_lacks(out, "the following new units were started:") 1050 1051 # Remove it 1052 out = switch_to_specialisation("${machine}", "simpleServiceNostop") 1053 assert_lacks(out, "stopping the following units:") 1054 assert_lacks(out, "NOT restarting the following changed units:") 1055 assert_lacks(out, "reloading the following units:") 1056 assert_contains(out, "\nrestarting the following units: test.service\n") 1057 assert_lacks(out, "\nstarting the following units:") 1058 assert_lacks(out, "the following new units were started:") 1059 1060 # Add a reload trigger 1061 out = switch_to_specialisation("${machine}", "simpleServiceReloadTrigger") 1062 assert_lacks(out, "stopping the following units:") 1063 assert_lacks(out, "NOT restarting the following changed units:") 1064 assert_contains(out, "reloading the following units: test.service\n") 1065 assert_lacks(out, "\nrestarting the following units:") 1066 assert_lacks(out, "\nstarting the following units:") 1067 assert_lacks(out, "the following new units were started:") 1068 1069 # Modify the reload trigger 1070 out = switch_to_specialisation("${machine}", "simpleServiceReloadTriggerModified") 1071 assert_lacks(out, "stopping the following units:") 1072 assert_lacks(out, "NOT restarting the following changed units:") 1073 assert_contains(out, "reloading the following units: test.service\n") 1074 assert_lacks(out, "\nrestarting the following units:") 1075 assert_lacks(out, "\nstarting the following units:") 1076 assert_lacks(out, "the following new units were started:") 1077 1078 # Modify the reload trigger and something else 1079 out = switch_to_specialisation("${machine}", "simpleServiceReloadTriggerModifiedAndSomethingElse") 1080 assert_lacks(out, "stopping the following units:") 1081 assert_lacks(out, "NOT restarting the following changed units:") 1082 assert_lacks(out, "reloading the following units:") 1083 assert_contains(out, "\nrestarting the following units: test.service\n") 1084 assert_lacks(out, "\nstarting the following units:") 1085 assert_lacks(out, "the following new units were started:") 1086 1087 # Remove the reload trigger 1088 out = switch_to_specialisation("${machine}", "simpleServiceReloadTriggerModifiedSomethingElse") 1089 assert_lacks(out, "stopping the following units:") 1090 assert_lacks(out, "NOT restarting the following changed units:") 1091 assert_lacks(out, "reloading the following units:") 1092 assert_lacks(out, "\nrestarting the following units:") 1093 assert_lacks(out, "\nstarting the following units:") 1094 assert_lacks(out, "the following new units were started:") 1095 1096 with subtest("restart and reload by activation script"): 1097 switch_to_specialisation("${machine}", "simpleServiceNorestart") 1098 out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script") 1099 assert_contains(out, "stopping the following units: test.service\n") 1100 assert_lacks(out, "NOT restarting the following changed units:") 1101 assert_lacks(out, "reloading the following units:") 1102 assert_lacks(out, "restarting the following units:") 1103 assert_contains(out, "\nstarting the following units: ${sortedUnits [ 1104 "no-restart-service.service" 1105 "reload-triggers-and-restart-by-as.service" 1106 "simple-reload-service.service" 1107 "simple-restart-service.service" 1108 "simple-service.service" 1109 "templated-no-restart-service@instance.service" 1110 "templated-reload-triggers-and-restart-by-as@instance.service" 1111 "templated-simple-reload-service@instance.service" 1112 "templated-simple-restart-service@instance.service" 1113 "templated-simple-service@instance.service" 1114 ]}\n") 1115 assert_contains(out, "the following new units were started: ${sortedUnits [ 1116 "no-restart-service.service" 1117 "reload-triggers-and-restart-by-as.service" 1118 "reload-triggers-and-restart.service" 1119 "reload-triggers.service" 1120 "simple-reload-service.service" 1121 "simple-restart-service.service" 1122 "simple-service.service" 1123 "system-templated\\\\x2dno\\\\x2drestart\\\\x2dservice.slice" 1124 "system-templated\\\\x2dreload\\\\x2dtriggers.slice" 1125 "system-templated\\\\x2dreload\\\\x2dtriggers\\\\x2dand\\\\x2drestart.slice" 1126 "system-templated\\\\x2dreload\\\\x2dtriggers\\\\x2dand\\\\x2drestart\\\\x2dby\\\\x2das.slice" 1127 "system-templated\\\\x2dsimple\\\\x2dreload\\\\x2dservice.slice" 1128 "system-templated\\\\x2dsimple\\\\x2drestart\\\\x2dservice.slice" 1129 "system-templated\\\\x2dsimple\\\\x2dservice.slice" 1130 "templated-no-restart-service@instance.service" 1131 "templated-reload-triggers-and-restart-by-as@instance.service" 1132 "templated-reload-triggers-and-restart@instance.service" 1133 "templated-reload-triggers@instance.service" 1134 "templated-simple-reload-service@instance.service" 1135 "templated-simple-restart-service@instance.service" 1136 "templated-simple-service@instance.service" 1137 ]}\n") 1138 # Switch to the same system where the example services get restarted 1139 # and reloaded by the activation script 1140 out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script") 1141 assert_lacks(out, "stopping the following units:") 1142 assert_lacks(out, "NOT restarting the following changed units:") 1143 assert_contains(out, "reloading the following units: ${sortedUnits [ 1144 "reload-triggers-and-restart.service" 1145 "reload-triggers.service" 1146 "simple-reload-service.service" 1147 "templated-reload-triggers-and-restart@instance.service" 1148 "templated-reload-triggers@instance.service" 1149 "templated-simple-reload-service@instance.service" 1150 ]}\n") 1151 assert_contains(out, "restarting the following units: ${sortedUnits [ 1152 "reload-triggers-and-restart-by-as.service" 1153 "simple-restart-service.service" 1154 "simple-service.service" 1155 "templated-reload-triggers-and-restart-by-as@instance.service" 1156 "templated-simple-restart-service@instance.service" 1157 "templated-simple-service@instance.service" 1158 ]}\n") 1159 assert_lacks(out, "\nstarting the following units:") 1160 assert_lacks(out, "the following new units were started:") 1161 # Switch to the same system and see if the service gets restarted when it's modified 1162 # while the fact that it's supposed to be reloaded by the activation script is ignored. 1163 out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script-modified") 1164 assert_lacks(out, "stopping the following units:") 1165 assert_lacks(out, "NOT restarting the following changed units:") 1166 assert_contains(out, "reloading the following units: ${sortedUnits [ 1167 "reload-triggers.service" 1168 "simple-reload-service.service" 1169 "templated-reload-triggers@instance.service" 1170 "templated-simple-reload-service@instance.service" 1171 ]}\n") 1172 assert_contains(out, "restarting the following units: ${sortedUnits [ 1173 "reload-triggers-and-restart-by-as.service" 1174 "reload-triggers-and-restart.service" 1175 "simple-restart-service.service" 1176 "simple-service.service" 1177 "templated-reload-triggers-and-restart-by-as@instance.service" 1178 "templated-reload-triggers-and-restart@instance.service" 1179 "templated-simple-restart-service@instance.service" 1180 "templated-simple-service@instance.service" 1181 ]}\n") 1182 assert_lacks(out, "\nstarting the following units:") 1183 assert_lacks(out, "the following new units were started:") 1184 # The same, but in dry mode 1185 out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script", action="dry-activate") 1186 assert_lacks(out, "would stop the following units:") 1187 assert_lacks(out, "would NOT stop the following changed units:") 1188 assert_contains(out, "would reload the following units: ${sortedUnits [ 1189 "reload-triggers.service" 1190 "simple-reload-service.service" 1191 "templated-reload-triggers@instance.service" 1192 "templated-simple-reload-service@instance.service" 1193 ]}\n") 1194 assert_contains(out, "would restart the following units: ${sortedUnits [ 1195 "reload-triggers-and-restart-by-as.service" 1196 "reload-triggers-and-restart.service" 1197 "simple-restart-service.service" 1198 "simple-service.service" 1199 "templated-reload-triggers-and-restart-by-as@instance.service" 1200 "templated-reload-triggers-and-restart@instance.service" 1201 "templated-simple-restart-service@instance.service" 1202 "templated-simple-service@instance.service" 1203 ]}\n") 1204 assert_lacks(out, "\nwould start the following units:") 1205 1206 with subtest("socket-activated services"): 1207 # Socket-activated services don't get started, just the socket 1208 machine.fail("[ -S /run/test.sock ]") 1209 out = switch_to_specialisation("${machine}", "simple-socket") 1210 # assert_lacks(out, "stopping the following units:") not relevant 1211 assert_lacks(out, "NOT restarting the following changed units:") 1212 assert_lacks(out, "reloading the following units:") 1213 assert_lacks(out, "\nrestarting the following units:") 1214 assert_lacks(out, "\nstarting the following units:") 1215 assert_contains(out, "the following new units were started: socket-activated.socket\n") 1216 machine.succeed("[ -S /run/test.sock ]") 1217 1218 # Changing a non-activated service does nothing 1219 out = switch_to_specialisation("${machine}", "simple-socket-service-modified") 1220 assert_lacks(out, "stopping the following units:") 1221 assert_lacks(out, "NOT restarting the following changed units:") 1222 assert_lacks(out, "reloading the following units:") 1223 assert_lacks(out, "\nrestarting the following units:") 1224 assert_lacks(out, "\nstarting the following units:") 1225 assert_lacks(out, "the following new units were started:") 1226 machine.succeed("[ -S /run/test.sock ]") 1227 # The unit is properly activated when the socket is accessed 1228 if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello": 1229 raise Exception("Socket was not properly activated") # idk how that would happen tbh 1230 1231 # Changing an activated service with stopIfChanged=false restarts the service 1232 out = switch_to_specialisation("${machine}", "simple-socket") 1233 assert_lacks(out, "stopping the following units:") 1234 assert_lacks(out, "NOT restarting the following changed units:") 1235 assert_lacks(out, "reloading the following units:") 1236 assert_contains(out, "\nrestarting the following units: socket-activated.service\n") 1237 assert_lacks(out, "\nstarting the following units:") 1238 assert_lacks(out, "the following new units were started:") 1239 machine.succeed("[ -S /run/test.sock ]") 1240 # Socket-activation of the unit still works 1241 if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello": 1242 raise Exception("Socket was not properly activated after the service was restarted") 1243 1244 # Changing an activated service with stopIfChanged=true stops the service and 1245 # socket and starts the socket 1246 out = switch_to_specialisation("${machine}", "simple-socket-stop-if-changed") 1247 assert_contains(out, "stopping the following units: socket-activated.service, socket-activated.socket\n") 1248 assert_lacks(out, "NOT restarting the following changed units:") 1249 assert_lacks(out, "reloading the following units:") 1250 assert_lacks(out, "\nrestarting the following units:") 1251 assert_contains(out, "\nstarting the following units: socket-activated.socket\n") 1252 assert_lacks(out, "the following new units were started:") 1253 machine.succeed("[ -S /run/test.sock ]") 1254 # Socket-activation of the unit still works 1255 if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello": 1256 raise Exception("Socket was not properly activated after the service was restarted") 1257 1258 # Changing a reload trigger of a socket-activated unit only reloads it 1259 out = switch_to_specialisation("${machine}", "simple-socket-stop-if-changed-and-reloadtrigger") 1260 assert_lacks(out, "stopping the following units:") 1261 assert_lacks(out, "NOT restarting the following changed units:") 1262 assert_contains(out, "reloading the following units: socket-activated.service\n") 1263 assert_lacks(out, "\nrestarting the following units:") 1264 assert_lacks(out, "\nstarting the following units: socket-activated.socket") 1265 assert_lacks(out, "the following new units were started:") 1266 machine.succeed("[ -S /run/test.sock ]") 1267 # Socket-activation of the unit still works 1268 if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello": 1269 raise Exception("Socket was not properly activated after the service was restarted") 1270 1271 with subtest("mounts"): 1272 switch_to_specialisation("${machine}", "mount") 1273 out = machine.succeed("mount | grep 'on /testmount'") 1274 assert_contains(out, "size=1024k") 1275 # Changing options reloads the unit 1276 out = switch_to_specialisation("${machine}", "mountOptionsModified") 1277 assert_lacks(out, "stopping the following units:") 1278 assert_lacks(out, "NOT restarting the following changed units:") 1279 assert_contains(out, "reloading the following units: testmount.mount\n") 1280 assert_lacks(out, "\nrestarting the following units:") 1281 assert_lacks(out, "\nstarting the following units:") 1282 assert_lacks(out, "the following new units were started:") 1283 # It changed 1284 out = machine.succeed("mount | grep 'on /testmount'") 1285 assert_contains(out, "size=10240k") 1286 # Changing anything but `Options=` restarts the unit 1287 out = switch_to_specialisation("${machine}", "mountModified") 1288 assert_lacks(out, "stopping the following units:") 1289 assert_lacks(out, "NOT restarting the following changed units:") 1290 assert_lacks(out, "reloading the following units:") 1291 assert_contains(out, "\nrestarting the following units: testmount.mount\n") 1292 assert_lacks(out, "\nstarting the following units:") 1293 assert_lacks(out, "the following new units were started:") 1294 # It changed 1295 out = machine.succeed("mount | grep 'on /testmount'") 1296 assert_contains(out, "ramfs") 1297 1298 with subtest("timers"): 1299 switch_to_specialisation("${machine}", "timer") 1300 out = machine.succeed("systemctl show test-timer.timer") 1301 assert_contains(out, "OnCalendar=2014-03-25 02:59:56 UTC") 1302 out = switch_to_specialisation("${machine}", "timerModified") 1303 assert_lacks(out, "stopping the following units:") 1304 assert_lacks(out, "NOT restarting the following units:") 1305 assert_lacks(out, "reloading the following units:") 1306 assert_contains(out, "\nrestarting the following units: test-timer.timer\n") 1307 assert_lacks(out, "\nstarting the following units:") 1308 assert_lacks(out, "the following new units were started:") 1309 # It changed 1310 out = machine.succeed("systemctl show test-timer.timer") 1311 assert_contains(out, "OnCalendar=Fri 2012-11-23 16:00:00") 1312 1313 with subtest("targets"): 1314 # Modifying some special targets like hybrid-sleep.target does nothing 1315 out = switch_to_specialisation("${machine}", "hybridSleepModified") 1316 assert_contains(out, "stopping the following units: test-timer.timer\n") 1317 assert_lacks(out, "NOT restarting the following changed units:") 1318 assert_lacks(out, "reloading the following units:") 1319 assert_lacks(out, "\nrestarting the following units:") 1320 assert_lacks(out, "\nstarting the following units:") 1321 assert_lacks(out, "the following new units were started:") 1322 1323 # Adding a new target starts it 1324 out = switch_to_specialisation("${machine}", "target") 1325 assert_lacks(out, "stopping the following units:") 1326 assert_lacks(out, "NOT restarting the following changed units:") 1327 assert_lacks(out, "reloading the following units:") 1328 assert_lacks(out, "\nrestarting the following units:") 1329 assert_lacks(out, "\nstarting the following units:") 1330 assert_contains(out, "the following new units were started: test-target.target\n") 1331 1332 # Changing a target doesn't print anything because the unit is filtered 1333 machine.systemctl("start test-service.service") 1334 out = switch_to_specialisation("${machine}", "targetModified") 1335 assert_lacks(out, "stopping the following units:") 1336 assert_lacks(out, "NOT restarting the following changed units:") 1337 assert_lacks(out, "reloading the following units:") 1338 assert_lacks(out, "\nrestarting the following units:") 1339 assert_lacks(out, "\nstarting the following units:") 1340 assert_lacks(out, "the following new units were started:") 1341 machine.succeed("systemctl is-active test-service.service") # target was not restarted 1342 1343 # With X-StopOnReconfiguration, the target gets stopped and started 1344 out = switch_to_specialisation("${machine}", "targetModifiedStopOnReconfig") 1345 assert_lacks(out, "stopping the following units:") 1346 assert_lacks(out, "NOT restarting the following changed units:") 1347 assert_lacks(out, "reloading the following units:") 1348 assert_lacks(out, "\nrestarting the following units:") 1349 assert_lacks(out, "\nstarting the following units:") 1350 assert_lacks(out, "the following new units were started:") 1351 machine.fail("systemctl is-active test-service.servce") # target was restarted 1352 1353 # Remove the target by switching to the old specialisation 1354 out = switch_to_specialisation("${machine}", "timerModified") 1355 assert_contains(out, "stopping the following units: test-target.target\n") 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-timer.timer\n") 1361 1362 with subtest("paths"): 1363 out = switch_to_specialisation("${machine}", "path") 1364 assert_contains(out, "stopping the following units: test-timer.timer\n") 1365 assert_lacks(out, "NOT restarting the following changed units:") 1366 assert_lacks(out, "reloading the following units:") 1367 assert_lacks(out, "\nrestarting the following units:") 1368 assert_lacks(out, "\nstarting the following units:") 1369 assert_contains(out, "the following new units were started: test-watch.path\n") 1370 machine.fail("test -f /testpath-modified") 1371 1372 # touch the file, unit should be triggered 1373 machine.succeed("touch /testpath") 1374 machine.wait_until_succeeds("test -f /testpath-modified") 1375 machine.succeed("rm /testpath /testpath-modified") 1376 machine.systemctl("stop test-watch.service") 1377 switch_to_specialisation("${machine}", "pathModified") 1378 machine.succeed("touch /testpath") 1379 machine.fail("test -f /testpath-modified") 1380 machine.succeed("touch /testpath2") 1381 machine.wait_until_succeeds("test -f /testpath-modified") 1382 1383 # This test ensures that changes to slice configuration get applied. 1384 # We test this by having a slice that allows no memory allocation at 1385 # all and starting a service within it. If the service crashes, the slice 1386 # is applied and if we modify the slice to allow memory allocation, the 1387 # service should successfully start. 1388 with subtest("slices"): 1389 machine.succeed("echo 0 > /proc/sys/vm/panic_on_oom") # allow OOMing 1390 out = switch_to_specialisation("${machine}", "slice") 1391 # assert_lacks(out, "stopping the following units:") not relevant 1392 assert_lacks(out, "NOT restarting the following changed units:") 1393 assert_lacks(out, "reloading the following units:") 1394 assert_lacks(out, "\nrestarting the following units:") 1395 assert_lacks(out, "\nstarting the following units:") 1396 assert_lacks(out, "the following new units were started:") 1397 machine.fail("systemctl start testservice.service") 1398 1399 out = switch_to_specialisation("${machine}", "sliceModified") 1400 assert_lacks(out, "stopping the following units:") 1401 assert_lacks(out, "NOT restarting the following changed units:") 1402 assert_lacks(out, "reloading the following units:") 1403 assert_lacks(out, "\nrestarting the following units:") 1404 assert_lacks(out, "\nstarting the following units:") 1405 assert_lacks(out, "the following new units were started:") 1406 machine.succeed("systemctl start testservice.service") 1407 machine.succeed("echo 1 > /proc/sys/vm/panic_on_oom") # disallow OOMing 1408 ''; 1409})