diff options
Diffstat (limited to 'src/tests/batch.rs')
-rw-r--r-- | src/tests/batch.rs | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/tests/batch.rs b/src/tests/batch.rs new file mode 100644 index 0000000..12f373f --- /dev/null +++ b/src/tests/batch.rs @@ -0,0 +1,96 @@ +use std::mem::size_of; + +use libc::{AF_UNSPEC, NFNL_MSG_BATCH_BEGIN, NLM_F_REQUEST}; +use nix::libc::NFNL_MSG_BATCH_END; + +use crate::nlmsg::{pad_netlink_object_with_variable_size, NfNetlinkDeserializable}; +use crate::parser::{parse_nlmsg, NlMsg}; +use crate::sys::{nfgenmsg, nlmsghdr, NFNETLINK_V0, NFNL_SUBSYS_NFTABLES}; +use crate::{Batch, MsgType, Table}; + +use super::get_test_table; + +const HEADER_SIZE: u32 = + pad_netlink_object_with_variable_size(size_of::<nlmsghdr>() + size_of::<nfgenmsg>()) as u32; + +const DEFAULT_BATCH_BEGIN_HDR: nlmsghdr = nlmsghdr { + nlmsg_len: HEADER_SIZE, + nlmsg_flags: NLM_F_REQUEST as u16, + nlmsg_type: NFNL_MSG_BATCH_BEGIN as u16, + nlmsg_seq: 0, + nlmsg_pid: 0, +}; +const DEFAULT_BATCH_MSG: NlMsg = NlMsg::NfGenMsg( + nfgenmsg { + nfgen_family: AF_UNSPEC as u8, + version: NFNETLINK_V0 as u8, + res_id: NFNL_SUBSYS_NFTABLES as u16, + }, + &[], +); + +const DEFAULT_BATCH_END_HDR: nlmsghdr = nlmsghdr { + nlmsg_len: HEADER_SIZE, + nlmsg_flags: NLM_F_REQUEST as u16, + nlmsg_type: NFNL_MSG_BATCH_END as u16, + nlmsg_seq: 1, + nlmsg_pid: 0, +}; + +#[test] +fn batch_empty() { + let batch = Batch::new(); + let buf = batch.finalize(); + + let (hdr, msg) = parse_nlmsg(&buf).expect("Invalid nlmsg message"); + assert_eq!(hdr, DEFAULT_BATCH_BEGIN_HDR); + assert_eq!(msg, DEFAULT_BATCH_MSG); + + let remaining_data_offset = pad_netlink_object_with_variable_size(hdr.nlmsg_len as usize); + + let (hdr, msg) = parse_nlmsg(&buf[remaining_data_offset..]).expect("Invalid nlmsg message"); + assert_eq!(hdr, DEFAULT_BATCH_END_HDR); + assert_eq!(msg, DEFAULT_BATCH_MSG); +} + +#[test] +fn batch_with_objects() { + let mut original_tables = vec![]; + for i in 0..10 { + let mut table = get_test_table(); + table.set_userdata(vec![i as u8]); + original_tables.push(table); + } + + let mut batch = Batch::new(); + for i in 0..10 { + batch.add( + &original_tables[i], + if i % 2 == 0 { + MsgType::Add + } else { + MsgType::Del + }, + ); + } + let buf = batch.finalize(); + + let (hdr, msg) = parse_nlmsg(&buf).expect("Invalid nlmsg message"); + assert_eq!(hdr, DEFAULT_BATCH_BEGIN_HDR); + assert_eq!(msg, DEFAULT_BATCH_MSG); + let mut remaining_data = &buf[pad_netlink_object_with_variable_size(hdr.nlmsg_len as usize)..]; + + for i in 0..10 { + let (deserialized_table, rest) = + Table::deserialize(&remaining_data).expect("could not deserialize a table"); + remaining_data = rest; + + assert_eq!(deserialized_table, original_tables[i]); + } + + let (hdr, msg) = parse_nlmsg(&remaining_data).expect("Invalid nlmsg message"); + let mut end_hdr = DEFAULT_BATCH_END_HDR; + end_hdr.nlmsg_seq = 11; + assert_eq!(hdr, end_hdr); + assert_eq!(msg, DEFAULT_BATCH_MSG); +} |