at 18.09-beta 7.8 kB view raw
1{ system, minimal ? false, config ? {} }: 2 3with import ./build-vms.nix { inherit system minimal config; }; 4with pkgs; 5 6let 7 jquery-ui = callPackage ./testing/jquery-ui.nix { }; 8 jquery = callPackage ./testing/jquery.nix { }; 9 10in rec { 11 12 inherit pkgs; 13 14 15 testDriver = stdenv.mkDerivation { 16 name = "nixos-test-driver"; 17 18 buildInputs = [ makeWrapper perl ]; 19 20 unpackPhase = "true"; 21 22 preferLocalBuild = true; 23 24 installPhase = 25 '' 26 mkdir -p $out/bin 27 cp ${./test-driver/test-driver.pl} $out/bin/nixos-test-driver 28 chmod u+x $out/bin/nixos-test-driver 29 30 libDir=$out/lib/perl5/site_perl 31 mkdir -p $libDir 32 cp ${./test-driver/Machine.pm} $libDir/Machine.pm 33 cp ${./test-driver/Logger.pm} $libDir/Logger.pm 34 35 wrapProgram $out/bin/nixos-test-driver \ 36 --prefix PATH : "${lib.makeBinPath [ qemu_test vde2 netpbm coreutils ]}" \ 37 --prefix PERL5LIB : "${with perlPackages; lib.makePerlPath [ TermReadLineGnu XMLWriter IOTty FileSlurp ]}:$out/lib/perl5/site_perl" 38 ''; 39 }; 40 41 42 # Run an automated test suite in the given virtual network. 43 # `driver' is the script that runs the network. 44 runTests = driver: 45 stdenv.mkDerivation { 46 name = "vm-test-run-${driver.testName}"; 47 48 requiredSystemFeatures = [ "kvm" "nixos-test" ]; 49 50 buildInputs = [ libxslt ]; 51 52 buildCommand = 53 '' 54 mkdir -p $out/nix-support 55 56 LOGFILE=$out/log.xml tests='eval $ENV{testScript}; die $@ if $@;' ${driver}/bin/nixos-test-driver 57 58 # Generate a pretty-printed log. 59 xsltproc --output $out/log.html ${./test-driver/log2html.xsl} $out/log.xml 60 ln -s ${./test-driver/logfile.css} $out/logfile.css 61 ln -s ${./test-driver/treebits.js} $out/treebits.js 62 ln -s ${jquery}/js/jquery.min.js $out/ 63 ln -s ${jquery-ui}/js/jquery-ui.min.js $out/ 64 65 touch $out/nix-support/hydra-build-products 66 echo "report testlog $out log.html" >> $out/nix-support/hydra-build-products 67 68 for i in */xchg/coverage-data; do 69 mkdir -p $out/coverage-data 70 mv $i $out/coverage-data/$(dirname $(dirname $i)) 71 done 72 ''; # */ 73 }; 74 75 76 makeTest = 77 { testScript 78 , makeCoverageReport ? false 79 , enableOCR ? false 80 , name ? "unnamed" 81 , ... 82 } @ t: 83 84 let 85 # A standard store path to the vm monitor is built like this: 86 # /tmp/nix-build-vm-test-run-$name.drv-0/vm-state-machine/monitor 87 # The max filename length of a unix domain socket is 108 bytes. 88 # This means $name can at most be 50 bytes long. 89 maxTestNameLen = 50; 90 testNameLen = builtins.stringLength name; 91 92 testDriverName = with builtins; 93 if testNameLen > maxTestNameLen then 94 abort ("The name of the test '${name}' must not be longer than ${toString maxTestNameLen} " + 95 "it's currently ${toString testNameLen} characters long.") 96 else 97 "nixos-test-driver-${name}"; 98 99 nodes = buildVirtualNetwork ( 100 t.nodes or (if t ? machine then { machine = t.machine; } else { })); 101 102 testScript' = 103 # Call the test script with the computed nodes. 104 if lib.isFunction testScript 105 then testScript { inherit nodes; } 106 else testScript; 107 108 vlans = map (m: m.config.virtualisation.vlans) (lib.attrValues nodes); 109 110 vms = map (m: m.config.system.build.vm) (lib.attrValues nodes); 111 112 ocrProg = tesseract_4.override { enableLanguages = [ "eng" ]; }; 113 114 imagemagick_tiff = imagemagick_light.override { inherit libtiff; }; 115 116 # Generate onvenience wrappers for running the test driver 117 # interactively with the specified network, and for starting the 118 # VMs from the command line. 119 driver = runCommand testDriverName 120 { buildInputs = [ makeWrapper]; 121 testScript = testScript'; 122 preferLocalBuild = true; 123 testName = name; 124 } 125 '' 126 mkdir -p $out/bin 127 echo "$testScript" > $out/test-script 128 ln -s ${testDriver}/bin/nixos-test-driver $out/bin/ 129 vms=($(for i in ${toString vms}; do echo $i/bin/run-*-vm; done)) 130 wrapProgram $out/bin/nixos-test-driver \ 131 --add-flags "''${vms[*]}" \ 132 ${lib.optionalString enableOCR 133 "--prefix PATH : '${ocrProg}/bin:${imagemagick_tiff}/bin'"} \ 134 --run "export testScript=\"\$(cat $out/test-script)\"" \ 135 --set VLANS '${toString vlans}' 136 ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-run-vms 137 wrapProgram $out/bin/nixos-run-vms \ 138 --add-flags "''${vms[*]}" \ 139 ${lib.optionalString enableOCR "--prefix PATH : '${ocrProg}/bin'"} \ 140 --set tests 'startAll; joinAll;' \ 141 --set VLANS '${toString vlans}' \ 142 ${lib.optionalString (builtins.length vms == 1) "--set USE_SERIAL 1"} 143 ''; # " 144 145 passMeta = drv: drv // lib.optionalAttrs (t ? meta) { 146 meta = (drv.meta or {}) // t.meta; 147 }; 148 149 test = passMeta (runTests driver); 150 report = passMeta (releaseTools.gcovReport { coverageRuns = [ test ]; }); 151 152 in (if makeCoverageReport then report else test) // { 153 inherit nodes driver test; 154 }; 155 156 runInMachine = 157 { drv 158 , machine 159 , preBuild ? "" 160 , postBuild ? "" 161 , ... # ??? 162 }: 163 let 164 vm = buildVM { } 165 [ machine 166 { key = "run-in-machine"; 167 networking.hostName = "client"; 168 nix.readOnlyStore = false; 169 virtualisation.writableStore = false; 170 } 171 ]; 172 173 buildrunner = writeText "vm-build" '' 174 source $1 175 176 ${coreutils}/bin/mkdir -p $TMPDIR 177 cd $TMPDIR 178 179 exec $origBuilder $origArgs 180 ''; 181 182 testScript = '' 183 startAll; 184 $client->waitForUnit("multi-user.target"); 185 ${preBuild} 186 $client->succeed("env -i ${bash}/bin/bash ${buildrunner} /tmp/xchg/saved-env >&2"); 187 ${postBuild} 188 $client->succeed("sync"); # flush all data before pulling the plug 189 ''; 190 191 vmRunCommand = writeText "vm-run" '' 192 xchg=vm-state-client/xchg 193 ${coreutils}/bin/mkdir $out 194 ${coreutils}/bin/mkdir -p $xchg 195 196 for i in $passAsFile; do 197 i2=''${i}Path 198 _basename=$(${coreutils}/bin/basename ''${!i2}) 199 ${coreutils}/bin/cp ''${!i2} $xchg/$_basename 200 eval $i2=/tmp/xchg/$_basename 201 ${coreutils}/bin/ls -la $xchg 202 done 203 204 unset i i2 _basename 205 export | ${gnugrep}/bin/grep -v '^xchg=' > $xchg/saved-env 206 unset xchg 207 208 export tests='${testScript}' 209 ${testDriver}/bin/nixos-test-driver ${vm.config.system.build.vm}/bin/run-*-vm 210 ''; # */ 211 212 in 213 lib.overrideDerivation drv (attrs: { 214 requiredSystemFeatures = [ "kvm" ]; 215 builder = "${bash}/bin/sh"; 216 args = ["-e" vmRunCommand]; 217 origArgs = attrs.args; 218 origBuilder = attrs.builder; 219 }); 220 221 222 runInMachineWithX = { require ? [], ... } @ args: 223 let 224 client = 225 { ... }: 226 { 227 inherit require; 228 virtualisation.memorySize = 1024; 229 services.xserver.enable = true; 230 services.xserver.displayManager.slim.enable = false; 231 services.xserver.displayManager.auto.enable = true; 232 services.xserver.windowManager.default = "icewm"; 233 services.xserver.windowManager.icewm.enable = true; 234 services.xserver.desktopManager.default = "none"; 235 }; 236 in 237 runInMachine ({ 238 machine = client; 239 preBuild = 240 '' 241 $client->waitForX; 242 ''; 243 } // args); 244 245 246 simpleTest = as: (makeTest as).test; 247 248}