nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at devShellTools-shell 386 lines 11 kB view raw
1{ 2 testers, 3 lib, 4 pkgs, 5 hello, 6 runCommand, 7 emptyFile, 8 emptyDirectory, 9 stdenvNoCC, 10 ... 11}: 12let 13 pkgs-with-overlay = pkgs.extend ( 14 final: prev: { 15 proof-of-overlay-hello = prev.hello; 16 } 17 ); 18 19 dummyVersioning = { 20 revision = "test"; 21 versionSuffix = "test"; 22 label = "test"; 23 }; 24 25 overrideStructuredAttrs = 26 enable: drv: 27 drv.overrideAttrs (old: { 28 failed = old.failed.overrideAttrs (oldFailed: { 29 name = oldFailed.name + "${lib.optionalString (!enable) "-no"}-structuredAttrs"; 30 __structuredAttrs = enable; 31 }); 32 }); 33 runNixOSTest-example = pkgs-with-overlay.testers.runNixOSTest ( 34 { lib, ... }: 35 { 36 name = "runNixOSTest-test"; 37 nodes.machine = 38 { pkgs, ... }: 39 { 40 system.nixos = dummyVersioning; 41 environment.systemPackages = [ 42 pkgs.proof-of-overlay-hello 43 pkgs.figlet 44 ]; 45 }; 46 testScript = '' 47 machine.succeed("hello | figlet >/dev/console") 48 ''; 49 } 50 ); 51 52in 53lib.recurseIntoAttrs { 54 lycheeLinkCheck = lib.recurseIntoAttrs pkgs.lychee.tests; 55 56 hasPkgConfigModules = pkgs.callPackage ../hasPkgConfigModules/tests.nix { }; 57 58 hasCmakeConfigModules = pkgs.callPackage ../hasCmakeConfigModules/tests.nix { }; 59 60 shellcheck = pkgs.callPackage ../shellcheck/tests.nix { }; 61 62 shfmt = pkgs.callPackages ../shfmt/tests.nix { }; 63 64 runCommand = lib.recurseIntoAttrs { 65 bork = pkgs.python3Packages.bork.tests.pytest-network; 66 67 dns-resolution = testers.runCommand { 68 name = "runCommand-dns-resolution-test"; 69 nativeBuildInputs = [ pkgs.ldns ]; 70 script = '' 71 drill example.com 72 touch $out 73 ''; 74 }; 75 76 nonDefault-hash = testers.runCommand { 77 name = "runCommand-nonDefaultHash-test"; 78 script = '' 79 mkdir $out 80 touch $out/empty 81 echo aaaaaaaaaaicjnrkeflncmrlk > $out/keymash 82 ''; 83 hash = "sha256-eMy+6bkG+KS75u7Zt4PM3APhtdVd60NxmBRN5GKJrHs="; 84 }; 85 }; 86 87 inherit runNixOSTest-example; 88 89 runNixOSTest-extendNixOS = 90 let 91 t = runNixOSTest-example.extendNixOS { 92 module = 93 { hi, lib, ... }: 94 { 95 config = { 96 assertions = [ { assertion = hi; } ]; 97 }; 98 options = { 99 itsProofYay = lib.mkOption { }; 100 }; 101 }; 102 specialArgs.hi = true; 103 }; 104 in 105 assert lib.isDerivation t; 106 assert t.nodes.machine ? itsProofYay; 107 t; 108 109 # Check that the wiring of nixosTest is correct. 110 # Correct operation of the NixOS test driver should be asserted elsewhere. 111 nixosTest-example = pkgs-with-overlay.testers.nixosTest ( 112 { lib, ... }: 113 { 114 name = "nixosTest-test"; 115 nodes.machine = 116 { pkgs, ... }: 117 { 118 system.nixos = dummyVersioning; 119 environment.systemPackages = [ 120 pkgs.proof-of-overlay-hello 121 pkgs.figlet 122 ]; 123 }; 124 testScript = '' 125 machine.succeed("hello | figlet >/dev/console") 126 ''; 127 } 128 ); 129 130 testBuildFailure = lib.recurseIntoAttrs rec { 131 happy = 132 runCommand "testBuildFailure-happy" 133 { 134 failed = testers.testBuildFailure ( 135 runCommand "fail" { } '' 136 echo ok-ish >$out 137 138 echo failing though 139 echo also stderr 1>&2 140 echo 'line\nwith-\bbackslashes' 141 printf "incomplete line - no newline" 142 143 exit 3 144 '' 145 ); 146 } 147 '' 148 grep -F 'ok-ish' $failed/result 149 150 grep -F 'failing though' $failed/testBuildFailure.log 151 grep -F 'also stderr' $failed/testBuildFailure.log 152 grep -F 'line\nwith-\bbackslashes' $failed/testBuildFailure.log 153 grep -F 'incomplete line - no newline' $failed/testBuildFailure.log 154 155 [[ 3 = $(cat $failed/testBuildFailure.exit) ]] 156 157 touch $out 158 ''; 159 160 happyStructuredAttrs = overrideStructuredAttrs true happy; 161 162 helloDoesNotFail = 163 runCommand "testBuildFailure-helloDoesNotFail" 164 { 165 failed = testers.testBuildFailure (testers.testBuildFailure hello); 166 167 # Add hello itself as a prerequisite, so we don't try to run this test if 168 # there's an actual failure in hello. 169 inherit hello; 170 } 171 '' 172 echo "Checking $failed/testBuildFailure.log" 173 grep -F 'testBuildFailure: The builder did not fail, but a failure was expected' $failed/testBuildFailure.log >/dev/null 174 [[ 1 = $(cat $failed/testBuildFailure.exit) ]] 175 touch $out 176 echo 'All good.' 177 ''; 178 179 multiOutput = 180 runCommand "testBuildFailure-multiOutput" 181 { 182 failed = testers.testBuildFailure ( 183 runCommand "fail" 184 { 185 # dev will be the default output 186 outputs = [ 187 "dev" 188 "doc" 189 "out" 190 ]; 191 } 192 '' 193 echo i am failing 194 exit 1 195 '' 196 ); 197 } 198 '' 199 grep -F 'i am failing' $failed/testBuildFailure.log >/dev/null 200 [[ 1 = $(cat $failed/testBuildFailure.exit) ]] 201 202 # Checking our note that dev is the default output 203 echo $failed/_ | grep -- '-dev/_' >/dev/null 204 echo 'All good.' 205 touch $out 206 ''; 207 208 multiOutputStructuredAttrs = overrideStructuredAttrs true multiOutput; 209 210 sideEffects = 211 runCommand "testBuildFailure-sideEffects" 212 { 213 failed = testers.testBuildFailure ( 214 stdenvNoCC.mkDerivation { 215 name = "fail-with-side-effects"; 216 src = emptyDirectory; 217 218 postHook = '' 219 echo touching side-effect... 220 # Assert that the side-effect doesn't exist yet... 221 # We're checking that this hook isn't run by expect-failure.sh 222 if [[ -e side-effect ]]; then 223 echo "side-effect already exists" 224 exit 1 225 fi 226 touch side-effect 227 ''; 228 229 buildPhase = '' 230 echo i am failing 231 exit 1 232 ''; 233 } 234 ); 235 } 236 '' 237 grep -F 'touching side-effect...' $failed/testBuildFailure.log >/dev/null 238 grep -F 'i am failing' $failed/testBuildFailure.log >/dev/null 239 [[ 1 = $(cat $failed/testBuildFailure.exit) ]] 240 [[ ! -e side-effect ]] 241 242 touch $out 243 ''; 244 245 sideEffectStructuredAttrs = overrideStructuredAttrs true sideEffects; 246 }; 247 248 testBuildFailure' = lib.recurseIntoAttrs ( 249 pkgs.callPackages ../testBuildFailurePrime/tests.nix { inherit overrideStructuredAttrs; } 250 ); 251 252 testEqualContents = lib.recurseIntoAttrs { 253 equalDir = testers.testEqualContents { 254 assertion = "The same directory contents at different paths are recognized as equal"; 255 expected = runCommand "expected" { } '' 256 mkdir -p -- "$out/c" 257 echo a >"$out/a" 258 echo b >"$out/b" 259 echo d >"$out/c/d" 260 echo e >"$out/e" 261 chmod a+x -- "$out/e" 262 ''; 263 actual = runCommand "actual" { } '' 264 mkdir -p -- "$out/c" 265 echo a >"$out/a" 266 echo b >"$out/b" 267 echo d >"$out/c/d" 268 echo e >"$out/e" 269 chmod a+x -- "$out/e" 270 ''; 271 }; 272 273 fileMissing = testers.testBuildFailure ( 274 testers.testEqualContents { 275 assertion = "Directories with different file list are not recognized as equal"; 276 expected = runCommand "expected" { } '' 277 mkdir -p -- "$out/c" 278 echo a >"$out/a" 279 echo b >"$out/b" 280 echo d >"$out/c/d" 281 ''; 282 actual = runCommand "actual" { } '' 283 mkdir -p -- "$out/c" 284 echo a >"$out/a" 285 echo d >"$out/c/d" 286 ''; 287 } 288 ); 289 290 equalExe = testers.testEqualContents { 291 assertion = "The same executable file contents at different paths are recognized as equal"; 292 expected = runCommand "expected" { } '' 293 echo test >"$out" 294 chmod a+x -- "$out" 295 ''; 296 actual = runCommand "actual" { } '' 297 echo test >"$out" 298 chmod a+x -- "$out" 299 ''; 300 }; 301 302 unequalExe = testers.testBuildFailure ( 303 testers.testEqualContents { 304 assertion = "Different file mode bits are not recognized as equal"; 305 expected = runCommand "expected" { } '' 306 touch -- "$out" 307 chmod a+x -- "$out" 308 ''; 309 actual = runCommand "actual" { } '' 310 touch -- "$out" 311 ''; 312 } 313 ); 314 315 unequalExeInDir = testers.testBuildFailure ( 316 testers.testEqualContents { 317 assertion = "Different file mode bits are not recognized as equal in directory"; 318 expected = runCommand "expected" { } '' 319 mkdir -p -- "$out/a" 320 echo b >"$out/b" 321 chmod a+x -- "$out/b" 322 ''; 323 actual = runCommand "actual" { } '' 324 mkdir -p -- "$out/a" 325 echo b >"$out/b" 326 ''; 327 } 328 ); 329 330 nonExistentPath = testers.testBuildFailure ( 331 testers.testEqualContents { 332 assertion = "Non existent paths are not recognized as equal"; 333 expected = "${emptyDirectory}/foo"; 334 actual = "${emptyDirectory}/bar"; 335 } 336 ); 337 338 emptyFileAndDir = testers.testBuildFailure ( 339 testers.testEqualContents { 340 assertion = "Empty file and directory are not recognized as equal"; 341 expected = emptyFile; 342 actual = emptyDirectory; 343 } 344 ); 345 346 fileDiff = 347 let 348 log = testers.testBuildFailure ( 349 testers.testEqualContents { 350 assertion = "Different files are not recognized as equal in subdirectories"; 351 expected = runCommand "expected" { } '' 352 mkdir -p -- "$out/b" 353 echo a >"$out/a" 354 echo EXPECTED >"$out/b/c" 355 ''; 356 actual = runCommand "actual" { } '' 357 mkdir -p "$out/b" 358 echo a >"$out/a" 359 echo ACTUAL >"$out/b/c" 360 ''; 361 } 362 ); 363 in 364 runCommand "testEqualContents-fileDiff" { inherit log; } '' 365 ( 366 set -x 367 # Note: use `&&` operator to chain commands because errexit (set -e) 368 # does not work in this context (even when set explicitly and with 369 # inherit_errexit), otherwise the subshell exits with the status of 370 # the last run command and ignores preceding failures. 371 grep -F -- 'Contents must be equal, but were not!' "$log/testBuildFailure.log" && 372 grep -E -- '\+\+\+ .*-expected/b/c' "$log/testBuildFailure.log" && 373 grep -E -- '--- .*-actual/b/c' "$log/testBuildFailure.log" && 374 grep -F -- -ACTUAL "$log/testBuildFailure.log" && 375 grep -F -- +EXPECTED "$log/testBuildFailure.log" 376 ) || { 377 echo "Test failed: could not find pattern in build log $log" 378 false 379 } 380 echo 'All good.' 381 touch -- "$out" 382 ''; 383 }; 384 385 testEqualArrayOrMap = pkgs.callPackages ../testEqualArrayOrMap/tests.nix { }; 386}