Merge pull request #639 from aya-rs/test-no-bpftool

Remove dependency on bpftool in integration tests
reviewable/pr640/r1
Tamir Duberstein 1 year ago committed by GitHub
commit e93e3c4a55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -999,12 +999,14 @@ impl Iterator for ProgramsIter {
io_error, io_error,
}) })
.and_then(|fd| { .and_then(|fd| {
bpf_prog_get_info_by_fd(fd) let info = bpf_prog_get_info_by_fd(fd)
.map_err(|io_error| ProgramError::SyscallError { .map_err(|io_error| ProgramError::SyscallError {
call: "bpf_prog_get_info_by_fd".to_owned(), call: "bpf_prog_get_info_by_fd".to_owned(),
io_error, io_error,
}) })
.map(ProgramInfo) .map(ProgramInfo);
unsafe { libc::close(fd) };
info
}), }),
) )
} }

@ -14,7 +14,6 @@ env_logger = "0.10"
futures-core = "0.3" futures-core = "0.3"
inventory = "0.3" inventory = "0.3"
integration-test-macros = { path = "../integration-test-macros" } integration-test-macros = { path = "../integration-test-macros" }
lazy_static = "1"
libc = { version = "0.2.105" } libc = { version = "0.2.105" }
log = "0.4" log = "0.4"
object = { version = "0.31", default-features = false, features = ["std", "read_core", "elf"] } object = { version = "0.31", default-features = false, features = ["std", "read_core", "elf"] }

