WiP! build tests with nixos-module system
This commit is contained in:
parent
5db9421732
commit
c765ba3b02
13
flake.nix
13
flake.nix
|
@ -139,15 +139,12 @@
|
|||
|
||||
checks =
|
||||
# Checks for continous testing
|
||||
let tests = import ./tests;
|
||||
in
|
||||
with (forAllCrossSystems ({ system, localSystem, crossSystem }:
|
||||
import ./tests {
|
||||
inherit self;
|
||||
apps = self.apps.${system};
|
||||
localPackages = nixpkgsFor.${localSystem};
|
||||
genodepkgs = self.packages.${system};
|
||||
lib = self.lib.${system};
|
||||
nixpkgs = nixpkgsFor.${system};
|
||||
legacyPackages = self.legacyPackages.${system};
|
||||
tests {
|
||||
flake = self;
|
||||
inherit system localSystem crossSystem;
|
||||
} // {
|
||||
ports = nixpkgsFor.${localSystem}.symlinkJoin {
|
||||
name = "ports";
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
# genodeInit.children is an attrset of nixos configurations, like containers
|
||||
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
imports = [ ];
|
||||
|
||||
options.genode.init = {
|
||||
|
||||
config = mkOption {
|
||||
description = "Dhall configuration of this init instance";
|
||||
type = types.either types.str types.path;
|
||||
};
|
||||
|
||||
inputs = mkOption {
|
||||
description = "List of packages to build a ROM store with.";
|
||||
type = types.listOf types.package;
|
||||
};
|
||||
|
||||
subinits = mkOption {
|
||||
type = types.attrsOf (types.submodule ({ config, options, name, ... }: {
|
||||
options = {
|
||||
|
||||
config = mkOption {
|
||||
description = ''
|
||||
A specification of the desired configuration of this sub-init, as a NixOS module.
|
||||
'';
|
||||
type =
|
||||
let confPkgs = if config.pkgs == null then pkgs else config.pkgs;
|
||||
in lib.mkOptionType {
|
||||
name = "Toplevel NixOS config";
|
||||
merge = loc: defs:
|
||||
(import (confPkgs.path + "/nixos/lib/eval-config.nix") {
|
||||
inherit system;
|
||||
pkgs = confPkgs;
|
||||
baseModules =
|
||||
import (confPkgs.path + "/nixos/modules/module-list.nix");
|
||||
inherit (confPkgs) lib;
|
||||
modules = let
|
||||
extraConfig = {
|
||||
_file = "module at ${__curPos.file}:${
|
||||
toString __curPos.line
|
||||
}";
|
||||
config = { };
|
||||
};
|
||||
in [ extraConfig ] ++ (map (x: x.value) defs);
|
||||
prefix = [ "containers" name ];
|
||||
}).config;
|
||||
};
|
||||
};
|
||||
|
||||
pkgs = mkOption {
|
||||
type = types.nullOr types.attrs;
|
||||
default = null;
|
||||
example = literalExample "pkgs";
|
||||
description = ''
|
||||
Customise which nixpkgs to use for this container.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf options.config.isDefined {
|
||||
path = config.config.system.build.toplevel;
|
||||
})
|
||||
];
|
||||
}));
|
||||
|
||||
default = { };
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
system.build.initXml = pkgs.buildPackages.runCommand "init.xml" {
|
||||
nativeBuildInputs = with pkgs.buildPackages; [ dhall xorg.lndir ];
|
||||
DHALL_GENODE = "${pkgs.genodePackages.dhallGenode}/binary.dhall";
|
||||
INIT_CONFIG = config.genode.init.config;
|
||||
} ''
|
||||
export XDG_CACHE_HOME=$NIX_BUILD_TOP
|
||||
lndir -silent \
|
||||
${pkgs.genodePackages.dhallGenode}/.cache \
|
||||
$XDG_CACHE_HOME
|
||||
dhall text <<< "(env:DHALL_GENODE).Init.render (env:INIT_CONFIG)" > $out
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -1,21 +1,31 @@
|
|||
{ self, apps, localPackages, genodepkgs, lib, nixpkgs, legacyPackages }:
|
||||
{ flake, system, localSystem, crossSystem }:
|
||||
|
||||
let
|
||||
apps = flake.apps.${system};
|
||||
localPackages = flake.legacyPackages.${localSystem};
|
||||
genodepkgs = flake.packages.${system};
|
||||
lib = flake.lib.${system};
|
||||
nixpkgs = flake.legacyPackages.${system};
|
||||
legacyPackages = flake.legacyPackages.${system};
|
||||
|
||||
in with import ./lib/build-vms.nix {
|
||||
inherit flake system localSystem crossSystem;
|
||||
pkgs = flake.legacyPackages.${system};
|
||||
localPackages = flake.inputs.nixpkgs.legacyPackages.${localSystem};
|
||||
modulesPath = "${flake.inputs.nixpkgs}/nixos/modules";
|
||||
};
|
||||
with flake.legacyPackages.${system};
|
||||
|
||||
let
|
||||
|
||||
callTest = path:
|
||||
import path {
|
||||
pkgs = testPkgs;
|
||||
inherit nixpkgs localPackages legacyPackages;
|
||||
};
|
||||
|
||||
testFiles = map callTest [
|
||||
testSpecs = map (p: import p) [
|
||||
./log.nix
|
||||
./posix.nix
|
||||
./tox-bootstrapd.nix
|
||||
./vmm_arm.nix
|
||||
./vmm_x86.nix
|
||||
./x86.nix
|
||||
] ++ (callTest ./solo5);
|
||||
# ./posix.nix
|
||||
# ./tox-bootstrapd.nix
|
||||
# ./vmm_arm.nix
|
||||
# ./vmm_x86.nix
|
||||
# ./x86.nix
|
||||
]; # TODO ++ (callTest ./solo5);
|
||||
|
||||
testPkgs = genodepkgs;
|
||||
|
||||
|
@ -27,6 +37,7 @@ let
|
|||
x86_64-genode = "${qemuPkg}/bin/qemu-system-x86_64";
|
||||
}.${genodepkgs.stdenv.hostPlatform.system};
|
||||
|
||||
# TODO: move the cores into nixos modules
|
||||
cores = [
|
||||
{
|
||||
prefix = "hw-pc-";
|
||||
|
@ -141,6 +152,7 @@ let
|
|||
let
|
||||
testDriverName = "genode-test-driver-${name}";
|
||||
|
||||
# TODO: move buildVM into a nixos module
|
||||
buildVM = vmName:
|
||||
{ config, inputs, env ? { }, extraPaths ? [ ] }:
|
||||
let
|
||||
|
@ -178,7 +190,6 @@ let
|
|||
./test-wrapper.dhall
|
||||
} (${config}) $(stat --format '%s' ${storeTarball}/store.tar) ${storeManifest} ${manifest}";
|
||||
env' = {
|
||||
DHALL_GENODE = "${testPkgs.dhallGenode}/source.dhall";
|
||||
DHALL_GENODE_TEST = "${./test.dhall}";
|
||||
} // env;
|
||||
|
||||
|
@ -197,7 +208,10 @@ let
|
|||
''${apps.render-init.program} <<< "(${config'}).config" > $out'';
|
||||
};
|
||||
|
||||
nodes = lib.mapAttrs buildVM
|
||||
# nodes = lib.mapAttrs buildVM
|
||||
# (t.nodes or (if t ? machine then { machine = t.machine; } else { }));
|
||||
|
||||
nodes = buildVirtualNetwork
|
||||
(t.nodes or (if t ? machine then { machine = t.machine; } else { }));
|
||||
|
||||
testScript' =
|
||||
|
@ -207,7 +221,9 @@ let
|
|||
else
|
||||
testScript;
|
||||
|
||||
vms = map (node: node.script) (lib.attrValues nodes);
|
||||
vlans = map (m: m.config.virtualisation.vlans) (lib.attrValues nodes);
|
||||
|
||||
vms = map (m: m.config.system.build.vm) (lib.attrValues nodes);
|
||||
|
||||
# Generate onvenience wrappers for running the test driver
|
||||
# interactively with the specified network, and for starting the
|
||||
|
@ -285,7 +301,7 @@ let
|
|||
} else
|
||||
null;
|
||||
|
||||
in lib.lists.crossLists f [ cores' testFiles ];
|
||||
in lib.lists.crossLists f [ cores' testSpecs ];
|
||||
|
||||
in builtins.listToAttrs (builtins.filter (_: _ != null) testList)
|
||||
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
{ flake, system, localSystem, crossSystem
|
||||
# Nixpkgs, for qemu, lib and more
|
||||
, localPackages, pkgs, modulesPath }:
|
||||
|
||||
with pkgs.lib;
|
||||
with import ./qemu-flags.nix { inherit pkgs; };
|
||||
|
||||
rec {
|
||||
|
||||
inherit pkgs;
|
||||
|
||||
qemu = pkgs.qemu_test;
|
||||
|
||||
# Build a virtual network from an attribute set `{ machine1 =
|
||||
# config1; ... machineN = configN; }', where `machineX' is the
|
||||
# hostname and `configX' is a NixOS system configuration. Each
|
||||
# machine is given an arbitrary IP address in the virtual network.
|
||||
buildVirtualNetwork = nodes:
|
||||
let nodesOut = mapAttrs (n: buildVM nodesOut) (assignIPAddresses nodes);
|
||||
in nodesOut;
|
||||
|
||||
buildVM = nodes: configurations:
|
||||
|
||||
import "${modulesPath}/../lib/eval-config.nix" {
|
||||
inherit system;
|
||||
modules = configurations;
|
||||
baseModules = (import "${modulesPath}/module-list.nix") ++ [
|
||||
"${modulesPath}/virtualisation/qemu-vm.nix"
|
||||
"${modulesPath}/testing/test-instrumentation.nix" # !!! should only get added for automated test runs
|
||||
{
|
||||
key = "no-manual";
|
||||
documentation.nixos.enable = false;
|
||||
}
|
||||
{
|
||||
key = "qemu";
|
||||
system.build.qemu = qemu;
|
||||
}
|
||||
{
|
||||
key = "nodes";
|
||||
_module.args.nodes = nodes;
|
||||
}
|
||||
{
|
||||
nixpkgs = {
|
||||
inherit system crossSystem localSystem;
|
||||
pkgs = flake.legacyPackages.${system};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
# Given an attribute set { machine1 = config1; ... machineN =
|
||||
# configN; }, sequentially assign IP addresses in the 192.168.1.0/24
|
||||
# range to each machine, and set the hostname to the attribute name.
|
||||
assignIPAddresses = nodes:
|
||||
|
||||
let
|
||||
|
||||
machines = attrNames nodes;
|
||||
|
||||
machinesNumbered = zipLists machines (range 1 254);
|
||||
|
||||
nodes_ = forEach machinesNumbered (m:
|
||||
nameValuePair m.fst [
|
||||
({ config, nodes, ... }:
|
||||
let
|
||||
interfacesNumbered =
|
||||
zipLists config.virtualisation.vlans (range 1 255);
|
||||
interfaces = forEach interfacesNumbered ({ fst, snd }:
|
||||
nameValuePair "eth${toString snd}" {
|
||||
ipv4.addresses = [{
|
||||
address = "192.168.${toString fst}.${toString m.snd}";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
});
|
||||
in {
|
||||
key = "ip-address";
|
||||
config = {
|
||||
networking.hostName = mkDefault m.fst;
|
||||
|
||||
networking.interfaces = listToAttrs interfaces;
|
||||
|
||||
networking.primaryIPAddress = optionalString (interfaces != [ ])
|
||||
(head (head interfaces).value.ipv4.addresses).address;
|
||||
|
||||
# Put the IP addresses of all VMs in this machine's
|
||||
# /etc/hosts file. If a machine has multiple
|
||||
# interfaces, use the IP address corresponding to
|
||||
# the first interface (i.e. the first network in its
|
||||
# virtualisation.vlans option).
|
||||
networking.extraHosts = flip concatMapStrings machines (m':
|
||||
let config = (getAttr m' nodes).config;
|
||||
in optionalString (config.networking.primaryIPAddress != "")
|
||||
("${config.networking.primaryIPAddress} "
|
||||
+ optionalString (config.networking.domain != null)
|
||||
"${config.networking.hostName}.${config.networking.domain} "
|
||||
+ ''
|
||||
${config.networking.hostName}
|
||||
''));
|
||||
|
||||
virtualisation.qemu.options = forEach interfacesNumbered
|
||||
({ fst, snd }: qemuNICFlags snd fst m.snd);
|
||||
};
|
||||
})
|
||||
(getAttr m.fst nodes)
|
||||
]);
|
||||
|
||||
in listToAttrs nodes_;
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
# QEMU flags shared between various Nix expressions.
|
||||
{ pkgs }:
|
||||
|
||||
let
|
||||
zeroPad = n:
|
||||
pkgs.lib.optionalString (n < 16) "0" +
|
||||
(if n > 255
|
||||
then throw "Can't have more than 255 nets or nodes!"
|
||||
else pkgs.lib.toHexString n);
|
||||
in
|
||||
|
||||
rec {
|
||||
qemuNicMac = net: machine: "52:54:00:12:${zeroPad net}:${zeroPad machine}";
|
||||
|
||||
qemuNICFlags = nic: net: machine:
|
||||
[ "-device virtio-net-pci,netdev=vlan${toString nic},mac=${qemuNicMac net machine}"
|
||||
"-netdev vde,id=vlan${toString nic},sock=$QEMU_VDE_SOCKET_${toString net}"
|
||||
];
|
||||
|
||||
qemuSerialDevice = if pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64 then "ttyS0"
|
||||
else if pkgs.stdenv.isAarch32 || pkgs.stdenv.isAarch64 then "ttyAMA0"
|
||||
else throw "Unknown QEMU serial device for system '${pkgs.stdenv.hostPlatform.system}'";
|
||||
|
||||
qemuBinary = qemuPkg: {
|
||||
x86_64-linux = "${qemuPkg}/bin/qemu-kvm -cpu max";
|
||||
armv7l-linux = "${qemuPkg}/bin/qemu-system-arm -enable-kvm -machine virt -cpu host";
|
||||
aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -enable-kvm -machine virt,gic-version=host -cpu host";
|
||||
x86_64-darwin = "${qemuPkg}/bin/qemu-kvm -cpu max";
|
||||
aarch64-genode = "${qemuPkg}/bin/qemu-system-aarch64 -M virt,virtualization=true,gic_version=3 -cpu cortex-a53";
|
||||
x86_64-genode = "${qemuPkg}/bin/qemu-system-x86_64 -machine q35";
|
||||
}.${pkgs.stdenv.hostPlatform.system} or "${qemuPkg}/bin/qemu-kvm";
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
let Test = ./test.dhall ? env:DHALL_GENODE_TEST
|
||||
|
||||
let Genode = Test.Genode
|
||||
let Genode =
|
||||
env:DHALL_GENODE
|
||||
? https://git.sr.ht/~ehmry/dhall-genode/blob/master/package.dhall
|
||||
|
||||
let Child = Genode.Init.Child
|
||||
|
||||
in Test::{
|
||||
in Genode.Init::{
|
||||
, children = toMap
|
||||
{ test-log =
|
||||
Child.flat
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
{ pkgs, ... }:
|
||||
with pkgs;
|
||||
|
||||
{
|
||||
name = "log";
|
||||
machine = {
|
||||
config = ./log.dhall;
|
||||
inputs = [ (pkgs.genodeSources.depot "test-log") ];
|
||||
machine = { config, pkgs, ... }: {
|
||||
imports = [
|
||||
../nixos-modules/genode-init.nix
|
||||
];
|
||||
genode.init = {
|
||||
config = ./log.dhall;
|
||||
inputs = [ (pkgs.genodeSources.depot "test-log") ];
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
|
Loading…
Reference in New Issue