about summary refs log tree commit diff
path: root/pkgs/profpatsch/testing/default.nix
blob: b2ae6239fab8013491c28df260a6d1e49380a58e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
{ runCommandLocal, lib
, runExecline, bin }:

let

  /* Realize drvDep, then return drvOut if that succeds.
   * This can be used to make drvOut depend on the
   * build success of drvDep without making drvDep a
   * dependency of drvOut
   * => drvOut is not rebuilt if drvDep changes
   */
  drvSeq = drvDep: drvOut: drvSeqL [drvDep] drvOut;

  /* TODO DOCS */
  drvSeqL = drvDeps: drvOut: let
  drvOutOutputs = drvOut.outputs or ["out"];
  in
    runCommandLocal drvOut.name {
      # we inherit all attributes in order to replicate
      # the original derivation as much as possible
      outputs = drvOutOutputs;
      passthru = drvOut.drvAttrs;
      # depend on drvDeps (by putting it in builder context)
      inherit drvDeps;
    }
    # the outputs of the original derivation are replicated
    # by creating a symlink to the old output path
    (lib.concatMapStrings (output: ''
      target=${lib.escapeShellArg drvOut.${output}}
      # if the target is already a symlink, follow it until it’s not;
      # this is done to prevent too many dereferences
      target=$(readlink -e "$target")
      # link to the output
      ln -s "$target" "${"$"}${output}"
    '') drvOutOutputs);

  /* Takes a derivation and an attribute set of
   * test names to tests.
   * Tests can be constructed by calling test
   * functions like `bashTest` or `execlineTest`.
   * They generally take scripts that
   * is not sucessful and succeed otherwise.
   */
  withTests = tests: drv:
    assert lib.isDerivation drv; # drv needs to be a derivation!
    let testDrvs = lib.mapAttrsToList
          (testName: testFun: testFun {
            drvName = "${drv.name}-test-${testName}";
          }) tests;
    in drvSeqL testDrvs drv;

  # /* Constructs a test from a bash script.
  #  * The test will fail if the bash script exits
  #  * with an exit code other than 0. */
  # bashTest = testScript: { drvName }:
  #   runCommand drvName {
  #     preferLocalBuild = true;
  #     allowSubstitutes = false;
  #   } ''
  #     ${testScript}
  #     touch "$out"
  #   '';

  # /* Constructs a test from an execline script.
  #  * The test will fail if the bash script exits
  #  * with an exit code other than 0. */
  # execlineTest = testScript: { drvName }:
  #   runExecline {
  #     name = drvName;
  #     execline = testScript;
  #     builderWrapper = runExecline {
  #       name = "touch-out";
  #       execline = ''
  #         importas -i out out
  #         ifte
  #           # if $@ succeeds, $out is touched
  #           { ${bin.s6-touch} $out }
  #           # otherwise we return the exit code
  #           { importas exit ?
  #             ${bin.s6-echo} $exit }
  #           # condition
  #           $@
  #       '';
  #     derivationArgs = {
  #       preferLocalBuild = true;
  #       allowSubstitutes = false;
  #     };
  #   };
  # };

in
  { inherit drvSeq drvSeqL withTests; }