about summary refs log tree commit diff
path: root/tvix/glue/src/tests/tvix_tests/eval-okay-context-propagation.nix
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/glue/src/tests/tvix_tests/eval-okay-context-propagation.nix')
-rw-r--r--tvix/glue/src/tests/tvix_tests/eval-okay-context-propagation.nix119
1 files changed, 119 insertions, 0 deletions
diff --git a/tvix/glue/src/tests/tvix_tests/eval-okay-context-propagation.nix b/tvix/glue/src/tests/tvix_tests/eval-okay-context-propagation.nix
new file mode 100644
index 0000000000..41e7f207b9
--- /dev/null
+++ b/tvix/glue/src/tests/tvix_tests/eval-okay-context-propagation.nix
@@ -0,0 +1,119 @@
+# We test various propagation of contexts under other builtins here.
+let
+  drv = derivation {
+    name = "fail";
+    builder = "/bin/false";
+    system = "x86_64-linux";
+    outputs = [ "out" "foo" ];
+  };
+  other-drv = derivation {
+    name = "other-fail";
+    builder = "/bin/false";
+    system = "x86_64-linux";
+    outputs = [ "out" "bar" ];
+  };
+  a-path-drv = builtins.path {
+    name = "a-path-drv";
+    path = ./eval-okay-context-introspection.nix;
+  };
+  another-path-drv = builtins.filterSource (_: true) ./eval-okay-context-introspection.nix;
+
+  # `substr` propagates context, we truncate to an empty string and concatenate to the target
+  # to infect it with the context of `copied`.
+  appendContextFrom = copied: target: (builtins.substring 0 0 copied) + target;
+
+  path = "${./eval-okay-context-introspection.nix}";
+
+  combo-path = "${path}${drv.outPath}${drv.foo.outPath}${drv.drvPath}";
+
+  mergeContext = a: b:
+    builtins.getContext a // builtins.getContext b;
+
+  preserveContext = origin: result:
+    builtins.getContext "${result}" == builtins.getContext "${origin}";
+
+  preserveContexts = origins: result:
+    let union = builtins.foldl' (x: y: x // y) { } (builtins.map (d: builtins.getContext "${d}") origins);
+    in
+    union == builtins.getContext "${result}";
+in
+[
+  # `toFile` should produce context.
+  (builtins.hasContext "${(builtins.toFile "myself" "${./eval-okay-context-introspection.nix}")}")
+  # `derivation` should produce context.
+  (builtins.hasContext "${drv}")
+  # `builtins.path` / `builtins.filterSource` should produce context.
+  (builtins.hasContext "${a-path-drv}")
+  (builtins.hasContext "${another-path-drv}")
+  # Low-level test to ensure that interpolation is working as expected.
+  (builtins.length (builtins.attrNames (builtins.getContext "${drv}${other-drv}")) == 2)
+  (builtins.getContext "${drv}${other-drv}" == mergeContext drv other-drv)
+  # Those three next tests are extremely related.
+  # To test interpolation, we need concatenation to be working and vice versa.
+  # In addition, we need `builtins.substring` empty string propagation to attach context
+  # in absence of `builtins.appendContext`.
+  # The previous test should ensure that we don't test vacuous truths.
+  # Substring preserves contexts.
+  (preserveContext combo-path (builtins.substring 0 0 combo-path)) # <- FIXME: broken
+  # Interpolation preserves contexts.
+  (preserveContext "${drv}${other-drv}" (appendContextFrom drv other-drv))
+  # Concatenation preserves contexts.
+  (preserveContext "${drv}${other-drv}" (drv + other-drv))
+  # Special case when Nix does not assert that the length argument is non-negative
+  # when the starting index is ≥ than the string's length.
+  # FIXME: those three are broken too, NON DETERMINISTIC!!!
+  (preserveContext combo-path (builtins.substring 5 (-5) (builtins.substring 0 0 combo-path)))
+  (preserveContext combo-path (toString combo-path))
+  # No replacement should yield at least the same context.
+  (preserveContext combo-path (builtins.replaceStrings [ ] [ ] combo-path))
+  # This is an idempotent replacement, it should yield therefore to full preservation of the context.
+  (preserveContext "${drv}${drv}" (builtins.replaceStrings [ "${drv}" ] [ "${drv}" ] "${drv}"))
+  # There's no context here, so no context should appear from `drv`.
+  (preserveContext "abc" (builtins.replaceStrings [ "${drv}" ] [ "${drv}" ] "abc"))
+  # Context should appear by a successful replacement.
+  (preserveContext "${drv}" (builtins.replaceStrings [ "a" ] [ "${drv}" ] "a"))
+  # We test multiple successful replacements.
+  (preserveContexts [ drv other-drv ] (builtins.replaceStrings [ "a" "b" ] [ "${drv}" "${other-drv}" ] "ab"))
+  # We test *empty* string replacements.
+  (preserveContext "${drv}" (builtins.replaceStrings [ "" ] [ "${drv}" ] "abc"))
+  (preserveContext "${drv}" (builtins.replaceStrings [ "" ] [ "${drv}" ] ""))
+  # There should be no context in a parsed derivation name.
+  (!builtins.any builtins.hasContext (builtins.attrValues (builtins.parseDrvName "${drv.name}")))
+  # Nix does not propagate contexts for `match`.
+  (!builtins.any builtins.hasContext (builtins.match "(.*)" "${drv}"))
+  # `dirOf` preserves contexts of non-paths.
+  (preserveContext "${drv}" (builtins.dirOf "${drv}"))
+  (preserveContext "abc" (builtins.dirOf "abc"))
+  # `baseNameOf propagates context of argument
+  (preserveContext "${drv}" (builtins.baseNameOf drv))
+  (preserveContext "abc" (builtins.baseNameOf "abc"))
+  # `concatStringsSep` preserves contexts of both arguments.
+  (preserveContexts [ drv other-drv ] (builtins.concatStringsSep "${other-drv}" (map toString [ drv drv drv drv drv ])))
+  (preserveContext drv (builtins.concatStringsSep "|" (map toString [ drv drv drv drv drv ])))
+  (preserveContext other-drv (builtins.concatStringsSep "${other-drv}" [ "abc" "def" ]))
+  # `attrNames` will never ever produce context.
+  (preserveContext "abc" (toString (builtins.attrNames { a = { }; b = { }; c = { }; })))
+  # `toJSON` preserves context of its inputs.
+  (preserveContexts [ drv other-drv ] (builtins.toJSON {
+    a = [ drv ];
+    b = [ other-drv ];
+  }))
+  (preserveContexts [ drv other-drv ] (builtins.toJSON {
+    a.deep = [ drv ];
+    b = [ other-drv ];
+  }))
+  (preserveContexts [ drv other-drv ] (builtins.toJSON {
+    a = "${drv}";
+    b = [ other-drv ];
+  }))
+  (preserveContexts [ drv other-drv ] (builtins.toJSON {
+    a.deep = "${drv}";
+    b = [ other-drv ];
+  }))
+  (preserveContexts [ drv other-drv ] (builtins.toJSON {
+    a = "${drv} ${other-drv}";
+  }))
+  (preserveContexts [ drv other-drv ] (builtins.toJSON {
+    a.b.c.d.e.f = "${drv} ${other-drv}";
+  }))
+]