1{ system ? builtins.currentSystem,
2 config ? {},
3 pkgs ? import ../.. { inherit system config; }
4}:
5
6with import ../lib/testing-python.nix { inherit system pkgs; };
7with pkgs.lib;
8
9let
10 baseline = {
11 virtualisation.useBootLoader = true;
12 };
13 grub = {
14 boot.loader.grub.enable = true;
15 };
16 systemd-boot = {
17 boot.loader.systemd-boot.enable = true;
18 };
19 uefi = {
20 virtualisation.useEFIBoot = true;
21 boot.loader.efi.canTouchEfiVariables = true;
22 boot.loader.grub.efiSupport = true;
23 environment.systemPackages = [ pkgs.efibootmgr ];
24 };
25 standard = {
26 boot.bootspec.enable = true;
27
28 imports = [
29 baseline
30 systemd-boot
31 uefi
32 ];
33 };
34in
35{
36 basic = makeTest {
37 name = "systemd-boot-with-bootspec";
38 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
39
40 nodes.machine = standard;
41
42 testScript = ''
43 machine.start()
44 machine.wait_for_unit("multi-user.target")
45
46 machine.succeed("test -e /run/current-system/boot.json")
47 '';
48 };
49
50 grub = makeTest {
51 name = "grub-with-bootspec";
52 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
53
54 nodes.machine = {
55 boot.bootspec.enable = true;
56
57 imports = [
58 baseline
59 grub
60 uefi
61 ];
62 };
63
64 testScript = ''
65 machine.start()
66 machine.wait_for_unit("multi-user.target")
67
68 machine.succeed("test -e /run/current-system/boot.json")
69 '';
70 };
71
72 legacy-boot = makeTest {
73 name = "legacy-boot-with-bootspec";
74 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
75
76 nodes.machine = {
77 boot.bootspec.enable = true;
78
79 imports = [
80 baseline
81 grub
82 ];
83 };
84
85 testScript = ''
86 machine.start()
87 machine.wait_for_unit("multi-user.target")
88
89 machine.succeed("test -e /run/current-system/boot.json")
90 '';
91 };
92
93 # Check that initrd create corresponding entries in bootspec.
94 initrd = makeTest {
95 name = "bootspec-with-initrd";
96 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
97
98 nodes.machine = {
99 imports = [ standard ];
100 environment.systemPackages = [ pkgs.jq ];
101 # It's probably the case, but we want to make it explicit here.
102 boot.initrd.enable = true;
103 };
104
105 testScript = ''
106 import json
107
108 machine.start()
109 machine.wait_for_unit("multi-user.target")
110
111 machine.succeed("test -e /run/current-system/boot.json")
112
113 bootspec = json.loads(machine.succeed("jq -r '.\"org.nixos.bootspec.v1\"' /run/current-system/boot.json"))
114
115 assert 'initrd' in bootspec, "Bootspec should contain initrd field when initrd is enabled"
116 assert 'initrdSecrets' not in bootspec, "Bootspec should not contain initrdSecrets when there's no initrdSecrets"
117 '';
118 };
119
120 # Check that initrd secrets create corresponding entries in bootspec.
121 initrd-secrets = makeTest {
122 name = "bootspec-with-initrd-secrets";
123 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
124
125 nodes.machine = {
126 imports = [ standard ];
127 environment.systemPackages = [ pkgs.jq ];
128 # It's probably the case, but we want to make it explicit here.
129 boot.initrd.enable = true;
130 boot.initrd.secrets."/some/example" = pkgs.writeText "example-secret" "test";
131 };
132
133 testScript = ''
134 import json
135
136 machine.start()
137 machine.wait_for_unit("multi-user.target")
138
139 machine.succeed("test -e /run/current-system/boot.json")
140
141 bootspec = json.loads(machine.succeed("jq -r '.\"org.nixos.bootspec.v1\"' /run/current-system/boot.json"))
142
143 assert 'initrdSecrets' in bootspec, "Bootspec should contain an 'initrdSecrets' field given there's an initrd secret"
144 '';
145 };
146
147
148 # Check that specialisations create corresponding entries in bootspec.
149 specialisation = makeTest {
150 name = "bootspec-with-specialisation";
151 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
152
153 nodes.machine = {
154 imports = [ standard ];
155 environment.systemPackages = [ pkgs.jq ];
156 specialisation.something.configuration = {};
157 };
158
159 testScript = ''
160 import json
161
162 machine.start()
163 machine.wait_for_unit("multi-user.target")
164
165 machine.succeed("test -e /run/current-system/boot.json")
166 machine.succeed("test -e /run/current-system/specialisation/something/boot.json")
167
168 sp_in_parent = json.loads(machine.succeed("jq -r '.\"org.nixos.specialisation.v1\".something' /run/current-system/boot.json"))
169 sp_in_fs = json.loads(machine.succeed("cat /run/current-system/specialisation/something/boot.json"))
170
171 assert sp_in_parent['org.nixos.bootspec.v1'] == sp_in_fs['org.nixos.bootspec.v1'], "Bootspecs of the same specialisation are different!"
172 '';
173 };
174
175 # Check that extensions are propagated.
176 extensions = makeTest {
177 name = "bootspec-with-extensions";
178 meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
179
180 nodes.machine = { config, ... }: {
181 imports = [ standard ];
182 environment.systemPackages = [ pkgs.jq ];
183 boot.bootspec.extensions = {
184 "org.nix-tests.product" = {
185 osRelease = config.environment.etc."os-release".source;
186 };
187 };
188 };
189
190 testScript = ''
191 machine.start()
192 machine.wait_for_unit("multi-user.target")
193
194 current_os_release = machine.succeed("cat /etc/os-release")
195 bootspec_os_release = machine.succeed("cat $(jq -r '.\"org.nix-tests.product\".osRelease' /run/current-system/boot.json)")
196
197 assert current_os_release == bootspec_os_release, "Filename referenced by extension has unexpected contents"
198 '';
199 };
200
201}