mirror of
https://github.com/imjasonh/krust
synced 2026-07-11 07:59:54 +00:00
Fix flaky tests with temp directories and update documentation
This commit eliminates test flakiness by building to unique temporary directories and updates the README to reflect all changes in this branch. Code changes: - Modified RustBuilder to use tempfile::tempdir() for each build - Added BuildResult struct to keep temp directory alive during image build - Each build now gets its own isolated target directory - Removed clean_example_dir() and all cleanup logic - no longer needed - Tests can now run concurrently without interfering with each other Documentation updates: - Added "Isolated builds" and "Concurrent builds" to key features - Added comprehensive "Build Process" section explaining the temp directory approach - Updated multi-arch documentation to reflect default behavior (builds both platforms) - Added "Multi-Architecture Images" section explaining how multi-arch works - Documented that manifest list support is planned for future release Benefits: - No more "Built binary not found" errors - Tests run reliably every time - Concurrent test execution is now safe - Simpler test code without cleanup logic - Clear documentation of build isolation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
068ad65477
commit
d4b7b216df
5 changed files with 68 additions and 16 deletions
|
|
@ -1,6 +1,7 @@
|
|||
use anyhow::{Context, Result};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use tempfile::TempDir;
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -12,6 +13,11 @@ pub struct RustBuilder {
|
|||
cargo_args: Vec<String>,
|
||||
}
|
||||
|
||||
pub struct BuildResult {
|
||||
pub binary_path: PathBuf,
|
||||
_temp_dir: TempDir, // Keep temp dir alive until BuildResult is dropped
|
||||
}
|
||||
|
||||
impl RustBuilder {
|
||||
pub fn new(project_path: impl AsRef<Path>, target: &str) -> Self {
|
||||
Self {
|
||||
|
|
@ -26,14 +32,21 @@ impl RustBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn build(&self) -> Result<PathBuf> {
|
||||
pub fn build(&self) -> Result<BuildResult> {
|
||||
info!("Building Rust project at {:?}", self.project_path);
|
||||
|
||||
// Use a unique target directory to avoid conflicts between concurrent builds
|
||||
let temp_target_dir =
|
||||
tempfile::tempdir().context("Failed to create temporary directory")?;
|
||||
let target_dir = temp_target_dir.path();
|
||||
|
||||
let mut cmd = Command::new("cargo");
|
||||
cmd.arg("build")
|
||||
.arg("--release")
|
||||
.arg("--target")
|
||||
.arg(&self.target)
|
||||
.arg("--target-dir")
|
||||
.arg(target_dir)
|
||||
.current_dir(&self.project_path);
|
||||
|
||||
// Set RUSTFLAGS for static linking
|
||||
|
|
@ -116,6 +129,7 @@ impl RustBuilder {
|
|||
debug!("Running command: {:?}", cmd);
|
||||
debug!("RUSTFLAGS: {}", rustflags);
|
||||
|
||||
info!("Running cargo build for target: {}", self.target);
|
||||
let output = cmd.output().context("Failed to execute cargo build")?;
|
||||
|
||||
if !output.status.success() {
|
||||
|
|
@ -128,19 +142,30 @@ impl RustBuilder {
|
|||
}
|
||||
|
||||
let binary_name = self.get_binary_name()?;
|
||||
let binary_path = self
|
||||
.project_path
|
||||
.join("target")
|
||||
let binary_path = target_dir
|
||||
.join(&self.target)
|
||||
.join("release")
|
||||
.join(&binary_name);
|
||||
|
||||
// Sometimes cargo build completes but the binary isn't immediately visible
|
||||
// due to filesystem sync issues. Give it a moment.
|
||||
let mut retries = 0;
|
||||
while !binary_path.exists() && retries < 3 {
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
retries += 1;
|
||||
}
|
||||
|
||||
if !binary_path.exists() {
|
||||
anyhow::bail!("Built binary not found at {:?}", binary_path);
|
||||
}
|
||||
|
||||
info!("Successfully built binary at {:?}", binary_path);
|
||||
Ok(binary_path)
|
||||
|
||||
// Return the build result with the temp directory to keep it alive
|
||||
Ok(BuildResult {
|
||||
binary_path,
|
||||
_temp_dir: temp_target_dir,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_binary_name(&self) -> Result<String> {
|
||||
|
|
|
|||
|
|
@ -80,11 +80,14 @@ async fn main() -> Result<()> {
|
|||
let builder =
|
||||
RustBuilder::new(&project_path, &target).with_cargo_args(cargo_args.clone());
|
||||
|
||||
let binary_path = builder.build()?;
|
||||
let build_result = builder.build()?;
|
||||
|
||||
// Build container image for this platform
|
||||
let image_builder =
|
||||
ImageBuilder::new(binary_path, base_image.clone(), platform_str.clone());
|
||||
let image_builder = ImageBuilder::new(
|
||||
build_result.binary_path,
|
||||
base_image.clone(),
|
||||
platform_str.clone(),
|
||||
);
|
||||
|
||||
let (config_data, layer_data, manifest) = image_builder.build()?;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue