1 //! This test is in its own file because the underlying libbpf_set_print function used by
2 //! set_print() and ObjectBuilder::debug() sets global state. The default is to run multiple tests
3 //! in different threads, so this test will always race with the others unless its isolated to a
4 //! different process.
5 //!
6 //! For the same reason, all tests here must run serially.
7 
8 use std::sync::atomic::AtomicBool;
9 use std::sync::atomic::Ordering;
10 
11 use libbpf_rs::get_print;
12 use libbpf_rs::set_print;
13 use libbpf_rs::ObjectBuilder;
14 use libbpf_rs::PrintCallback;
15 use libbpf_rs::PrintLevel;
16 use serial_test::serial;
17 
18 #[test]
19 #[serial]
test_set_print()20 fn test_set_print() {
21     static CORRECT_LEVEL: AtomicBool = AtomicBool::new(false);
22     static CORRECT_MESSAGE: AtomicBool = AtomicBool::new(false);
23 
24     fn callback(level: PrintLevel, msg: String) {
25         if level == PrintLevel::Warn {
26             CORRECT_LEVEL.store(true, Ordering::Relaxed);
27         }
28 
29         if msg.starts_with("libbpf: ") {
30             CORRECT_MESSAGE.store(true, Ordering::Relaxed);
31         }
32     }
33 
34     set_print(Some((PrintLevel::Debug, callback)));
35     // expect_err requires that OpenObject implement Debug, which it does not.
36     let obj = ObjectBuilder::default().open_file("/dev/null");
37     assert!(obj.is_err(), "Successfully loaded /dev/null?");
38 
39     let correct_level = CORRECT_LEVEL.load(Ordering::Relaxed);
40     let correct_message = CORRECT_MESSAGE.load(Ordering::Relaxed);
41     assert!(correct_level, "Did not capture a warning");
42     assert!(correct_message, "Did not capture the correct message");
43 }
44 
45 #[test]
46 #[serial]
test_set_restore_print()47 fn test_set_restore_print() {
48     fn callback1(_: PrintLevel, _: String) {
49         println!("one");
50     }
51     fn callback2(_: PrintLevel, _: String) {
52         println!("two");
53     }
54 
55     set_print(Some((PrintLevel::Warn, callback1)));
56     let prev = get_print();
57     assert_eq!(prev, Some((PrintLevel::Warn, callback1 as PrintCallback)));
58 
59     set_print(Some((PrintLevel::Debug, callback2)));
60     let prev = get_print();
61     assert_eq!(prev, Some((PrintLevel::Debug, callback2 as PrintCallback)));
62 }
63 
64 #[test]
65 #[serial]
test_set_and_save_print()66 fn test_set_and_save_print() {
67     fn callback1(_: PrintLevel, _: String) {
68         println!("one");
69     }
70     fn callback2(_: PrintLevel, _: String) {
71         println!("two");
72     }
73 
74     set_print(Some((PrintLevel::Warn, callback1)));
75     let prev = set_print(Some((PrintLevel::Debug, callback2)));
76     assert_eq!(prev, Some((PrintLevel::Warn, callback1 as PrintCallback)));
77 
78     let prev = set_print(None);
79     assert_eq!(prev, Some((PrintLevel::Debug, callback2 as PrintCallback)));
80 }
81