1/* 2 Create tests that run in the nix sandbox with additional access to selected host paths 3 4 This is for example useful for testing hardware where a tests needs access to 5 /sys and optionally more. 6 7 The following example shows a test that accesses the GPU: 8 9 Example: 10 makeImpureTest { 11 name = "opencl"; 12 testedPackage = "mypackage"; # Or testPath = "mypackage.impureTests.opencl.testDerivation" 13 14 sandboxPaths = [ "/sys" "/dev/dri" ]; # Defaults to ["/sys"] 15 prepareRunCommands = ""; # (Optional) Setup for the runScript 16 nixFlags = []; # (Optional) nix-build options for the runScript 17 18 testScript = "..."; 19 } 20 21 Save as `test.nix` next to a package and reference it from the package: 22 passthru.impureTests = { opencl = callPackage ./test.nix {}; }; 23 24 `makeImpureTest` will return here a script that contains the actual nix-build command including all necessary sandbox flags. 25 26 It can be executed like this: 27 $(nix-build -A mypackage.impureTests) 28 29 Rerun an already cached test: 30 $(nix-build -A mypackage.impureTests) --check 31*/ 32{ 33 lib, 34 stdenv, 35 writeShellScript, 36 37 name, 38 testedPackage ? null, 39 testPath ? "${testedPackage}.impureTests.${name}.testDerivation", 40 sandboxPaths ? [ "/sys" ], 41 prepareRunCommands ? "", 42 nixFlags ? [ ], 43 testScript, 44 ... 45}@args: 46 47let 48 sandboxPathsTests = builtins.map (path: "[[ ! -e '${path}' ]]") sandboxPaths; 49 sandboxPathsTest = lib.concatStringsSep " || " sandboxPathsTests; 50 sandboxPathsList = lib.concatStringsSep " " sandboxPaths; 51 52 testDerivation = stdenv.mkDerivation ( 53 lib.recursiveUpdate 54 { 55 name = "test-run-${name}"; 56 57 requiredSystemFeatures = [ "nixos-test" ]; 58 59 buildCommand = '' 60 mkdir -p $out 61 62 if ${sandboxPathsTest}; then 63 echo 'Run this test as *root* with `--option extra-sandbox-paths '"'${sandboxPathsList}'"'`' 64 exit 1 65 fi 66 67 # Run test 68 ${testScript} 69 ''; 70 71 passthru.runScript = runScript; 72 } 73 ( 74 builtins.removeAttrs args [ 75 "lib" 76 "stdenv" 77 "writeShellScript" 78 79 "name" 80 "testedPackage" 81 "testPath" 82 "sandboxPaths" 83 "prepareRunCommands" 84 "nixFlags" 85 "testScript" 86 ] 87 ) 88 ); 89 90 runScript = writeShellScript "run-script-${name}" '' 91 set -euo pipefail 92 93 ${prepareRunCommands} 94 95 sudo nix-build --option extra-sandbox-paths '${sandboxPathsList}' ${lib.escapeShellArgs nixFlags} -A ${testPath} "$@" 96 ''; 97in 98# The main output is the run script, inject the derivation for the actual test 99runScript.overrideAttrs (old: { 100 passthru = { inherit testDerivation; }; 101})