From 2710d6a568cf64fc870d6af9264355ea591e7337 Mon Sep 17 00:00:00 2001 From: oxalica Date: Fri, 28 Apr 2023 17:05:32 +0800 Subject: [PATCH] Rework nix-interop tests Introduce a standalone test flake instead of inlining lock files or archiving the main repository. --- crates/nil/src/server.rs | 3 +- crates/nix-interop/src/flake_lock.rs | 74 +++---------------- crates/nix-interop/src/flake_output.rs | 21 ++---- crates/nix-interop/src/nixos_options.rs | 3 +- .../nix-interop/tests/test_flake/flake.lock | 45 +++++++++++ crates/nix-interop/tests/test_flake/flake.nix | 31 ++++++++ 6 files changed, 100 insertions(+), 77 deletions(-) create mode 100644 crates/nix-interop/tests/test_flake/flake.lock create mode 100644 crates/nix-interop/tests/test_flake/flake.nix diff --git a/crates/nil/src/server.rs b/crates/nil/src/server.rs index 7d4b7d4..bc259fc 100644 --- a/crates/nil/src/server.rs +++ b/crates/nil/src/server.rs @@ -357,7 +357,8 @@ impl Server { "nix flake archive".to_owned(), ) .await; - let ret = flake_lock::archive(&config.nix_binary) + let flake_url = FlakeUrl::new_path(&config.root_path); + let ret = flake_lock::archive(&config.nix_binary, &flake_url) .await .and_then(|()| { let missing = missing_paths().collect::>(); diff --git a/crates/nix-interop/src/flake_lock.rs b/crates/nix-interop/src/flake_lock.rs index 2e604b6..ccadd4d 100644 --- a/crates/nix-interop/src/flake_lock.rs +++ b/crates/nix-interop/src/flake_lock.rs @@ -14,6 +14,7 @@ use serde_repr::Deserialize_repr; use tokio::process::Command; use crate::eval::nix_eval_expr_json; +use crate::FlakeUrl; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ResolvedInput { @@ -188,7 +189,7 @@ struct LockedFlakeRef { // NB. The output of `nix flake archive` doesn't contain followed inputs. We should still use // call `resolve_flake_locked_inputs` for all resolved inputs. -pub async fn archive(nix_command: &Path) -> Result<()> { +pub async fn archive(nix_command: &Path, flake_url: &FlakeUrl) -> Result<()> { let output = Command::new(nix_command) .kill_on_drop(true) .args([ @@ -198,6 +199,7 @@ pub async fn archive(nix_command: &Path) -> Result<()> { "nix-command flakes", "--json", ]) + .arg(flake_url) .stdin(Stdio::null()) // Configures stdout/stderr automatically. .output() @@ -206,7 +208,8 @@ pub async fn archive(nix_command: &Path) -> Result<()> { ensure!( output.status.success(), - "`nix flake archive` failed with {}. Stderr:\n{}", + "`nix flake archive {}` failed with {}. Stderr:\n{}", + flake_url, output.status, String::from_utf8_lossy(&output.stderr), ); @@ -220,62 +223,8 @@ mod tests { #[tokio::test] #[ignore = "requires calling 'nix'"] async fn resolve_flake_lock_inputs() { - // { - // inputs.nixpkgs.url = "github:NixOS/nixpkgs/5ed481943351e9fd354aeb557679624224de38d5"; - // inputs.flake-utils = { - // url = "github:numtide/flake-utils/5aed5285a952e0b949eb3ba02c12fa4fcfef535f"; - // flake = false; - // }; - // outputs = { ... }: { }; - // } - let lock_src = br#" -{ - "nodes": { - "flake-utils": { - "flake": false, - "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1674211260, - "narHash": "sha256-xU6Rv9sgnwaWK7tgCPadV6HhI2Y/fl4lKxJoG2+m9qs=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "5ed481943351e9fd354aeb557679624224de38d5", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "5ed481943351e9fd354aeb557679624224de38d5", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - } - }, - "root": "root", - "version": 7 -} - "#; - let got = resolve_flake_locked_inputs("nix".as_ref(), lock_src) + let lock_src = std::fs::read("./tests/test_flake/flake.lock").unwrap(); + let got = resolve_flake_locked_inputs("nix".as_ref(), &lock_src) .await .unwrap(); let expect = HashMap::from_iter([ @@ -287,9 +236,9 @@ mod tests { }, ), ( - "flake-utils".to_owned(), + "nix".to_owned(), ResolvedInput { - store_path: "/nix/store/sk4ga2wy0b02k7pnzakwq4r3jdknda4g-source".to_owned(), + store_path: "/nix/store/5598lqiaw5qjgn661w74q2a6kivgiksa-source".to_owned(), is_flake: false, }, ), @@ -298,8 +247,9 @@ mod tests { } #[tokio::test] - #[ignore = "requires calling 'nix'"] + #[ignore = "requires calling 'nix' and network access"] async fn archive() { - super::archive("nix".as_ref()).await.unwrap(); + let flake = FlakeUrl::new_path("./tests/test_flake"); + super::archive("nix".as_ref(), &flake).await.unwrap(); } } diff --git a/crates/nix-interop/src/flake_output.rs b/crates/nix-interop/src/flake_output.rs index 7e5422c..e424a4b 100644 --- a/crates/nix-interop/src/flake_output.rs +++ b/crates/nix-interop/src/flake_output.rs @@ -119,28 +119,23 @@ mod tests { use super::*; #[tokio::test] - #[ignore = "requires calling 'nix'"] - async fn self_() { - let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); + #[ignore = "requires calling 'nix' and network access"] + async fn eval_outputs() { + let flake_url = FlakeUrl::new_path("./tests/test_flake"); let (tx, rx) = watch::channel(String::new()); - let output = eval_flake_output("nix".as_ref(), &FlakeUrl::new_path(dir), Some(tx), false) + let output = eval_flake_output("nix".as_ref(), &flake_url, Some(tx), false) .await .unwrap(); // Even if the system is omitted, the attrpath is still printed in progress. - assert_eq!(*rx.borrow(), "packages.x86_64-linux.nil"); + assert_eq!(*rx.borrow(), "packages.x86_64-linux.hello"); let system = crate::tests::get_nix_system().await; let leaf = (|| { - output.as_attrset()?["packages"].as_attrset()?[&system].as_attrset()?["nil"].as_leaf() + output.as_attrset()?["packages"].as_attrset()?[&system].as_attrset()?["hello"].as_leaf() })() .unwrap(); assert_eq!(leaf.type_, Type::Derivation); - assert!(leaf.name.as_ref().unwrap().starts_with("nil-unstable-")); - assert!(leaf - .description - .as_ref() - .unwrap() - .to_lowercase() - .contains("language server")); + assert_eq!(leaf.name.as_ref().unwrap(), "hello-1.2.3"); + assert_eq!(leaf.description.as_deref(), Some("A test derivation")); } } diff --git a/crates/nix-interop/src/nixos_options.rs b/crates/nix-interop/src/nixos_options.rs index 47b23b3..a375df5 100644 --- a/crates/nix-interop/src/nixos_options.rs +++ b/crates/nix-interop/src/nixos_options.rs @@ -10,6 +10,7 @@ use tokio::process::Command; pub async fn eval_all_options(nix_command: &Path, nixpkgs_path: &Path) -> Result { let nixpkgs_path = nixpkgs_path .to_str() + .filter(|path| path.starts_with('/')) .with_context(|| format!("Invalid path to nixpkgs: {}", nixpkgs_path.display()))?; let output = Command::new(nix_command) @@ -159,7 +160,7 @@ mod tests { use super::*; #[tokio::test] - #[ignore = "requires using 'nix' and 'nixpkgs'"] + #[ignore = "requires using 'nix' and ''"] async fn nixos_options() { let output = Command::new("nix") .kill_on_drop(true) diff --git a/crates/nix-interop/tests/test_flake/flake.lock b/crates/nix-interop/tests/test_flake/flake.lock new file mode 100644 index 0000000..40b03d4 --- /dev/null +++ b/crates/nix-interop/tests/test_flake/flake.lock @@ -0,0 +1,45 @@ +{ + "nodes": { + "nix": { + "flake": false, + "locked": { + "lastModified": 1677045134, + "narHash": "sha256-jUc2ccTR8f6MGY2pUKgujm+lxSPNGm/ZAP+toX+nMNc=", + "owner": "NixOS", + "repo": "nix", + "rev": "4acc684ef7b3117c6d6ac12837398a0008a53d85", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "2.13.3", + "repo": "nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1674211260, + "narHash": "sha256-xU6Rv9sgnwaWK7tgCPadV6HhI2Y/fl4lKxJoG2+m9qs=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5ed481943351e9fd354aeb557679624224de38d5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5ed481943351e9fd354aeb557679624224de38d5", + "type": "github" + } + }, + "root": { + "inputs": { + "nix": "nix", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/crates/nix-interop/tests/test_flake/flake.nix b/crates/nix-interop/tests/test_flake/flake.nix new file mode 100644 index 0000000..3092b7c --- /dev/null +++ b/crates/nix-interop/tests/test_flake/flake.nix @@ -0,0 +1,31 @@ +{ + # Just for tests. No need to be up-to-date. + inputs.nixpkgs.url = "github:NixOS/nixpkgs/5ed481943351e9fd354aeb557679624224de38d5"; + inputs.nix = { + flake = false; + url = "github:NixOS/nix/2.13.3"; + }; + + outputs = { nixpkgs, ... }: let + inherit (nixpkgs) lib; + forSystems = lib.genAttrs lib.systems.flakeExposed; + in { + packages = forSystems (system: { + hello = derivation rec { + pname = "hello"; + version = "1.2.3"; + name = "${pname}-${version}"; + + inherit system; + builder = "/bin/sh"; + args = ":"; + + meta = { + description = "A test derivation"; + homepage = "https://example.com"; + license = [ lib.licenses.mit /* OR */ lib.licenses.asl20 ]; + }; + }; + }); + }; +}