tests.nixpkgs-check-by-name: Improve lib path handling in tests

nix-build failed because the tests assume to run in a CWD equal to the
project root, which is not the case in the derivation build.

This commit fixes it by not using hacky `..` references to paths,
and instead uses NIX_PATH for all implicit Nix testing path
dependencies.

Also the root of the `lib` path gets passed in from the `default.nix`
file, so all the relative path handling is done by Nix during evaluation
already, and in the Nix store when possible.
This commit is contained in:
Silvan Mosberger
2024-01-15 18:34:16 +01:00
parent be26d74840
commit aa7dd0b596
44 changed files with 82 additions and 54 deletions
@@ -9,6 +9,7 @@
}:
let
runtimeExprPath = ./src/eval.nix;
nixpkgsLibPath = ../../../lib;
package =
rustPlatform.buildRustPackage {
name = "nixpkgs-check-by-name";
@@ -30,6 +31,8 @@ let
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_STORE_DIR=$TEST_ROOT/store
export NIXPKGS_LIB_PATH=${nixpkgsLibPath}
# Ensure that even if tests run in parallel, we don't get an error
# We'd run into https://github.com/NixOS/nix/issues/2706 unless the store is initialised first
nix-store --init
@@ -44,6 +47,7 @@ let
'';
passthru.shell = mkShell {
env.NIX_CHECK_BY_NAME_EXPR_PATH = toString runtimeExprPath;
env.NIXPKGS_LIB_PATH = toString nixpkgsLibPath;
inputsFrom = [ package ];
};
};
+9 -3
View File
@@ -2,6 +2,8 @@ use crate::nixpkgs_problem::NixpkgsProblem;
use crate::ratchet;
use crate::structure;
use crate::validation::{self, Validation::Success};
use std::collections::HashMap;
use std::ffi::OsString;
use std::path::Path;
use anyhow::Context;
@@ -71,7 +73,7 @@ enum CallPackageVariant {
pub fn check_values(
nixpkgs_path: &Path,
package_names: Vec<String>,
eval_accessible_paths: &[&Path],
eval_nix_path: &HashMap<String, PathBuf>,
) -> validation::Result<ratchet::Nixpkgs> {
// Write the list of packages we need to check into a temporary JSON file.
// This can then get read by the Nix evaluation.
@@ -120,9 +122,13 @@ pub fn check_values(
.arg(nixpkgs_path);
// Also add extra paths that need to be accessible
for path in eval_accessible_paths {
for (name, path) in eval_nix_path {
command.arg("-I");
command.arg(path);
let mut name_value = OsString::new();
name_value.push(name);
name_value.push("=");
name_value.push(path);
command.arg(name_value);
}
command.args(["-I", &expr_path]);
command.arg(expr_path);
+28 -10
View File
@@ -12,6 +12,7 @@ use crate::validation::Validation::Success;
use anyhow::Context;
use clap::Parser;
use colored::Colorize;
use std::collections::HashMap;
use std::io;
use std::path::{Path, PathBuf};
use std::process::ExitCode;
@@ -44,7 +45,12 @@ pub struct Args {
fn main() -> ExitCode {
let args = Args::parse();
match process(&args.base, &args.nixpkgs, &[], &mut io::stderr()) {
match process(
&args.base,
&args.nixpkgs,
&HashMap::new(),
&mut io::stderr(),
) {
Ok(true) => {
eprintln!("{}", "Validated successfully".green());
ExitCode::SUCCESS
@@ -77,15 +83,15 @@ fn main() -> ExitCode {
pub fn process<W: io::Write>(
base_nixpkgs: &Path,
main_nixpkgs: &Path,
eval_accessible_paths: &[&Path],
eval_nix_path: &HashMap<String, PathBuf>,
error_writer: &mut W,
) -> anyhow::Result<bool> {
// Check the main Nixpkgs first
let main_result = check_nixpkgs(main_nixpkgs, eval_accessible_paths, error_writer)?;
let main_result = check_nixpkgs(main_nixpkgs, eval_nix_path, error_writer)?;
let check_result = main_result.result_map(|nixpkgs_version| {
// If the main Nixpkgs doesn't have any problems, run the ratchet checks against the base
// Nixpkgs
check_nixpkgs(base_nixpkgs, eval_accessible_paths, error_writer)?.result_map(
check_nixpkgs(base_nixpkgs, eval_nix_path, error_writer)?.result_map(
|base_nixpkgs_version| {
Ok(ratchet::Nixpkgs::compare(
base_nixpkgs_version,
@@ -113,7 +119,7 @@ pub fn process<W: io::Write>(
/// ratchet check against another result.
pub fn check_nixpkgs<W: io::Write>(
nixpkgs_path: &Path,
eval_accessible_paths: &[&Path],
eval_nix_path: &HashMap<String, PathBuf>,
error_writer: &mut W,
) -> validation::Result<ratchet::Nixpkgs> {
Ok({
@@ -134,7 +140,7 @@ pub fn check_nixpkgs<W: io::Write>(
} else {
check_structure(&nixpkgs_path)?.result_map(|package_names|
// Only if we could successfully parse the structure, we do the evaluation checks
eval::check_values(&nixpkgs_path, package_names, eval_accessible_paths))?
eval::check_values(&nixpkgs_path, package_names, eval_nix_path))?
}
})
}
@@ -144,8 +150,10 @@ mod tests {
use crate::process;
use crate::utils;
use anyhow::Context;
use std::collections::HashMap;
use std::fs;
use std::path::Path;
use std::path::PathBuf;
use tempfile::{tempdir_in, TempDir};
#[test]
@@ -226,9 +234,19 @@ mod tests {
}
fn test_nixpkgs(name: &str, path: &Path, expected_errors: &str) -> anyhow::Result<()> {
let mock_nixpkgs_path = Path::new("tests/mock-nixpkgs.nix");
let real_lib_path = Path::new("../../../lib");
let extra_nix_path = [mock_nixpkgs_path, real_lib_path];
let eval_nix_path = HashMap::from([
(
"test-nixpkgs".to_string(),
PathBuf::from("tests/mock-nixpkgs.nix"),
),
(
"test-nixpkgs/lib".to_string(),
PathBuf::from(
std::env::var("NIXPKGS_LIB_PATH")
.with_context(|| "Could not get environment variable NIXPKGS_LIB_PATH")?,
),
),
]);
let base_path = path.join("base");
let base_nixpkgs = if base_path.exists() {
@@ -240,7 +258,7 @@ mod tests {
// We don't want coloring to mess up the tests
let writer = temp_env::with_var("NO_COLOR", Some("1"), || -> anyhow::Result<_> {
let mut writer = vec![];
process(base_nixpkgs, &path, &extra_nix_path, &mut writer)
process(base_nixpkgs, &path, &eval_nix_path, &mut writer)
.with_context(|| format!("Failed test case {name}"))?;
Ok(writer)
})?;
@@ -1,4 +1,4 @@
args:
builtins.removeAttrs
(import ../mock-nixpkgs.nix { root = ./.; } args)
(import <test-nixpkgs> { root = ./.; } args)
[ "foo" ]
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -25,7 +25,7 @@ It returns a Nixpkgs-like function that can be auto-called and evaluates to an a
let
# Simplified versions of lib functions
lib = import ../../../../lib;
lib = import <test-nixpkgs/lib>;
# The base fixed-point function to populate the resulting attribute set
pkgsFun = self: {
@@ -1 +1 @@
import ../../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }
@@ -1 +1 @@
import ../mock-nixpkgs.nix { root = ./.; }
import <test-nixpkgs> { root = ./.; }