@ -1,11 +1,11 @@
use std::{convert::TryInto, process::Command, thread, time}; use std::{convert::TryInto as _, thread, time};
use aya::{ use aya::{
include_bytes_aligned, include_bytes_aligned,
maps::Array, maps::Array,
programs::{ programs::{
links::{FdLink, PinnedLink}, links::{FdLink, PinnedLink},
KProbe, TracePoint, Xdp, XdpFlags, loaded_programs, KProbe, TracePoint, Xdp, XdpFlags,
}, },
Bpf, Bpf,
}; };
@ -58,20 +58,10 @@ fn multiple_btf_maps() {
assert_eq!(val_2, 42); assert_eq!(val_2, 42);
} }
fn is_loaded(name: &str) -> bool {
let output = Command::new("bpftool").args(["prog"]).output();
let output = match output {
Err(e) => panic!("Failed to run 'bpftool prog': {e}"),
Ok(out) => out,
};
let stdout = String::from_utf8(output.stdout).unwrap();
stdout.contains(name)
}
macro_rules! assert_loaded { macro_rules! assert_loaded {
($name:literal, $loaded:expr) => { ($name:literal, $loaded:expr) => {
for i in 0..(MAX_RETRIES + 1) { for i in 0..(MAX_RETRIES + 1) {
let state = is_loaded($name); let state = loaded_programs().any(|prog| prog.unwrap().name() == $name.as_bytes());
if state == $loaded { if state == $loaded {
break; break;
} }

@ -1,8 +1,7 @@
use anyhow::bail; use anyhow::bail;
use lazy_static::lazy_static;
use libc::{uname, utsname}; use libc::{uname, utsname};
use regex::Regex; use regex::Regex;
use std::{ffi::CStr, mem}; use std::{cell::OnceCell, ffi::CStr, mem};
pub mod bpf_probe_read; pub mod bpf_probe_read;
pub mod btf_relocations; pub mod btf_relocations;
@ -22,15 +21,15 @@ pub struct IntegrationTest {
} }
pub(crate) fn kernel_version() -> anyhow::Result<(u8, u8, u8)> { pub(crate) fn kernel_version() -> anyhow::Result<(u8, u8, u8)> {
lazy_static! { static mut RE: OnceCell<Regex> = OnceCell::new();
static ref RE: Regex = Regex::new(r"^([0-9]+)\.([0-9]+)\.([0-9]+)").unwrap(); let re =
} unsafe { &mut RE }.get_or_init(|| Regex::new(r"^([0-9]+)\.([0-9]+)\.([0-9]+)").unwrap());
let mut data: utsname = unsafe { mem::zeroed() }; let mut data: utsname = unsafe { mem::zeroed() };
let ret = unsafe { uname(&mut data) }; let ret = unsafe { uname(&mut data) };
assert!(ret >= 0, "libc::uname failed."); assert!(ret >= 0, "libc::uname failed.");
let release_cstr = unsafe { CStr::from_ptr(data.release.as_ptr()) }; let release_cstr = unsafe { CStr::from_ptr(data.release.as_ptr()) };
let release = release_cstr.to_string_lossy(); let release = release_cstr.to_string_lossy();
if let Some(caps) = RE.captures(&release) { if let Some(caps) = re.captures(&release) {
let major = caps.get(1).unwrap().as_str().parse().unwrap(); let major = caps.get(1).unwrap().as_str().parse().unwrap();
let minor = caps.get(2).unwrap().as_str().parse().unwrap(); let minor = caps.get(2).unwrap().as_str().parse().unwrap();
let patch = caps.get(3).unwrap().as_str().parse().unwrap(); let patch = caps.get(3).unwrap().as_str().parse().unwrap();

@ -193,7 +193,7 @@ EOF
exec_vm sudo dnf config-manager --set-enabled updates-testing exec_vm sudo dnf config-manager --set-enabled updates-testing
exec_vm sudo dnf config-manager --set-enabled updates-testing-modular exec_vm sudo dnf config-manager --set-enabled updates-testing-modular
echo "Installing dependencies" echo "Installing dependencies"
exec_vm sudo dnf install -qy bpftool llvm llvm-devel clang clang-devel zlib-devel exec_vm sudo dnf install -qy llvm llvm-devel clang clang-devel zlib-devel
exec_vm 'curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \ exec_vm 'curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \
-y --profile minimal --default-toolchain nightly --component rust-src --component clippy' -y --profile minimal --default-toolchain nightly --component rust-src --component clippy'
exec_vm 'echo source ~/.cargo/env >> ~/.bashrc' exec_vm 'echo source ~/.cargo/env >> ~/.bashrc'

@ -12,5 +12,4 @@ syn = "2"
quote = "1" quote = "1"
proc-macro2 = "1" proc-macro2 = "1"
indoc = "2.0" indoc = "2.0"
lazy_static = "1"
serde_json = "1" serde_json = "1"

@ -1,5 +1,8 @@
use std::{ use std::{
env, fs, borrow::Cow,
env,
ffi::{OsStr, OsString},
fs,
path::{Path, PathBuf}, path::{Path, PathBuf},
process::Command, process::Command,
}; };
@ -7,7 +10,7 @@ use std::{
use anyhow::{bail, Context}; use anyhow::{bail, Context};
use clap::Parser; use clap::Parser;
use crate::utils::WORKSPACE_ROOT; use crate::utils::workspace_root;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum Architecture { pub enum Architecture {
@ -52,7 +55,7 @@ pub fn build_ebpf(opts: BuildEbpfOptions) -> anyhow::Result<()> {
} }
fn build_rust_ebpf(opts: &BuildEbpfOptions) -> anyhow::Result<()> { fn build_rust_ebpf(opts: &BuildEbpfOptions) -> anyhow::Result<()> {
let mut dir = PathBuf::from(WORKSPACE_ROOT.to_string()); let mut dir = PathBuf::from(workspace_root());
dir.push("test/integration-ebpf"); dir.push("test/integration-ebpf");
let target = format!("--target={}", opts.target); let target = format!("--target={}", opts.target);
@ -77,9 +80,12 @@ fn build_rust_ebpf(opts: &BuildEbpfOptions) -> anyhow::Result<()> {
fn get_libbpf_headers<P: AsRef<Path>>(libbpf_dir: P, include_path: P) -> anyhow::Result<()> { fn get_libbpf_headers<P: AsRef<Path>>(libbpf_dir: P, include_path: P) -> anyhow::Result<()> {
let dir = include_path.as_ref(); let dir = include_path.as_ref();
fs::create_dir_all(dir)?; fs::create_dir_all(dir)?;
let mut includedir = OsString::new();
includedir.push("INCLUDEDIR=");
includedir.push(dir.as_os_str());
let status = Command::new("make") let status = Command::new("make")
.current_dir(libbpf_dir.as_ref().join("src")) .current_dir(libbpf_dir.as_ref().join("src"))
.arg(format!("INCLUDEDIR={}", dir.as_os_str().to_string_lossy())) .arg(includedir)
.arg("install_headers") .arg("install_headers")
.status() .status()
.expect("failed to build get libbpf headers"); .expect("failed to build get libbpf headers");
@ -88,10 +94,10 @@ fn get_libbpf_headers<P: AsRef<Path>>(libbpf_dir: P, include_path: P) -> anyhow:
} }
fn build_c_ebpf(opts: &BuildEbpfOptions) -> anyhow::Result<()> { fn build_c_ebpf(opts: &BuildEbpfOptions) -> anyhow::Result<()> {
let mut src = PathBuf::from(WORKSPACE_ROOT.to_string()); let mut src = PathBuf::from(workspace_root());
src.push("test/integration-ebpf/src/bpf"); src.push("test/integration-ebpf/src/bpf");
let mut out_path = PathBuf::from(WORKSPACE_ROOT.to_string()); let mut out_path = PathBuf::from(workspace_root());
out_path.push("target"); out_path.push("target");
out_path.push(opts.target.to_string()); out_path.push(opts.target.to_string());
out_path.push("release"); out_path.push("release");
@ -119,17 +125,19 @@ fn compile_with_clang<P: Clone + AsRef<Path>>(
out: P, out: P,
include_path: P, include_path: P,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let clang = match env::var("CLANG") { let clang: Cow<'_, _> = match env::var_os("CLANG") {
Ok(val) => val, Some(val) => val.into(),
Err(_) => String::from("/usr/bin/clang"), None => OsStr::new("/usr/bin/clang").into(),
}; };
let arch = match std::env::consts::ARCH { let arch = match env::consts::ARCH {
"x86_64" => "x86", "x86_64" => "x86",
"aarch64" => "arm64", "aarch64" => "arm64",
_ => std::env::consts::ARCH, arch => arch,
}; };
let mut cmd = Command::new(clang); let mut cmd = Command::new(clang);
cmd.arg(format!("-I{}", include_path.as_ref().to_string_lossy())) cmd.arg("-v")
.arg("-I")
.arg(include_path.as_ref())
.arg("-g") .arg("-g")
.arg("-O2") .arg("-O2")
.arg("-target") .arg("-target")

@ -36,8 +36,13 @@ fn build(opts: &Options) -> Result<(), anyhow::Error> {
.args(&args) .args(&args)
.status() .status()
.expect("failed to build userspace"); .expect("failed to build userspace");
assert!(status.success()); match status.code() {
Ok(()) Some(code) => match code {
0 => Ok(()),
code => Err(anyhow::anyhow!("exited with status code: {code}")),
},
None => Err(anyhow::anyhow!("process terminated by signal")),
}
} }
/// Build and run the project /// Build and run the project

@ -1,17 +1,15 @@
use lazy_static::lazy_static;
use serde_json::Value; use serde_json::Value;
use std::process::Command; use std::{cell::OnceCell, process::Command};
lazy_static! { pub fn workspace_root() -> &'static str {
pub static ref WORKSPACE_ROOT: String = workspace_root(); static mut WORKSPACE_ROOT: OnceCell<String> = OnceCell::new();
} unsafe { &mut WORKSPACE_ROOT }.get_or_init(|| {
let output = Command::new("cargo").arg("metadata").output().unwrap();
fn workspace_root() -> String { if !output.status.success() {
let output = Command::new("cargo").arg("metadata").output().unwrap(); panic!("unable to run cargo metadata")
if !output.status.success() { }
panic!("unable to run cargo metadata") let stdout = String::from_utf8(output.stdout).unwrap();
} let v: Value = serde_json::from_str(&stdout).unwrap();
let stdout = String::from_utf8(output.stdout).unwrap(); v["workspace_root"].as_str().unwrap().to_string()
let v: Value = serde_json::from_str(&stdout).unwrap(); })
v["workspace_root"].as_str().unwrap().to_string()
} }

Loading…
Cancel
Save