diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 535259e3..77765bc6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -57,10 +57,10 @@ jobs: - name: Build run: cargo build --profile=${{ matrix.profile }} --locked --verbose --workspace --exclude runqslower - name: Run tests - # Skip BTF & map tests which require sudo - run: cargo test --profile=${{ matrix.profile }} --locked --verbose --workspace --exclude runqslower -- --skip test_object --skip test_tc --skip test_map_info --include-ignored - - name: Run BTF tests - run: cd libbpf-rs && cargo test --profile=${{ matrix.profile }} --locked --verbose -- test_object test_tc + # Skip tests which require sudo + run: cargo test --profile=${{ matrix.profile }} --locked --verbose --workspace --exclude runqslower -- --skip test_sudo_ --include-ignored + - name: Run root tests + run: cd libbpf-rs && cargo test --profile=${{ matrix.profile }} --locked --verbose -- test_sudo_ build-minimum: name: Build using minimum versions of dependencies diff --git a/libbpf-rs/src/map.rs b/libbpf-rs/src/map.rs index 9d353172..4b20c1c2 100644 --- a/libbpf-rs/src/map.rs +++ b/libbpf-rs/src/map.rs @@ -987,48 +987,3 @@ impl MapInfo { MapFlags::from_bits_truncate(self.info.map_flags as u64) } } - -#[cfg(test)] -mod tests { - use super::*; - - use crate::Map; - use crate::MapFlags; - use crate::MapInfo; - use crate::MapType; - - /// Test whether `MapInfo` works properly - #[test] - pub fn test_map_info() { - let opts = libbpf_sys::bpf_map_create_opts { - sz: mem::size_of::() as libbpf_sys::size_t, - map_flags: libbpf_sys::BPF_ANY, - btf_fd: 0, - btf_key_type_id: 0, - btf_value_type_id: 0, - btf_vmlinux_value_type_id: 0, - inner_map_fd: 0, - map_extra: 0, - numa_node: 0, - map_ifindex: 0, - }; - - let map = Map::create(MapType::Hash, Some("simple_map"), 8, 64, 1024, &opts).unwrap(); - let map_info = MapInfo::new(map.fd()).unwrap(); - let name_received = map_info.name().unwrap(); - assert_eq!(name_received, "simple_map"); - assert_eq!(map_info.map_type(), MapType::Hash); - assert_eq!(map_info.flags() & MapFlags::ANY, MapFlags::ANY); - - let map_info = &map_info.info; - assert_eq!(map_info.key_size, 8); - assert_eq!(map_info.value_size, 64); - assert_eq!(map_info.max_entries, 1024); - assert_eq!(map_info.btf_id, 0); - assert_eq!(map_info.btf_key_type_id, 0); - assert_eq!(map_info.btf_value_type_id, 0); - assert_eq!(map_info.btf_vmlinux_value_type_id, 0); - assert_eq!(map_info.map_extra, 0); - assert_eq!(map_info.ifindex, 0); - } -} diff --git a/libbpf-rs/tests/test.rs b/libbpf-rs/tests/test.rs index 56905384..e13d3ac0 100644 --- a/libbpf-rs/tests/test.rs +++ b/libbpf-rs/tests/test.rs @@ -3,6 +3,7 @@ use std::ffi::c_void; use std::fs; use std::hint; use std::io::Read; +use std::mem::size_of; use std::os::fd::AsRawFd; use std::path::Path; use std::path::PathBuf; @@ -23,6 +24,7 @@ use libbpf_rs::Iter; use libbpf_rs::Linker; use libbpf_rs::Map; use libbpf_rs::MapFlags; +use libbpf_rs::MapInfo; use libbpf_rs::MapType; use libbpf_rs::Object; use libbpf_rs::ObjectBuilder; @@ -102,7 +104,7 @@ where } #[test] -fn test_object_build_and_load() { +fn test_sudo_object_build_and_load() { bump_rlimit_mlock(); get_test_object("runqslower.bpf.o"); @@ -122,7 +124,7 @@ fn test_object_build_from_memory() { /// Check that loading an object from an empty file fails as expected. #[test] -fn test_object_load_invalid() { +fn test_sudo_object_load_invalid() { let empty_file = NamedTempFile::new().unwrap(); let _err = ObjectBuilder::default() .debug(true) @@ -141,7 +143,7 @@ fn test_object_name() { } #[test] -fn test_object_maps() { +fn test_sudo_object_maps() { bump_rlimit_mlock(); let obj = get_test_object("runqslower.bpf.o"); @@ -151,7 +153,7 @@ fn test_object_maps() { } #[test] -fn test_object_maps_iter() { +fn test_sudo_object_maps_iter() { bump_rlimit_mlock(); let obj = get_test_object("runqslower.bpf.o"); @@ -163,7 +165,7 @@ fn test_object_maps_iter() { } #[test] -fn test_object_map_key_value_size() { +fn test_sudo_object_map_key_value_size() { bump_rlimit_mlock(); let mut obj = get_test_object("runqslower.bpf.o"); @@ -178,7 +180,7 @@ fn test_object_map_key_value_size() { } #[test] -fn test_object_map_delete_batch() { +fn test_sudo_object_map_delete_batch() { bump_rlimit_mlock(); let mut obj = get_test_object("runqslower.bpf.o"); @@ -226,8 +228,43 @@ fn test_object_map_delete_batch() { assert!(start.keys().collect::>().is_empty()) } +/// Test whether `MapInfo` works properly #[test] -fn test_object_percpu_lookup() { +pub fn test_sudo_map_info() { + let opts = libbpf_sys::bpf_map_create_opts { + sz: size_of::() as libbpf_sys::size_t, + map_flags: libbpf_sys::BPF_ANY, + btf_fd: 0, + btf_key_type_id: 0, + btf_value_type_id: 0, + btf_vmlinux_value_type_id: 0, + inner_map_fd: 0, + map_extra: 0, + numa_node: 0, + map_ifindex: 0, + }; + + let map = Map::create(MapType::Hash, Some("simple_map"), 8, 64, 1024, &opts).unwrap(); + let map_info = MapInfo::new(map.fd()).unwrap(); + let name_received = map_info.name().unwrap(); + assert_eq!(name_received, "simple_map"); + assert_eq!(map_info.map_type(), MapType::Hash); + assert_eq!(map_info.flags() & MapFlags::ANY, MapFlags::ANY); + + let map_info = &map_info.info; + assert_eq!(map_info.key_size, 8); + assert_eq!(map_info.value_size, 64); + assert_eq!(map_info.max_entries, 1024); + assert_eq!(map_info.btf_id, 0); + assert_eq!(map_info.btf_key_type_id, 0); + assert_eq!(map_info.btf_value_type_id, 0); + assert_eq!(map_info.btf_vmlinux_value_type_id, 0); + assert_eq!(map_info.map_extra, 0); + assert_eq!(map_info.ifindex, 0); +} + +#[test] +fn test_sudo_object_percpu_lookup() { bump_rlimit_mlock(); let mut obj = get_test_object("percpu_map.bpf.o"); @@ -242,11 +279,11 @@ fn test_object_percpu_lookup() { res.len(), num_possible_cpus().expect("must be one value per cpu") ); - assert_eq!(res[0].len(), std::mem::size_of::()); + assert_eq!(res[0].len(), size_of::()); } #[test] -fn test_object_percpu_invalid_lookup_fn() { +fn test_sudo_object_percpu_invalid_lookup_fn() { bump_rlimit_mlock(); let mut obj = get_test_object("percpu_map.bpf.o"); @@ -256,7 +293,7 @@ fn test_object_percpu_invalid_lookup_fn() { } #[test] -fn test_object_percpu_update() { +fn test_sudo_object_percpu_update() { bump_rlimit_mlock(); let mut obj = get_test_object("percpu_map.bpf.o"); @@ -280,7 +317,7 @@ fn test_object_percpu_update() { } #[test] -fn test_object_percpu_invalid_update_fn() { +fn test_sudo_object_percpu_invalid_update_fn() { bump_rlimit_mlock(); let mut obj = get_test_object("percpu_map.bpf.o"); @@ -293,7 +330,7 @@ fn test_object_percpu_invalid_update_fn() { } #[test] -fn test_object_percpu_lookup_update() { +fn test_sudo_object_percpu_lookup_update() { bump_rlimit_mlock(); let mut obj = get_test_object("percpu_map.bpf.o"); @@ -321,7 +358,7 @@ fn test_object_percpu_lookup_update() { } #[test] -fn test_object_map_empty_lookup() { +fn test_sudo_object_map_empty_lookup() { bump_rlimit_mlock(); let obj = get_test_object("runqslower.bpf.o"); @@ -334,7 +371,7 @@ fn test_object_map_empty_lookup() { } #[test] -fn test_object_map_mutation() { +fn test_sudo_object_map_mutation() { bump_rlimit_mlock(); let mut obj = get_test_object("runqslower.bpf.o"); @@ -359,7 +396,7 @@ fn test_object_map_mutation() { } #[test] -fn test_object_map_lookup_flags() { +fn test_sudo_object_map_lookup_flags() { bump_rlimit_mlock(); let mut obj = get_test_object("runqslower.bpf.o"); @@ -374,7 +411,7 @@ fn test_object_map_lookup_flags() { } #[test] -fn test_object_map_key_iter() { +fn test_sudo_object_map_key_iter() { bump_rlimit_mlock(); let mut obj = get_test_object("runqslower.bpf.o"); @@ -406,7 +443,7 @@ fn test_object_map_key_iter() { } #[test] -fn test_object_map_key_iter_empty() { +fn test_sudo_object_map_key_iter_empty() { bump_rlimit_mlock(); let obj = get_test_object("runqslower.bpf.o"); @@ -420,7 +457,7 @@ fn test_object_map_key_iter_empty() { } #[test] -fn test_object_map_pin() { +fn test_sudo_object_map_pin() { bump_rlimit_mlock(); let mut obj = get_test_object("runqslower.bpf.o"); @@ -440,7 +477,7 @@ fn test_object_map_pin() { } #[test] -fn test_object_loading_pinned_map_from_path() { +fn test_sudo_object_loading_pinned_map_from_path() { bump_rlimit_mlock(); let mut obj = get_test_object("runqslower.bpf.o"); @@ -461,7 +498,7 @@ fn test_object_loading_pinned_map_from_path() { } #[test] -fn test_object_loading_loaded_map_from_id() { +fn test_sudo_object_loading_loaded_map_from_id() { bump_rlimit_mlock(); let mut obj = get_test_object("runqslower.bpf.o"); @@ -479,7 +516,7 @@ fn test_object_loading_loaded_map_from_id() { } #[test] -fn test_object_programs() { +fn test_sudo_object_programs() { bump_rlimit_mlock(); let obj = get_test_object("runqslower.bpf.o"); @@ -493,7 +530,7 @@ fn test_object_programs() { } #[test] -fn test_object_programs_iter_mut() { +fn test_sudo_object_programs_iter_mut() { bump_rlimit_mlock(); let obj = get_test_object("runqslower.bpf.o"); @@ -501,7 +538,7 @@ fn test_object_programs_iter_mut() { } #[test] -fn test_object_program_pin() { +fn test_sudo_object_program_pin() { bump_rlimit_mlock(); let mut obj = get_test_object("runqslower.bpf.o"); @@ -530,7 +567,7 @@ fn test_object_program_pin() { } #[test] -fn test_object_link_pin() { +fn test_sudo_object_link_pin() { bump_rlimit_mlock(); let mut obj = get_test_object("runqslower.bpf.o"); @@ -560,7 +597,7 @@ fn test_object_link_pin() { } #[test] -fn test_object_reuse_pined_map() { +fn test_sudo_object_reuse_pined_map() { bump_rlimit_mlock(); let path = "/sys/fs/bpf/mymap_test_object_reuse_pined_map"; @@ -610,7 +647,7 @@ fn test_object_reuse_pined_map() { } #[test] -fn test_object_ringbuf() { +fn test_sudo_object_ringbuf() { bump_rlimit_mlock(); let mut obj = get_test_object("ringbuf.bpf.o"); @@ -694,7 +731,7 @@ fn test_object_ringbuf() { } #[test] -fn test_object_ringbuf_closure() { +fn test_sudo_object_ringbuf_closure() { bump_rlimit_mlock(); let mut obj = get_test_object("ringbuf.bpf.o"); @@ -760,7 +797,7 @@ fn test_object_ringbuf_closure() { } #[test] -fn test_object_task_iter() { +fn test_sudo_object_task_iter() { bump_rlimit_mlock(); let mut obj = get_test_object("taskiter.bpf.o"); @@ -783,7 +820,7 @@ fn test_object_task_iter() { .expect("Failed to read from iterator"); assert!(bytes_read > 0); - assert_eq!(bytes_read % std::mem::size_of::(), 0); + assert_eq!(bytes_read % size_of::(), 0); let items: &[IndexPidPair] = plain::slice_from_bytes(buf.as_slice()).expect("Input slice cannot satisfy length"); @@ -795,12 +832,12 @@ fn test_object_task_iter() { } #[test] -fn test_object_map_iter() { +fn test_sudo_object_map_iter() { bump_rlimit_mlock(); // Create a map for iteration test. let opts = libbpf_sys::bpf_map_create_opts { - sz: std::mem::size_of::() as libbpf_sys::size_t, + sz: size_of::() as libbpf_sys::size_t, map_flags: libbpf_sys::BPF_F_NO_PREALLOC, ..Default::default() }; @@ -836,7 +873,7 @@ fn test_object_map_iter() { .expect("Failed to read from iterator"); assert!(bytes_read > 0); - assert_eq!(bytes_read % std::mem::size_of::(), 0); + assert_eq!(bytes_read % size_of::(), 0); // Convert buf to &[u32] let buf = plain::slice_from_bytes::(buf.as_slice()).expect("Input slice cannot satisfy length"); @@ -846,18 +883,18 @@ fn test_object_map_iter() { } #[test] -fn test_object_map_create_and_pin() { +fn test_sudo_object_map_create_and_pin() { bump_rlimit_mlock(); let opts = libbpf_sys::bpf_map_create_opts { - sz: std::mem::size_of::() as libbpf_sys::size_t, + sz: size_of::() as libbpf_sys::size_t, map_flags: libbpf_sys::BPF_F_NO_PREALLOC, ..Default::default() }; let mut map = Map::create( MapType::Hash, - Some("mymap_test_object_map_create_and_pin"), + Some("mymap_test_sudo_object_map_create_and_pin"), 4, 8, 8, @@ -865,7 +902,7 @@ fn test_object_map_create_and_pin() { ) .expect("failed to create map"); - assert_eq!(map.name(), "mymap_test_object_map_create_and_pin"); + assert_eq!(map.name(), "mymap_test_sudo_object_map_create_and_pin"); let key = vec![1, 2, 3, 4]; let val = vec![1, 2, 3, 4, 5, 6, 7, 8]; @@ -877,7 +914,7 @@ fn test_object_map_create_and_pin() { .expect("failed to find value for key"); assert_eq!(val, res); - let path = "/sys/fs/bpf/mymap_test_object_map_create_and_pin"; + let path = "/sys/fs/bpf/mymap_test_sudo_object_map_create_and_pin"; // Unpinning a unpinned map should be an error assert!(map.unpin(path).is_err()); @@ -891,11 +928,11 @@ fn test_object_map_create_and_pin() { } #[test] -fn test_object_map_create_without_name() { +fn test_sudo_object_map_create_without_name() { bump_rlimit_mlock(); let opts = libbpf_sys::bpf_map_create_opts { - sz: std::mem::size_of::() as libbpf_sys::size_t, + sz: size_of::() as libbpf_sys::size_t, map_flags: libbpf_sys::BPF_F_NO_PREALLOC, btf_fd: 0, btf_key_type_id: 0, @@ -924,7 +961,7 @@ fn test_object_map_create_without_name() { } #[test] -fn test_object_usdt() { +fn test_sudo_object_usdt() { bump_rlimit_mlock(); let mut obj = get_test_object("usdt.bpf.o"); @@ -953,7 +990,7 @@ fn test_object_usdt() { } #[test] -fn test_object_usdt_cookie() { +fn test_sudo_object_usdt_cookie() { bump_rlimit_mlock(); let cookie_val = 1337u16; @@ -987,7 +1024,7 @@ fn test_object_usdt_cookie() { } #[test] -fn test_object_map_probes() { +fn test_sudo_map_probes() { bump_rlimit_mlock(); let supported = MapType::Array @@ -999,7 +1036,7 @@ fn test_object_map_probes() { } #[test] -fn test_object_program_probes() { +fn test_sudo_program_probes() { bump_rlimit_mlock(); let supported = ProgramType::SocketFilter @@ -1011,7 +1048,7 @@ fn test_object_program_probes() { } #[test] -fn test_object_program_helper_probes() { +fn test_sudo_program_helper_probes() { bump_rlimit_mlock(); let supported = ProgramType::SocketFilter @@ -1028,7 +1065,7 @@ fn test_object_program_helper_probes() { } #[test] -fn test_object_open_program_insns() { +fn test_sudo_object_open_program_insns() { bump_rlimit_mlock(); let open_obj = open_test_object("usdt.bpf.o"); @@ -1041,7 +1078,7 @@ fn test_object_open_program_insns() { } #[test] -fn test_object_program_insns() { +fn test_sudo_object_program_insns() { bump_rlimit_mlock(); let obj = get_test_object("usdt.bpf.o"); @@ -1053,7 +1090,7 @@ fn test_object_program_insns() { /// Check that we can attach a BPF program to a kernel tracepoint. #[test] -fn test_object_tracepoint() { +fn test_sudo_object_tracepoint() { bump_rlimit_mlock(); let mut obj = get_test_object("tracepoint.bpf.o"); @@ -1077,7 +1114,7 @@ fn test_object_tracepoint() { /// Check that we can attach a BPF program to a kernel tracepoint, providing /// additional options. #[test] -fn test_object_tracepoint_with_opts() { +fn test_sudo_object_tracepoint_with_opts() { bump_rlimit_mlock(); let cookie_val = 42u16; @@ -1112,7 +1149,7 @@ extern "C" fn uprobe_target() -> usize { /// Check that we can attach a BPF program to a uprobe. #[test] -fn test_object_uprobe_with_opts() { +fn test_sudo_object_uprobe_with_opts() { bump_rlimit_mlock(); let mut obj = get_test_object("uprobe.bpf.o"); @@ -1143,7 +1180,7 @@ fn test_object_uprobe_with_opts() { /// Check that we can attach a BPF program to a uprobe and access the cookie /// provided during attach. #[test] -fn test_object_uprobe_with_cookie() { +fn test_sudo_object_uprobe_with_cookie() { bump_rlimit_mlock(); let cookie_val = 5u16; @@ -1220,7 +1257,7 @@ fn buffer<'a>(perf: &'a libbpf_rs::PerfBuffer, buf_idx: usize) -> &'a [u8] { /// Check that we can see the raw ring buffer of the perf buffer and find a /// value we have sent. #[test] -fn test_object_perf_buffer_raw() { +fn test_sudo_object_perf_buffer_raw() { use memmem::Searcher; use memmem::TwoWaySearcher; @@ -1262,7 +1299,7 @@ fn test_object_perf_buffer_raw() { /// Check that we can get map pin status and map pin path #[test] -fn test_object_map_pinned_status() { +fn test_sudo_map_pinned_status() { bump_rlimit_mlock(); let obj = get_test_object("map_auto_pin.bpf.o"); @@ -1281,7 +1318,7 @@ fn test_object_map_pinned_status() { /// Check that we can get program fd by id and vice versa. #[test] -fn test_object_program_get_fd_and_id() { +fn test_sudo_program_get_fd_and_id() { bump_rlimit_mlock(); let obj = get_test_object("runqslower.bpf.o"); diff --git a/libbpf-rs/tests/test_tc.rs b/libbpf-rs/tests/test_tc.rs index 517b51cb..c4dad409 100644 --- a/libbpf-rs/tests/test_tc.rs +++ b/libbpf-rs/tests/test_tc.rs @@ -41,7 +41,7 @@ fn clear_clsact(fd: BorrowedFd) -> Result<()> { #[test] #[serial] -fn test_tc_basic_cycle() { +fn test_sudo_tc_basic_cycle() { bump_rlimit_mlock(); let obj = get_test_object("tc-unit.bpf.o"); @@ -83,7 +83,7 @@ fn test_tc_basic_cycle() { #[test] #[serial] -fn test_tc_attach_no_qdisc() { +fn test_sudo_tc_attach_no_qdisc() { bump_rlimit_mlock(); let obj = get_test_object("tc-unit.bpf.o"); @@ -108,7 +108,7 @@ fn test_tc_attach_no_qdisc() { #[test] #[serial] -fn test_tc_attach_basic() { +fn test_sudo_tc_attach_basic() { bump_rlimit_mlock(); let obj = get_test_object("tc-unit.bpf.o"); @@ -137,7 +137,7 @@ fn test_tc_attach_basic() { #[test] #[serial] -fn test_tc_attach_repeat() { +fn test_sudo_tc_attach_repeat() { bump_rlimit_mlock(); let obj = get_test_object("tc-unit.bpf.o"); @@ -177,7 +177,7 @@ fn test_tc_attach_repeat() { #[test] #[serial] -fn test_tc_attach_custom() { +fn test_sudo_tc_attach_custom() { bump_rlimit_mlock(); let obj = get_test_object("tc-unit.bpf.o"); let fd = obj.prog("handle_tc").unwrap().fd(); @@ -230,7 +230,7 @@ fn test_tc_attach_custom() { #[test] #[serial] -fn test_tc_detach_basic() { +fn test_sudo_tc_detach_basic() { bump_rlimit_mlock(); let obj = get_test_object("tc-unit.bpf.o"); let fd = obj.prog("handle_tc").unwrap().fd(); @@ -276,7 +276,7 @@ fn test_tc_detach_basic() { #[test] #[serial] -fn test_tc_query() { +fn test_sudo_tc_query() { bump_rlimit_mlock(); let obj = get_test_object("tc-unit.bpf.o"); @@ -348,7 +348,7 @@ fn test_tc_query() { #[test] #[serial] -fn test_tc_double_create() { +fn test_sudo_tc_double_create() { bump_rlimit_mlock(); let obj = get_test_object("tc-unit.bpf.o");