{ system , pkgs ? import ../.. { inherit system config; } # Use a minimal kernel? , minimal ? false # Ignored , config ? { } # !!! See comment about args in lib/modules.nix , specialArgs ? { } # Modules to add to each VM , extraConfigurations ? [ ] }: with pkgs; rec { inherit pkgs; mkTestDriver = let testDriverScript = ./test-driver/test-driver.py; in qemu_pkg: stdenv.mkDerivation { name = "nixos-test-driver"; nativeBuildInputs = [ makeWrapper ]; buildInputs = [ (python3.withPackages (p: [ p.ptpython p.colorama ])) ]; checkInputs = with python3Packages; [ pylint black mypy ]; dontUnpack = true; preferLocalBuild = true; buildPhase = '' python < maxTestNameLen then abort ("The name of the test '${name}' must not be longer than ${toString maxTestNameLen} " + "it's currently ${toString testNameLen} characters long.") else "nixos-test-driver-${name}"; in lib.warnIf skipLint "Linting is disabled" (runCommand testDriverName { nativeBuildInputs = [ makeWrapper ]; testScript = testScript'; preferLocalBuild = true; testName = name; passthru = passthru // { inherit nodes; }; } '' mkdir -p $out/bin echo -n "$testScript" > $out/test-script ${lib.optionalString (!skipLint) '' PYFLAKES_BUILTINS="$( echo -n ${lib.escapeShellArg (lib.concatStringsSep "," nodeHostNames)}, < ${lib.escapeShellArg "${testDriver}/nix-support/driver-exports"} )" ${python3Packages.pyflakes}/bin/pyflakes $out/test-script ''} ln -s ${testDriver}/bin/nixos-test-driver $out/bin/ vms=($(for i in ${toString vms}; do echo $i/bin/run-*-vm; done)) wrapProgram $out/bin/nixos-test-driver \ --add-flags "''${vms[*]}" \ ${lib.optionalString enableOCR "--prefix PATH : '${ocrProg}/bin:${imagemagick_tiff}/bin'"} \ --run "export testScript=\"\$(${coreutils}/bin/cat $out/test-script)\"" \ --set VLANS '${toString vlans}' ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-run-vms wrapProgram $out/bin/nixos-run-vms \ --add-flags "''${vms[*]}" \ ${lib.optionalString enableOCR "--prefix PATH : '${ocrProg}/bin'"} \ --set tests 'start_all(); join_all();' \ --set VLANS '${toString vlans}' ''); # " passMeta = drv: drv // lib.optionalAttrs (t ? meta) { meta = (drv.meta or { }) // t.meta; }; driver = mkDriver null; driverInteractive = mkDriver pkgs.qemu; test = passMeta (runTests { inherit driver pos; }); nodeNames = builtins.attrNames driver.nodes; invalidNodeNames = lib.filter (node: builtins.match "^[A-z_]([A-z0-9_]+)?$" node == null) nodeNames; nodeHostNames = map (c: c.config.system.name) (lib.attrValues driver.nodes); in if lib.length invalidNodeNames > 0 then throw '' Cannot create machines out of (${lib.concatStringsSep ", " invalidNodeNames})! All machines are referenced as python variables in the testing framework which will break the script when special characters are used. Please stick to alphanumeric chars and underscores as separation. '' else test // { inherit test driver driverInteractive; inherit (driver) nodes; }; runInMachine = { drv , machine , preBuild ? "" , postBuild ? "" , qemu ? pkgs.qemu_test , ... # ??? }: let build-vms = import ./build-vms.nix { inherit system pkgs minimal specialArgs extraConfigurations; }; vm = build-vms.buildVM { } [ machine { key = "run-in-machine"; networking.hostName = "client"; nix.readOnlyStore = false; virtualisation.writableStore = false; } ]; buildrunner = writeText "vm-build" '' source $1 ${coreutils}/bin/mkdir -p $TMPDIR cd $TMPDIR exec $origBuilder $origArgs ''; testScript = '' start_all() client.wait_for_unit("multi-user.target") ${preBuild} client.succeed("env -i ${bash}/bin/bash ${buildrunner} /tmp/xchg/saved-env >&2") ${postBuild} client.succeed("sync") # flush all data before pulling the plug ''; vmRunCommand = writeText "vm-run" '' xchg=vm-state-client/xchg ${coreutils}/bin/mkdir $out ${coreutils}/bin/mkdir -p $xchg for i in $passAsFile; do i2=''${i}Path _basename=$(${coreutils}/bin/basename ''${!i2}) ${coreutils}/bin/cp ''${!i2} $xchg/$_basename eval $i2=/tmp/xchg/$_basename ${coreutils}/bin/ls -la $xchg done unset i i2 _basename export | ${gnugrep}/bin/grep -v '^xchg=' > $xchg/saved-env unset xchg export tests='${testScript}' ${mkTestDriver qemu}/bin/nixos-test-driver --keep-vm-state ${vm.config.system.build.vm}/bin/run-*-vm ''; # */ in lib.overrideDerivation drv (attrs: { requiredSystemFeatures = [ "kvm" ]; builder = "${bash}/bin/sh"; args = [ "-e" vmRunCommand ]; origArgs = attrs.args; origBuilder = attrs.builder; }); runInMachineWithX = { require ? [ ], ... } @ args: let client = { ... }: { inherit require; imports = [ ../tests/common/auto.nix ]; virtualisation.memorySize = 1024; services.xserver.enable = true; test-support.displayManager.auto.enable = true; services.xserver.displayManager.defaultSession = "none+icewm"; services.xserver.windowManager.icewm.enable = true; }; in runInMachine ({ machine = client; preBuild = '' client.wait_for_x() ''; } // args); simpleTest = as: (makeTest as).test; }