nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
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}