From b01bc3f49be4e1099601a8f682bc52b54eb1f960 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 30 Nov 2024 08:49:18 -0500 Subject: [PATCH] Use Result in integration-test's build script Something of an experiment. --- test/integration-test/Cargo.toml | 1 + test/integration-test/build.rs | 86 +++++++++++++++++++------------- 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/test/integration-test/Cargo.toml b/test/integration-test/Cargo.toml index 7caeb3a9..4cdeaa28 100644 --- a/test/integration-test/Cargo.toml +++ b/test/integration-test/Cargo.toml @@ -30,6 +30,7 @@ tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] } xdpilone = { workspace = true } [build-dependencies] +anyhow = { workspace = true } aya-build = { path = "../../aya-build" } # TODO(https://github.com/rust-lang/cargo/issues/12375): this should be an artifact dependency, but # it's not possible to tell cargo to use `-Z build-std` to build it. We cargo-in-cargo in the build diff --git a/test/integration-test/build.rs b/test/integration-test/build.rs index 6f71f8c2..d7ae6ff0 100644 --- a/test/integration-test/build.rs +++ b/test/integration-test/build.rs @@ -6,6 +6,7 @@ use std::{ process::{Child, Command, Output, Stdio}, }; +use anyhow::{anyhow, Context as _, Ok, Result}; use aya_build::cargo_metadata::{Metadata, MetadataCommand, Package, Target, TargetKind}; use xtask::{exec, AYA_BUILD_INTEGRATION_BPF, LIBBPF_DIR}; @@ -22,26 +23,42 @@ use xtask::{exec, AYA_BUILD_INTEGRATION_BPF, LIBBPF_DIR}; /// occur on metadata-only actions such as `cargo check` or `cargo clippy` of this crate. This means /// that naively attempting to `cargo test --no-run` this crate will produce binaries that fail at /// runtime because the stubs are inadequate for actually running the tests. -fn main() { - println!("cargo:rerun-if-env-changed={}", AYA_BUILD_INTEGRATION_BPF); +fn main() -> Result<()> { + println!("cargo:rerun-if-env-changed={AYA_BUILD_INTEGRATION_BPF}"); // TODO(https://github.com/rust-lang/cargo/issues/4001): generalize this and move it to // aya-build if we can determine that we're in a check build. - let build_integration_bpf = env::var(AYA_BUILD_INTEGRATION_BPF) - .as_deref() - .map(str::parse) - .map(Result::unwrap) + let build_integration_bpf = env::var_os(AYA_BUILD_INTEGRATION_BPF) + .map(|build_integration_bpf| { + let build_integration_bpf = std::str::from_utf8( + build_integration_bpf.as_encoded_bytes(), + ) + .with_context(|| format!("{AYA_BUILD_INTEGRATION_BPF}={build_integration_bpf:?}"))?; + let build_integration_bpf = build_integration_bpf + .parse() + .with_context(|| format!("{AYA_BUILD_INTEGRATION_BPF}={build_integration_bpf}"))?; + Ok(build_integration_bpf) + }) + .transpose()? .unwrap_or_default(); - let Metadata { packages, .. } = MetadataCommand::new().no_deps().exec().unwrap(); + let Metadata { + packages, + workspace_root, + .. + } = MetadataCommand::new() + .no_deps() + .exec() + .context("MetadataCommand::exec")?; let integration_ebpf_package = packages .into_iter() .find(|Package { name, .. }| name == "integration-ebpf") - .unwrap(); + .ok_or_else(|| anyhow!("integration-ebpf package not found"))?; - let manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap(); + let manifest_dir = + env::var_os("CARGO_MANIFEST_DIR").ok_or(anyhow!("CARGO_MANIFEST_DIR not set"))?; let manifest_dir = PathBuf::from(manifest_dir); - let out_dir = env::var_os("OUT_DIR").unwrap(); + let out_dir = env::var_os("OUT_DIR").ok_or(anyhow!("OUT_DIR not set"))?; let out_dir = PathBuf::from(out_dir); const C_BPF: &[(&str, bool)] = &[ @@ -55,22 +72,18 @@ fn main() { ]; if build_integration_bpf { - let endian = env::var_os("CARGO_CFG_TARGET_ENDIAN").unwrap(); + let endian = env::var_os("CARGO_CFG_TARGET_ENDIAN") + .ok_or(anyhow!("CARGO_CFG_TARGET_ENDIAN not set"))?; let target = if endian == "big" { "bpfeb" } else if endian == "little" { "bpfel" } else { - panic!("unsupported endian={:?}", endian) + return Err(anyhow!("unsupported endian={endian:?}")); }; - let libbpf_dir = manifest_dir - .parent() - .unwrap() - .parent() - .unwrap() - .join(LIBBPF_DIR); - println!("cargo:rerun-if-changed={}", libbpf_dir.to_str().unwrap()); + let libbpf_dir = workspace_root.join(LIBBPF_DIR); + println!("cargo:rerun-if-changed={libbpf_dir}"); let libbpf_headers_dir = out_dir.join("libbpf_headers"); @@ -84,15 +97,15 @@ fn main() { .arg(libbpf_dir.join("src")) .arg(includedir) .arg("install_headers"), - ) - .unwrap(); + )?; let bpf_dir = manifest_dir.join("bpf"); let mut target_arch = OsString::new(); target_arch.push("-D__TARGET_ARCH_"); - let arch = env::var_os("CARGO_CFG_TARGET_ARCH").unwrap(); + let arch = + env::var_os("CARGO_CFG_TARGET_ARCH").ok_or(anyhow!("CARGO_CFG_TARGET_ARCH not set"))?; if arch == "x86_64" { target_arch.push("x86"); } else if arch == "aarch64" { @@ -125,9 +138,12 @@ fn main() { for (src, build_btf) in C_BPF { let dst = out_dir.join(src).with_extension("o"); let src = bpf_dir.join(src); - println!("cargo:rerun-if-changed={}", src.to_str().unwrap()); + { + let src = src.to_str().with_context(|| format!("{src:?}"))?; + println!("cargo:rerun-if-changed={src}"); + } - exec(clang().arg(&src).arg("-o").arg(&dst)).unwrap(); + exec(clang().arg(&src).arg("-o").arg(&dst))?; if *build_btf { let mut cmd = clang(); @@ -137,10 +153,10 @@ fn main() { .args(["-o", "-"]) .stdout(Stdio::piped()) .spawn() - .unwrap_or_else(|err| panic!("failed to spawn {cmd:?}: {err}")); + .with_context(|| format!("failed to spawn {cmd:?}"))?; let Child { stdout, .. } = &mut child; - let stdout = stdout.take().unwrap(); + let stdout = stdout.take().expect("stdout"); let dst = dst.with_extension("target.o"); @@ -154,25 +170,26 @@ fn main() { .arg(output) .arg("-") .stdin(stdout), - ) - .unwrap(); + )?; let output = child .wait_with_output() - .unwrap_or_else(|err| panic!("failed to wait for {cmd:?}: {err}")); + .with_context(|| format!("failed to wait for {cmd:?}"))?; let Output { status, .. } = &output; - assert_eq!(status.code(), Some(0), "{cmd:?} failed: {output:?}"); + if !status.success() { + return Err(anyhow!("{cmd:?} failed: {status:?}")); + } } } - aya_build::build_ebpf([integration_ebpf_package]).unwrap(); + aya_build::build_ebpf([integration_ebpf_package])?; } else { for (src, build_btf) in C_BPF { let dst = out_dir.join(src).with_extension("o"); - fs::write(&dst, []).unwrap_or_else(|err| panic!("failed to create {dst:?}: {err}")); + fs::write(&dst, []).with_context(|| format!("failed to create {dst:?}"))?; if *build_btf { let dst = dst.with_extension("target.o"); - fs::write(&dst, []).unwrap_or_else(|err| panic!("failed to create {dst:?}: {err}")); + fs::write(&dst, []).with_context(|| format!("failed to create {dst:?}"))?; } } @@ -182,7 +199,8 @@ fn main() { continue; } let dst = out_dir.join(name); - fs::write(&dst, []).unwrap_or_else(|err| panic!("failed to create {dst:?}: {err}")); + fs::write(&dst, []).with_context(|| format!("failed to create {dst:?}"))?; } } + Ok(()) }