1# Test whether hibernation from partition works.
2
3{ system ? builtins.currentSystem
4, config ? {}
5, pkgs ? import ../.. { inherit system config; }
6}:
7
8with import ../lib/testing-python.nix { inherit system pkgs; };
9
10let
11 # System configuration of the installed system, which is used for the actual
12 # hibernate testing.
13 installedConfig = with pkgs.lib; {
14 imports = [
15 ../modules/testing/test-instrumentation.nix
16 ../modules/profiles/qemu-guest.nix
17 ../modules/profiles/minimal.nix
18 ];
19
20 hardware.enableAllFirmware = mkForce false;
21 documentation.nixos.enable = false;
22 boot.loader.grub.device = "/dev/vda";
23
24 systemd.services.backdoor.conflicts = [ "sleep.target" ];
25
26 powerManagement.resumeCommands = "systemctl --no-block restart backdoor.service";
27
28 fileSystems = {
29 "/".device = "/dev/vda2";
30 };
31 swapDevices = mkOverride 0 [ { device = "/dev/vda1"; } ];
32 };
33 installedSystem = (import ../lib/eval-config.nix {
34 inherit system;
35 modules = [ installedConfig ];
36 }).config.system.build.toplevel;
37in makeTest {
38 name = "hibernate";
39
40 nodes = {
41 # System configuration used for installing the installedConfig from above.
42 machine = { config, lib, pkgs, ... }: with lib; {
43 imports = [
44 ../modules/profiles/installation-device.nix
45 ../modules/profiles/base.nix
46 ];
47
48 nix.binaryCaches = mkForce [ ];
49 nix.extraOptions = ''
50 hashed-mirrors =
51 connect-timeout = 1
52 '';
53
54 virtualisation.memorySize = 2048;
55 virtualisation.diskSize = 8 * 1024;
56 virtualisation.emptyDiskImages = [
57 # Small root disk for installer
58 512
59 ];
60 virtualisation.bootDevice = "/dev/vdb";
61 };
62 };
63
64 # 9P doesn't support reconnection to virtio transport after a hibernation.
65 # Therefore, machine just hangs on any Nix store access.
66 # To avoid this, we install NixOS onto a temporary disk with everything we need
67 # included into the store.
68
69 testScript =
70 ''
71 def create_named_machine(name):
72 machine = create_machine(
73 {
74 "qemuFlags": "-cpu max ${
75 if system == "x86_64-linux" then "-m 1024"
76 else "-m 768 -enable-kvm -machine virt,gic-version=host"}",
77 "hdaInterface": "virtio",
78 "hda": "vm-state-machine/machine.qcow2",
79 "name": name,
80 }
81 )
82 driver.machines.append(machine)
83 return machine
84
85
86 # Install NixOS
87 machine.start()
88 machine.succeed(
89 # Partition /dev/vda
90 "flock /dev/vda parted --script /dev/vda -- mklabel msdos"
91 + " mkpart primary linux-swap 1M 1024M"
92 + " mkpart primary ext2 1024M -1s",
93 "udevadm settle",
94 "mkfs.ext3 -L nixos /dev/vda2",
95 "mount LABEL=nixos /mnt",
96 "mkswap /dev/vda1 -L swap",
97 # Install onto /mnt
98 "nix-store --load-db < ${pkgs.closureInfo {rootPaths = [installedSystem];}}/registration",
99 "nixos-install --root /mnt --system ${installedSystem} --no-root-passwd --no-channel-copy >&2",
100 )
101 machine.shutdown()
102
103 # Start up
104 hibernate = create_named_machine("hibernate")
105
106 # Drop in file that checks if we un-hibernated properly (and not booted fresh)
107 hibernate.succeed(
108 "mkdir /run/test",
109 "mount -t ramfs -o size=1m ramfs /run/test",
110 "echo not persisted to disk > /run/test/suspended",
111 )
112
113 # Hibernate machine
114 hibernate.execute("systemctl hibernate >&2 &", check_return=False)
115 hibernate.wait_for_shutdown()
116
117 # Restore machine from hibernation, validate our ramfs file is there.
118 resume = create_named_machine("resume")
119 resume.start()
120 resume.succeed("grep 'not persisted to disk' /run/test/suspended")
121 '';
122
123}