diff --git a/rust/nix-expr/src/eval_state.rs b/rust/nix-expr/src/eval_state.rs index 9e1a7c4..8990cba 100644 --- a/rust/nix-expr/src/eval_state.rs +++ b/rust/nix-expr/src/eval_state.rs @@ -403,12 +403,11 @@ pub fn test_init() { #[cfg(test)] mod tests { - use std::collections::HashMap; - - use ctor::ctor; - use std::io::Write as _; - use super::*; + use ctor::ctor; + use std::collections::HashMap; + use std::fs::read_dir; + use std::io::Write as _; #[ctor] fn setup() { @@ -871,7 +870,7 @@ mod tests { #[test] fn eval_state_apply() { gc_registering_current_thread(|| { - let store = Store::open("auto").unwrap(); + let store = Store::open("auto", HashMap::new()).unwrap(); let es = EvalState::new(store, []).unwrap(); // This is a function that takes two arguments. let f = es.eval_from_string("x: x + 1", "").unwrap(); @@ -911,7 +910,7 @@ mod tests { #[test] fn eval_state_apply_fail_body() { gc_registering_current_thread(|| { - let store = Store::open("auto").unwrap(); + let store = Store::open("auto", HashMap::new()).unwrap(); let es = EvalState::new(store, []).unwrap(); let f = es.eval_from_string("x: x + 1", "").unwrap(); let a = es.eval_from_string("true", "").unwrap(); @@ -956,7 +955,7 @@ mod tests { #[test] fn eval_state_apply_fail_args() { gc_registering_current_thread(|| { - let store = Store::open("auto").unwrap(); + let store = Store::open("auto", HashMap::new()).unwrap(); let es = EvalState::new(store, []).unwrap(); let f = es.eval_from_string("{x}: x + 1", "").unwrap(); let a = es.eval_from_string("{}", "").unwrap(); @@ -976,4 +975,79 @@ mod tests { }) .unwrap(); } + + #[test] + fn store_open_params() { + gc_registering_current_thread(|| { + let store = tempfile::tempdir().unwrap(); + let store_path = store.path().to_str().unwrap(); + let state = tempfile::tempdir().unwrap(); + let state_path = state.path().to_str().unwrap(); + let log = tempfile::tempdir().unwrap(); + let log_path = log.path().to_str().unwrap(); + + let es = EvalState::new( + Store::open( + "local", + HashMap::from([ + ("store", store_path), + ("state", state_path), + ("log", log_path), + ]) + .iter() + .map(|(a, b)| (*a, *b)), + ) + .unwrap(), + [], + ) + .unwrap(); + + let expr = r#" + '' + a derivation output: ${ + derivation { name = "letsbuild"; + system = builtins.currentSystem; + builder = "/bin/sh"; + args = [ "-c" "echo foo > $out" ]; + }} + a path: ${builtins.toFile "just-a-file" "ooh file good"} + a derivation path by itself: ${ + builtins.unsafeDiscardOutputDependency + (derivation { + name = "not-actually-built-yet"; + system = builtins.currentSystem; + builder = "/bin/sh"; + args = [ "-c" "echo foo > $out" ]; + }).drvPath} + '' + "#; + let derivations: [&[u8]; 3] = [ + b"letsbuild.drv", + b"just-a-file", + b"not-actually-built-yet.drv", + ]; + let _ = es.eval_from_string(expr, "").unwrap(); + + // assert that all three `derivations` are inside the store and the `state` directory is not empty either. + let store_contents: Vec<_> = read_dir(store.path()) + .unwrap() + .map(|dir_entry| dir_entry.unwrap().file_name()) + .collect(); + for derivation in derivations { + assert!(store_contents + .iter() + .find(|f| f.as_encoded_bytes().ends_with(derivation)) + .is_some()); + } + assert!(!empty(read_dir(state.path()).unwrap())); + + store.close().unwrap(); + state.close().unwrap(); + log.close().unwrap(); + }) + .unwrap(); + } + fn empty(foldable: impl IntoIterator) -> bool { + foldable.into_iter().all(|_| false) + } }