ba138712e4
This makes it possible for callers to control whether they can receive partially evaluated values from an evaluation or not. We're actually flipping the default behaviour to non-strict top-level evaluation, which means that callers have to set `strict = true` on the Evaluation to get the previous behaviour. Change-Id: Ic048e9ba09c88866d4c3177d5fa07db11c4eb20e Reviewed-on: https://cl.tvl.fyi/c/depot/+/8325 Autosubmit: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
84 lines
2.4 KiB
Rust
84 lines
2.4 KiB
Rust
//! Tests which use upstream nix as an oracle to test evaluation against
|
|
|
|
use std::{env, path::PathBuf, process::Command};
|
|
|
|
use pretty_assertions::assert_eq;
|
|
use tempdir::TempDir;
|
|
|
|
fn nix_binary_path() -> PathBuf {
|
|
env::var("NIX_INSTANTIATE_BINARY_PATH")
|
|
.unwrap_or_else(|_| "nix-instantiate".to_owned())
|
|
.into()
|
|
}
|
|
|
|
fn nix_eval(expr: &str) -> String {
|
|
let store_dir = TempDir::new("store-dir").unwrap();
|
|
|
|
let output = Command::new(nix_binary_path())
|
|
.args(["--eval", "--strict", "-E"])
|
|
.arg(format!("({expr})"))
|
|
.env(
|
|
"NIX_REMOTE",
|
|
format!("local?root={}", store_dir.path().display()),
|
|
)
|
|
.output()
|
|
.unwrap();
|
|
if !output.status.success() {
|
|
panic!(
|
|
"nix eval {expr} failed!\n stdout: {}\n stderr: {}",
|
|
String::from_utf8_lossy(&output.stdout),
|
|
String::from_utf8_lossy(&output.stderr)
|
|
)
|
|
}
|
|
|
|
String::from_utf8(output.stdout).unwrap()
|
|
}
|
|
|
|
/// Compare the evaluation of the given nix expression in nix (using the
|
|
/// `NIX_INSTANTIATE_BINARY_PATH` env var to resolve the `nix-instantiate` binary) and tvix, and
|
|
/// assert that the result is identical
|
|
#[track_caller]
|
|
fn compare_eval(expr: &str) {
|
|
let nix_result = nix_eval(expr);
|
|
let mut eval = tvix_eval::Evaluation::new(expr, None);
|
|
eval.strict = true;
|
|
eval.io_handle = Box::new(tvix_eval::StdIO);
|
|
|
|
let tvix_result = eval
|
|
.evaluate()
|
|
.value
|
|
.expect("tvix evaluation should succeed")
|
|
.to_string();
|
|
|
|
assert_eq!(nix_result.trim(), tvix_result);
|
|
}
|
|
|
|
/// Generate a suite of tests which call [`compare_eval`] on expressions, checking that nix and tvix
|
|
/// return identical results.
|
|
macro_rules! compare_eval_tests {
|
|
() => {};
|
|
($(#[$meta:meta])* $test_name: ident($expr: expr); $($rest:tt)*) => {
|
|
#[test]
|
|
$(#[$meta])*
|
|
fn $test_name() {
|
|
compare_eval($expr);
|
|
}
|
|
|
|
compare_eval_tests!($($rest)*);
|
|
}
|
|
}
|
|
|
|
compare_eval_tests! {
|
|
literal_int("1");
|
|
add_ints("1 + 1");
|
|
add_lists("[1 2] ++ [3 4]");
|
|
add_paths(r#"[
|
|
(./. + "/")
|
|
(./foo + "bar")
|
|
(let name = "bar"; in ./foo + name)
|
|
(let name = "bar"; in ./foo + "${name}")
|
|
(let name = "bar"; in ./foo + "/" + "${name}")
|
|
(let name = "bar"; in ./foo + "/${name}")
|
|
(./. + ./.)
|
|
]"#);
|
|
}
|