Skip to content

Commit da67258

Browse files
rizsottoclaude
andcommitted
integration tests: use install.sh instead of hand-rolled setup
Replace the manual file-copy logic in InstallEnvironment with a call to scripts/install.sh, so the install script is exercised on every test run. Add SOURCE_DIR env var to install.sh for pointing at non-release artifact directories (e.g. target/debug/). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8a728c6 commit da67258

File tree

4 files changed

+51
-46
lines changed

4 files changed

+51
-46
lines changed

integration-tests/build.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ fn main() {
3939
println!("cargo:rerun-if-changed=../bear/src");
4040
println!("cargo:rerun-if-changed=../intercept-preload/src");
4141

42+
// Locate install script and repo root for integration tests
43+
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
44+
let repo_root = std::path::Path::new(&manifest_dir).parent().unwrap();
45+
let install_script = repo_root.join("scripts").join("install.sh");
46+
println!("cargo:rerun-if-changed={}", install_script.display());
47+
println!("cargo:rustc-env=REPO_ROOT={}", repo_root.display());
48+
println!("cargo:rustc-env=INSTALL_SCRIPT_PATH={}", install_script.display());
49+
4250
// Set up paths for driver, wrapper and preload artifacts
4351
let (driver_path, wrapper_path, preload_path) = find_intercept_artifacts();
4452
println!("cargo:rustc-env=DRIVER_EXECUTABLE={}", DRIVER_NAME);

integration-tests/tests/fixtures/constants.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,12 @@ pub const MKDIR_PATH: &str = env!("MKDIR_PATH");
7272
#[cfg(has_executable_rm)]
7373
#[allow(dead_code)]
7474
pub const RM_PATH: &str = env!("RM_PATH");
75+
76+
#[allow(dead_code)]
77+
pub const INSTALL_SCRIPT_PATH: &str = env!("INSTALL_SCRIPT_PATH");
78+
79+
#[allow(dead_code)]
80+
pub const INTERCEPT_LIBDIR: &str = env!("INTERCEPT_LIBDIR");
81+
82+
#[allow(dead_code)]
83+
pub const REPO_ROOT: &str = env!("REPO_ROOT");

integration-tests/tests/fixtures/infrastructure.rs

Lines changed: 29 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -56,68 +56,52 @@ use std::process::Output;
5656
use tempfile;
5757

5858
/// Install environment for Bear
59+
///
60+
/// Uses `scripts/install.sh` to create a proper installation layout in a temp
61+
/// directory. This exercises the install script on every test run.
5962
pub struct InstallEnvironment {
6063
#[allow(dead_code)]
6164
install_dir: tempfile::TempDir,
62-
#[allow(dead_code)]
63-
bin_dir: tempfile::TempDir,
6465
bear: PathBuf,
6566
}
6667

6768
impl InstallEnvironment {
6869
pub fn new() -> Result<Self> {
6970
let install_dir = tempfile::TempDir::new().with_context(|| "install dir tempdir failed")?;
70-
let bin_dir = tempfile::TempDir::new().with_context(|| "bin dir tempdir failed")?;
71-
72-
let driver = Self::prepare_install_dir(install_dir.path())?;
73-
let bear = Self::prepare_entry_script(bin_dir.path(), &driver)?;
74-
75-
Ok(Self { install_dir, bin_dir, bear })
76-
}
77-
78-
fn prepare_install_dir(path: &Path) -> Result<PathBuf> {
79-
let bin_dir = path.join("bin");
80-
std::fs::create_dir(&bin_dir).with_context(|| format!("create dir={:?}", &bin_dir))?;
8171

82-
let driver = &bin_dir.join(DRIVER_EXECUTABLE);
83-
std::fs::copy(DRIVER_EXECUTABLE_PATH, driver)
84-
.with_context(|| format!("copy from={}, to={:?}", DRIVER_EXECUTABLE_PATH, &driver))?;
72+
Self::run_install_script(install_dir.path())?;
8573

86-
let wrapper = &bin_dir.join(WRAPPER_EXECUTABLE);
87-
std::fs::copy(WRAPPER_EXECUTABLE_PATH, wrapper)
88-
.with_context(|| format!("copy from={}, to={:?}", WRAPPER_EXECUTABLE_PATH, &wrapper))?;
74+
let bear = install_dir.path().join("bin").join("bear");
8975

90-
let lib_dir = path.join(env!("INTERCEPT_LIBDIR"));
91-
std::fs::create_dir(&lib_dir).with_context(|| format!("create dir={:?}", &lib_dir))?;
92-
93-
let library = &lib_dir.join(PRELOAD_LIBRARY);
94-
std::fs::copy(PRELOAD_LIBRARY_PATH, library)
95-
.with_context(|| format!("copy from={}, to={:?}", PRELOAD_LIBRARY_PATH, &library))?;
96-
97-
Ok(bin_dir.join(env!("DRIVER_EXECUTABLE")))
76+
Ok(Self { install_dir, bear })
9877
}
9978

100-
#[cfg(unix)]
101-
fn prepare_entry_script(path: &Path, driver: &Path) -> Result<PathBuf> {
102-
let file = path.join("bear");
103-
let script = format!("#!/usr/bin/sh\n{driver:?} $@\n");
104-
105-
std::fs::write(&file, script).with_context(|| format!("writing file={:?}", &file))?;
106-
107-
use std::os::unix::fs::PermissionsExt;
108-
std::fs::set_permissions(&file, std::fs::Permissions::from_mode(0o755)).unwrap();
109-
110-
Ok(file)
111-
}
79+
fn run_install_script(destdir: &Path) -> Result<()> {
80+
// Find the build artifact directory (same logic as build.rs)
81+
let source_dir = Path::new(DRIVER_EXECUTABLE_PATH)
82+
.parent()
83+
.with_context(|| "cannot determine artifact directory from DRIVER_EXECUTABLE_PATH")?;
11284

113-
#[cfg(not(unix))]
114-
fn prepare_entry_script(path: &Path, driver: &Path) -> Result<PathBuf> {
115-
let file = path.join("bear.bat");
116-
let script = format!("@echo off\r\n{driver:?} %*\r\n");
85+
let output = std::process::Command::new("sh")
86+
.arg(INSTALL_SCRIPT_PATH)
87+
.env("DESTDIR", destdir)
88+
.env("INTERCEPT_LIBDIR", INTERCEPT_LIBDIR)
89+
.env("SOURCE_DIR", source_dir)
90+
.output()
91+
.with_context(|| "failed to run install.sh")?;
11792

118-
std::fs::write(&file, script).with_context(|| "writing the script failed")?;
93+
if !output.status.success() {
94+
let stderr = String::from_utf8_lossy(&output.stderr);
95+
let stdout = String::from_utf8_lossy(&output.stdout);
96+
anyhow::bail!(
97+
"install.sh failed with exit code {:?}\nstdout: {}\nstderr: {}",
98+
output.status.code(),
99+
stdout,
100+
stderr
101+
);
102+
}
119103

120-
Ok(file)
104+
Ok(())
121105
}
122106

123107
pub fn path(&self) -> &Path {

scripts/install.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# Environment variables:
77
# DESTDIR — installation prefix (default: /usr/local if root, $HOME/.local otherwise)
88
# INTERCEPT_LIBDIR — library directory name (default: lib)
9+
# SOURCE_DIR — directory containing build artifacts (default: target/release)
910
#
1011
# Usage:
1112
# ./scripts/install.sh # install with defaults
@@ -48,8 +49,11 @@ refuse_root_destdir() {
4849

4950
# When run from the source repo, artifacts are in target/release/.
5051
# When run from a release archive, artifacts are next to the script.
52+
# Override with SOURCE_DIR to use a custom artifact directory (e.g. target/debug/).
5153
find_source_dir() {
52-
if [ -d "$REPO_ROOT/target/release" ]; then
54+
if [ -n "${SOURCE_DIR:-}" ]; then
55+
echo "$SOURCE_DIR"
56+
elif [ -d "$REPO_ROOT/target/release" ]; then
5357
echo "$REPO_ROOT/target/release"
5458
elif [ -f "$REPO_ROOT/bin/bear-driver" ] || [ -f "$REPO_ROOT/bin/bear-driver.exe" ]; then
5559
echo "$REPO_ROOT"

0 commit comments

Comments
 (0)