blob: 2c4f3c3f082e027cb1e17af46469478c977d2ca0 [file] [log] [blame] [edit]
//! This test is in its own file because the underlying libbpf_set_print function used by
//! set_print() and ObjectBuilder::debug() sets global state. The default is to run multiple tests
//! in different threads, so this test will always race with the others unless its isolated to a
//! different process.
//!
//! For the same reason, all tests here must run serially.
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use libbpf_rs::get_print;
use libbpf_rs::set_print;
use libbpf_rs::ObjectBuilder;
use libbpf_rs::PrintCallback;
use libbpf_rs::PrintLevel;
use serial_test::serial;
#[test]
#[serial]
fn test_set_print() {
static CORRECT_LEVEL: AtomicBool = AtomicBool::new(false);
static CORRECT_MESSAGE: AtomicBool = AtomicBool::new(false);
fn callback(level: PrintLevel, msg: String) {
if level == PrintLevel::Warn {
CORRECT_LEVEL.store(true, Ordering::Relaxed);
}
if msg.starts_with("libbpf: ") {
CORRECT_MESSAGE.store(true, Ordering::Relaxed);
}
}
set_print(Some((PrintLevel::Debug, callback)));
// expect_err requires that OpenObject implement Debug, which it does not.
let obj = ObjectBuilder::default().open_file("/dev/null");
assert!(obj.is_err(), "Successfully loaded /dev/null?");
let correct_level = CORRECT_LEVEL.load(Ordering::Relaxed);
let correct_message = CORRECT_MESSAGE.load(Ordering::Relaxed);
assert!(correct_level, "Did not capture a warning");
assert!(correct_message, "Did not capture the correct message");
}
#[test]
#[serial]
fn test_set_restore_print() {
fn callback1(_: PrintLevel, _: String) {
println!("one");
}
fn callback2(_: PrintLevel, _: String) {
println!("two");
}
set_print(Some((PrintLevel::Warn, callback1)));
let prev = get_print();
assert_eq!(prev, Some((PrintLevel::Warn, callback1 as PrintCallback)));
set_print(Some((PrintLevel::Debug, callback2)));
let prev = get_print();
assert_eq!(prev, Some((PrintLevel::Debug, callback2 as PrintCallback)));
}
#[test]
#[serial]
fn test_set_and_save_print() {
fn callback1(_: PrintLevel, _: String) {
println!("one");
}
fn callback2(_: PrintLevel, _: String) {
println!("two");
}
set_print(Some((PrintLevel::Warn, callback1)));
let prev = set_print(Some((PrintLevel::Debug, callback2)));
assert_eq!(prev, Some((PrintLevel::Warn, callback1 as PrintCallback)));
let prev = set_print(None);
assert_eq!(prev, Some((PrintLevel::Debug, callback2 as PrintCallback)));
}