Skip to content

Commit 2b0639b

Browse files
committed
Test the EXEPATH optimization of system_prefix()
This tests the `EXEPATH` strategy that `system_prefix()` attempts on Windows (before falling back to the `git --exec-path` strategy). Specifically, this tests the `system_prefix_from_exepath_var()` helper that was recently introduced to facilitate testing. Some of these new tests don't pass yet, because they test two scenarios that are not yet covered: - More than one of `mingw32`, `mingw64`, and `clangarm64` exist under the directory named by the value of `EXEPATH`. In this situation, the `EXEPATH` optimization should not be used. - `clangarm64` exists under the directory named by the value of `EXEPATH` (and neither `mingw32` nor `mingw64` exist under it). In this situation, the `clangarm64` subdirectory should be used. Although the `EXEPATH` optimization is only ever used on Windows, nothing in its test or implementation precludes testing elsewhere, so the tests build and run on Unix-like systems too.
1 parent 3b304fa commit 2b0639b

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

gix-path/src/env/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,6 @@ pub fn var(name: &str) -> Option<OsString> {
214214
std::env::var_os(name)
215215
}
216216
}
217+
218+
#[cfg(test)]
219+
mod tests;

gix-path/src/env/tests.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
mod system_prefix {
2+
use super::super::system_prefix_from_exepath_var;
3+
use gix_testtools::tempfile;
4+
use std::{ffi::OsString, path::PathBuf};
5+
6+
struct ExePath {
7+
_tempdir: tempfile::TempDir,
8+
path: PathBuf,
9+
}
10+
11+
impl ExePath {
12+
fn new() -> Self {
13+
let tempdir = tempfile::tempdir().expect("can create new temporary directory");
14+
15+
// This is just `tempdir.path()` unless it is relative, in which case it is resolved.
16+
let path = std::env::current_dir()
17+
.expect("can get current directory")
18+
.join(tempdir.path());
19+
20+
Self {
21+
_tempdir: tempdir,
22+
path,
23+
}
24+
}
25+
26+
fn create_subdir(&self, name: &str) -> PathBuf {
27+
let child = self.path.join(name);
28+
std::fs::create_dir(&child).expect("can create subdirectory");
29+
child
30+
}
31+
32+
fn create_separate_subdirs(&self, names: &[&str]) {
33+
for name in names {
34+
self.create_subdir(name);
35+
}
36+
}
37+
38+
fn create_separate_regular_files(&self, names: &[&str]) {
39+
for name in names {
40+
std::fs::File::create_new(self.path.join(name)).expect("can create new file");
41+
}
42+
}
43+
44+
fn var_os_func(&self, key: &str) -> Option<OsString> {
45+
match key {
46+
"EXEPATH" => Some(self.path.clone().into_os_string()),
47+
_ => None,
48+
}
49+
}
50+
}
51+
52+
#[test]
53+
fn exepath_unset() {
54+
let outcome = system_prefix_from_exepath_var(|_| None);
55+
assert_eq!(outcome, None);
56+
}
57+
58+
#[test]
59+
fn exepath_no_relevant_subdir() {
60+
for names in [[].as_slice(), ["ucrt64"].as_slice()] {
61+
let exepath = ExePath::new();
62+
exepath.create_separate_subdirs(names);
63+
let outcome = system_prefix_from_exepath_var(|key| exepath.var_os_func(key));
64+
assert_eq!(outcome, None);
65+
}
66+
}
67+
68+
#[test]
69+
fn exepath_unambiguous_subdir() {
70+
for name in ["mingw32", "mingw64", "clangarm64"] {
71+
let exepath = ExePath::new();
72+
let subdir = exepath.create_subdir(name);
73+
let outcome = system_prefix_from_exepath_var(|key| exepath.var_os_func(key));
74+
assert_eq!(outcome, Some(subdir));
75+
}
76+
}
77+
78+
#[test]
79+
fn exepath_unambiguous_subdir_beside_strange_files() {
80+
for (dirname, filename1, filename2) in [
81+
("mingw32", "mingw64", "clangarm64"),
82+
("mingw64", "mingw32", "clangarm64"),
83+
("clangarm64", "mingw32", "mingw64"),
84+
] {
85+
let exepath = ExePath::new();
86+
let subdir = exepath.create_subdir(dirname);
87+
exepath.create_separate_regular_files(&[filename1, filename2]);
88+
let outcome = system_prefix_from_exepath_var(|key| exepath.var_os_func(key));
89+
assert_eq!(outcome, Some(subdir));
90+
}
91+
}
92+
93+
#[test]
94+
fn exepath_ambiguous_subdir() {
95+
for names in [
96+
["mingw32", "mingw64"].as_slice(),
97+
["mingw32", "clangarm64"].as_slice(),
98+
["mingw64", "clangarm64"].as_slice(),
99+
["mingw32", "mingw64", "clangarm64"].as_slice(),
100+
] {
101+
let exepath = ExePath::new();
102+
exepath.create_separate_subdirs(names);
103+
let outcome = system_prefix_from_exepath_var(|key| exepath.var_os_func(key));
104+
assert_eq!(outcome, None);
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)