| //! 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))); |
| } |