Merge pull request #254435 from tweag/fix-by-name-check-on-darwin

tests.nixpkgs-check-by-name: Fix for symlinked tempdirs

authored by Silvan Mosberger and committed by GitHub dc194ec7 e657d378

+49 -3
+4
pkgs/test/nixpkgs-check-by-name/default.nix
··· 25 export NIX_LOG_DIR=$TEST_ROOT/var/log/nix 26 export NIX_STATE_DIR=$TEST_ROOT/var/nix 27 export NIX_STORE_DIR=$TEST_ROOT/store 28 ''; 29 postCheck = '' 30 cargo fmt --check
··· 25 export NIX_LOG_DIR=$TEST_ROOT/var/log/nix 26 export NIX_STATE_DIR=$TEST_ROOT/var/nix 27 export NIX_STORE_DIR=$TEST_ROOT/store 28 + 29 + # cargo tests run in parallel by default, which would then run into 30 + # https://github.com/NixOS/nix/issues/2706 unless the store is initialised first 31 + nix-store --init 32 ''; 33 postCheck = '' 34 cargo fmt --check
+9 -3
pkgs/test/nixpkgs-check-by-name/src/eval.rs
··· 30 // Write the list of packages we need to check into a temporary JSON file. 31 // This can then get read by the Nix evaluation. 32 let attrs_file = NamedTempFile::new().context("Failed to create a temporary file")?; 33 serde_json::to_writer(&attrs_file, &nixpkgs.package_names).context(format!( 34 "Failed to serialise the package names to the temporary path {}", 35 - attrs_file.path().display() 36 ))?; 37 38 // With restrict-eval, only paths in NIX_PATH can be accessed, so we explicitly specify the ··· 57 // Pass the path to the attrs_file as an argument and add it to the NIX_PATH so it can be 58 // accessed in restrict-eval mode 59 .args(["--arg", "attrsPath"]) 60 - .arg(attrs_file.path()) 61 .arg("-I") 62 - .arg(attrs_file.path()) 63 // Same for the nixpkgs to test 64 .args(["--arg", "nixpkgsPath"]) 65 .arg(&nixpkgs.path)
··· 30 // Write the list of packages we need to check into a temporary JSON file. 31 // This can then get read by the Nix evaluation. 32 let attrs_file = NamedTempFile::new().context("Failed to create a temporary file")?; 33 + // We need to canonicalise this path because if it's a symlink (which can be the case on 34 + // Darwin), Nix would need to read both the symlink and the target path, therefore need 2 35 + // NIX_PATH entries for restrict-eval. But if we resolve the symlinks then only one predictable 36 + // entry is needed. 37 + let attrs_file_path = attrs_file.path().canonicalize()?; 38 + 39 serde_json::to_writer(&attrs_file, &nixpkgs.package_names).context(format!( 40 "Failed to serialise the package names to the temporary path {}", 41 + attrs_file_path.display() 42 ))?; 43 44 // With restrict-eval, only paths in NIX_PATH can be accessed, so we explicitly specify the ··· 63 // Pass the path to the attrs_file as an argument and add it to the NIX_PATH so it can be 64 // accessed in restrict-eval mode 65 .args(["--arg", "attrsPath"]) 66 + .arg(&attrs_file_path) 67 .arg("-I") 68 + .arg(&attrs_file_path) 69 // Same for the nixpkgs to test 70 .args(["--arg", "nixpkgsPath"]) 71 .arg(&nixpkgs.path)
+36
pkgs/test/nixpkgs-check-by-name/src/main.rs
··· 140 Ok(()) 141 } 142 143 fn test_nixpkgs(name: &str, path: &Path, expected_errors: &str) -> anyhow::Result<()> { 144 let extra_nix_path = Path::new("tests/mock-nixpkgs.nix"); 145
··· 140 Ok(()) 141 } 142 143 + /// Tests symlinked temporary directories. 144 + /// This is needed because on darwin, `/tmp` is a symlink to `/private/tmp`, and Nix's 145 + /// restrict-eval doesn't also allow access to the canonical path when you allow the 146 + /// non-canonical one. 147 + /// 148 + /// The error if we didn't do this would look like this: 149 + /// error: access to canonical path '/private/var/folders/[...]/.tmpFbcNO0' is forbidden in restricted mode 150 + #[test] 151 + fn test_symlinked_tmpdir() -> anyhow::Result<()> { 152 + // Create a directory with two entries: 153 + // - actual (dir) 154 + // - symlinked -> actual (symlink) 155 + let temp_root = tempdir()?; 156 + fs::create_dir(temp_root.path().join("actual"))?; 157 + std::os::unix::fs::symlink("actual", temp_root.path().join("symlinked"))?; 158 + let tmpdir = temp_root.path().join("symlinked"); 159 + 160 + // Then set TMPDIR to the symlinked directory 161 + // Make sure to persist the old value so we can undo this later 162 + let old_tmpdir = env::var("TMPDIR").ok(); 163 + env::set_var("TMPDIR", &tmpdir); 164 + 165 + // Then run a simple test with this symlinked temporary directory 166 + // This should be successful 167 + test_nixpkgs("symlinked_tmpdir", Path::new("tests/success"), "")?; 168 + 169 + // Undo the env variable change 170 + if let Some(old) = old_tmpdir { 171 + env::set_var("TMPDIR", old); 172 + } else { 173 + env::remove_var("TMPDIR"); 174 + } 175 + 176 + Ok(()) 177 + } 178 + 179 fn test_nixpkgs(name: &str, path: &Path, expected_errors: &str) -> anyhow::Result<()> { 180 let extra_nix_path = Path::new("tests/mock-nixpkgs.nix"); 181