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 qemu-common = import ../lib/qemu-common.nix { inherit (pkgs) lib pkgs; };
11
12 iso =
13 (import ../lib/eval-config.nix {
14 inherit system;
15 modules = [
16 ../modules/installer/cd-dvd/installation-cd-minimal.nix
17 ../modules/testing/test-instrumentation.nix
18 ];
19 }).config.system.build.isoImage;
20
21 sd =
22 (import ../lib/eval-config.nix {
23 inherit system;
24 modules = [
25 ../modules/installer/sd-card/sd-image-x86_64.nix
26 ../modules/testing/test-instrumentation.nix
27 { sdImage.compressImage = false; }
28 ];
29 }).config.system.build.sdImage;
30
31 pythonDict = params: "\n {\n ${concatStringsSep ",\n " (mapAttrsToList (name: param: "\"${name}\": \"${param}\"") params)},\n }\n";
32
33 makeBootTest = name: extraConfig:
34 let
35 machineConfig = pythonDict ({
36 qemuBinary = qemu-common.qemuBinary pkgs.qemu_test;
37 qemuFlags = "-m 768";
38 } // extraConfig);
39 in
40 makeTest {
41 name = "boot-" + name;
42 nodes = { };
43 testScript =
44 ''
45 machine = create_machine(${machineConfig})
46 machine.start()
47 machine.wait_for_unit("multi-user.target")
48 machine.succeed("nix store verify --no-trust -r --option experimental-features nix-command /run/current-system")
49
50 with subtest("Check whether the channel got installed correctly"):
51 machine.succeed("nix-instantiate --dry-run '<nixpkgs>' -A hello")
52 machine.succeed("nix-env --dry-run -iA nixos.procps")
53
54 machine.shutdown()
55 '';
56 };
57
58 makeNetbootTest = name: extraConfig:
59 let
60 config = (import ../lib/eval-config.nix {
61 inherit system;
62 modules =
63 [ ../modules/installer/netboot/netboot.nix
64 ../modules/testing/test-instrumentation.nix
65 { key = "serial"; }
66 ];
67 }).config;
68 ipxeBootDir = pkgs.symlinkJoin {
69 name = "ipxeBootDir";
70 paths = [
71 config.system.build.netbootRamdisk
72 config.system.build.kernel
73 config.system.build.netbootIpxeScript
74 ];
75 };
76 machineConfig = pythonDict ({
77 qemuBinary = qemu-common.qemuBinary pkgs.qemu_test;
78 qemuFlags = "-boot order=n -m 2000";
79 netBackendArgs = "tftp=${ipxeBootDir},bootfile=netboot.ipxe";
80 } // extraConfig);
81 in
82 makeTest {
83 name = "boot-netboot-" + name;
84 nodes = { };
85 testScript = ''
86 machine = create_machine(${machineConfig})
87 machine.start()
88 machine.wait_for_unit("multi-user.target")
89 machine.shutdown()
90 '';
91 };
92 uefiBinary = {
93 x86_64-linux = "${pkgs.OVMF.fd}/FV/OVMF.fd";
94 aarch64-linux = "${pkgs.OVMF.fd}/FV/QEMU_EFI.fd";
95 }.${pkgs.stdenv.hostPlatform.system};
96in {
97 uefiCdrom = makeBootTest "uefi-cdrom" {
98 cdrom = "${iso}/iso/${iso.isoName}";
99 bios = uefiBinary;
100 };
101
102 uefiUsb = makeBootTest "uefi-usb" {
103 usb = "${iso}/iso/${iso.isoName}";
104 bios = uefiBinary;
105 };
106
107 uefiNetboot = makeNetbootTest "uefi" {
108 bios = uefiBinary;
109 # Custom ROM is needed for EFI PXE boot. I failed to understand exactly why, because QEMU should still use iPXE for EFI.
110 netFrontendArgs = "romfile=${pkgs.ipxe}/ipxe.efirom";
111 };
112} // optionalAttrs (pkgs.stdenv.hostPlatform.system == "x86_64-linux") {
113 biosCdrom = makeBootTest "bios-cdrom" {
114 cdrom = "${iso}/iso/${iso.isoName}";
115 };
116
117 biosUsb = makeBootTest "bios-usb" {
118 usb = "${iso}/iso/${iso.isoName}";
119 };
120
121 biosNetboot = makeNetbootTest "bios" {};
122
123 ubootExtlinux = let
124 sdImage = "${sd}/sd-image/${sd.imageName}";
125 mutableImage = "/tmp/linked-image.qcow2";
126
127 machineConfig = pythonDict {
128 bios = "${pkgs.ubootQemuX86}/u-boot.rom";
129 qemuFlags = "-m 768 -machine type=pc,accel=tcg -drive file=${mutableImage},if=ide,format=qcow2";
130 };
131 in makeTest {
132 name = "boot-uboot-extlinux";
133 nodes = { };
134 testScript = ''
135 import os
136
137 # Create a mutable linked image backed by the read-only SD image
138 if os.system("qemu-img create -f qcow2 -F raw -b ${sdImage} ${mutableImage}") != 0:
139 raise RuntimeError("Could not create mutable linked image")
140
141 machine = create_machine(${machineConfig})
142 machine.start()
143 machine.wait_for_unit("multi-user.target")
144 machine.succeed("nix store verify -r --no-trust --option experimental-features nix-command /run/current-system")
145 machine.shutdown()
146 '';
147 };
148}