From: Sam Muhammed Date: Fri, 7 Jan 2022 17:27:06 +0000 (+0200) Subject: nfs4_records: add unittests for nom7 parsers X-Git-Tag: suricata-7.0.0-beta1~1071 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9bea850d53b3336de3868ce43e3416c53afe772c;p=thirdparty%2Fsuricata.git nfs4_records: add unittests for nom7 parsers Task #4866 --- diff --git a/rust/src/nfs/nfs4_records.rs b/rust/src/nfs/nfs4_records.rs index 01929215c4..d8950354e6 100644 --- a/rust/src/nfs/nfs4_records.rs +++ b/rust/src/nfs/nfs4_records.rs @@ -830,3 +830,462 @@ pub fn parse_nfs4_response_compound(i: &[u8]) -> IResult<&[u8], Nfs4ResponseComp let (i, commands) = count(nfs4_res_compound_command, ops_cnt as usize)(i)?; Ok((i, Nfs4ResponseCompoundRecord { status, commands })) } + +#[cfg(test)] +mod tests { + use crate::nfs::nfs4_records::*; + + #[test] + fn test_nfs4_request_compound() { + // Operations: SEQUENCE, PUTFH, CLOSE + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x00, /*Tag*/ + 0x00, 0x00, 0x00, 0x01, /*min_ver*/ + 0x00, 0x00, 0x00, 0x03, /*ops_cnt*/ + // SEQUENCE + 0x00, 0x00, 0x00, 0x35, /*op_code*/ + 0x00, 0x00, 0x02, 0xd2, 0xe0, 0x14, 0x82, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + // PUTFH + 0x00, 0x00, 0x00, 0x16, /*op_code*/ + 0x00, 0x00, 0x00, 0x20, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x72, 0x00, 0x00, 0x23, 0xa6, 0xc0, 0x12, + 0x00, 0xf2, 0xfa, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + // CLOSE + 0x00, 0x00, 0x00, 0x04, /*op_code*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x82, 0x14, 0xe0, 0x5b, 0x00, 0x88, 0xd9, + 0x04, 0x00, 0x00, 0x00, + ]; + + let sequence_buf: &[u8] = &buf[16..48]; + let putfh_buf: &[u8] = &buf[52..88]; + let close_buf: &[u8] = &buf[92..]; + + let (_, req_sequence) = nfs4_req_sequence(sequence_buf).unwrap(); + let (_, req_putfh) = nfs4_req_putfh(putfh_buf).unwrap(); + let (_, req_close) = nfs4_req_close(close_buf).unwrap(); + + let (_, compound_ops) = parse_nfs4_request_compound(buf).unwrap(); + assert_eq!(compound_ops.commands[0], req_sequence); + assert_eq!(compound_ops.commands[1], req_putfh); + assert_eq!(compound_ops.commands[2], req_close); + } + + + #[test] + fn test_nfs4_request_open() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x12, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, /*_seq_id*/ + 0x00, 0x00, 0x00, 0x02, /*_share_access*/ + 0x00, 0x00, 0x00, 0x00, /*_share_deny*/ + 0xe0, 0x14, 0x82, 0x00, 0x00, 0x00, 0x02, 0xd2, /*_client_id*/ + // OWNER + 0x00, 0x00, 0x00, 0x18, /*owner_len*/ + 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x69, 0x64, 0x3a, + 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x48, 0x0c, 0xae, 0x9b, 0x05, 0x08, + // OPEN + 0x00, 0x00, 0x00, 0x01, /*open_type: OPEN4_CREATE*/ + 0x00, 0x00, 0x00, 0x00, /*create_mode: UNCHECKED4*/ + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, /*attr_mask*/ + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xb4, + // CLAIM_TYPE + 0x00, 0x00, 0x00, 0x00, /*_claim_type: CLAIM_NULL*/ + 0x00, 0x00, 0x00, 0x04, 0x66, 0x69, 0x6c, 0x65, /*filename*/ + ]; + + let (_, attr_buf) = nfs4_parse_attrbits(&buf[60..88]).unwrap(); + let (_, filename_buf) = nfs4_parse_nfsstring(&buf[92..]).unwrap(); + + let (_, request) = nfs4_req_open(&buf[4..]).unwrap(); + match request { + Nfs4RequestContent::Open(req_open) => { + assert_eq!(req_open.open_type, 1); + assert_eq!(req_open.open_data, Some(Nfs4OpenRequestContent::Unchecked4(attr_buf))); + assert_eq!(req_open.filename, filename_buf); + } + _ => { panic!("Failure, {:?}", request); } + } + } + + #[test] + fn test_nfs4_request_write() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x26, /*op_code*/ + 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x14, 0xe0, /*stateid*/ + 0x5b, 0x00, 0x89, 0xd9, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*offset*/ + 0x00, 0x00, 0x00, 0x02, /*stable*/ + 0x00, 0x00, 0x00, 0x05, /*write_len*/ + 0x74, 0x65, 0x73, 0x74, 0x0a, /*data*/ + 0x00, 0x00, 0x00, /*_padding*/ + ]; + + let (_, stateid_buf) = nfs4_parse_stateid(&buf[4..20]).unwrap(); + + let (_, request) = nfs4_req_write(&buf[4..]).unwrap(); + match request { + Nfs4RequestContent::Write(req_write) => { + assert_eq!(req_write.stateid, stateid_buf); + assert_eq!(req_write.offset, 0); + assert_eq!(req_write.stable, 2); + assert_eq!(req_write.write_len, 5); + assert_eq!(req_write.data, "test\n".as_bytes()); + } + _ => { panic!("Failure, {:?}", request); } + } + } + + #[test] + fn test_nfs4_request_exchangeid() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x2a, /*opcode*/ + // eia_clientowner + 0x5c, 0x8a, 0x9b, 0xfe, 0x0c, 0x09, 0x5e, 0x92, /*_verifier*/ + 0x00, 0x00, 0x00, 0x17, 0x4c, 0x69, 0x6e, 0x75, /*eia_clientstring*/ + 0x78, 0x20, 0x4e, 0x46, 0x53, 0x76, 0x34, 0x2e, + 0x31, 0x20, 0x6e, 0x65, 0x74, 0x61, 0x70, 0x70, + 0x2d, 0x32, 0x36, 0x00, + 0x00, 0x00, 0x01, 0x01, /*_eia_clientflags*/ + 0x00, 0x00, 0x00, 0x00, /*_eia_state_protect*/ + // _eia_client_impl_id + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x72, 0x6e, /*nii_domain*/ + 0x65, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x45, 0x4c, 0x69, 0x6e, 0x75, /*nii_name*/ + 0x78, 0x20, 0x33, 0x2e, 0x31, 0x30, 0x2e, 0x30, + 0x2d, 0x39, 0x35, 0x37, 0x2e, 0x65, 0x6c, 0x37, + 0x2e, 0x78, 0x38, 0x36, 0x5f, 0x36, 0x34, 0x20, + 0x23, 0x31, 0x20, 0x53, 0x4d, 0x50, 0x20, 0x54, + 0x68, 0x75, 0x20, 0x4f, 0x63, 0x74, 0x20, 0x34, + 0x20, 0x32, 0x30, 0x3a, 0x34, 0x38, 0x3a, 0x35, + 0x31, 0x20, 0x55, 0x54, 0x43, 0x20, 0x32, 0x30, + 0x31, 0x38, 0x20, 0x78, 0x38, 0x36, 0x5f, 0x36, + 0x34, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*_nii_data_sec*/ + 0x00, 0x00, 0x00, 0x00, /*_nii_data_nsec*/ + ]; + + /*( .Linux NFSv4.1 netapp-26 )*/ + let (_, client_string_buf) = nfs4_parse_nfsstring(&buf[12..40]).unwrap(); + /*(kernel.org\0\0\0\n)*/ + let (_, nii_domain_buf) = nfs4_parse_nfsstring(&buf[52..68]).unwrap(); + /* ( ELinux 3.10.0-957.el7.x86_64 #1 SMP Thu Oct 4 20:48:51 UTC 2018 x86_64 ) */ + let (_, nii_name_buf) = nfs4_parse_nfsstring(&buf[68..144]).unwrap(); + + let (_, request) = nfs4_req_exchangeid(&buf[4..]).unwrap(); + match request { + Nfs4RequestContent::ExchangeId(req_exchangeid) => { + assert_eq!(req_exchangeid.client_string, client_string_buf); + assert_eq!(req_exchangeid.nii_domain, nii_domain_buf); + assert_eq!(req_exchangeid.nii_name, nii_name_buf); + } + _ => { panic!("Failure, {:?}", request); } + } + } + + #[test] + fn test_nfs4_request_close() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x04, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, /*_seq_id*/ + 0x00, 0x00, 0x00, 0x01, 0x00, 0x82, 0x14, 0xe0, /*stateid*/ + 0x5b, 0x00, 0x88, 0xd9, 0x04, 0x00, 0x00, 0x00, + ]; + + let (_, stateid_buf) = nfs4_parse_stateid(&buf[8..]).unwrap(); + + let (_, request) = nfs4_req_close(&buf[4..]).unwrap(); + match request { + Nfs4RequestContent::Close(req_stateid) => { + assert_eq!(req_stateid, stateid_buf); + } + _ => { panic!("Failure, {:?}", request); } + } + } + + #[test] + fn test_nfs4_request_sequenece() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x35, /*opcode*/ + 0x00, 0x00, 0x02, 0xd2, 0xe0, 0x14, 0x82, 0x00, /*ssn_id*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, + 0x00, 0x00, 0x00, 0x18, /*_seq_id*/ + 0x00, 0x00, 0x00, 0x00, /*_slot_id*/ + 0x00, 0x00, 0x00, 0x00, /*_high_slot_id*/ + 0x00, 0x00, 0x00, 0x01, /*_catch_this*/ + ]; + + let (_, req_sequence) = nfs4_req_sequence(&buf[4..]).unwrap(); + match req_sequence { + Nfs4RequestContent::Sequence(seq_buf) => { + assert_eq!(seq_buf.ssn_id, &buf[4..20]); + } + _ => { panic!("Failure, {:?}", req_sequence); } + } + } + + #[test] + fn test_nfs4_request_lookup() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x0f, /*opcode*/ + 0x00, 0x00, 0x00, 0x04, 0x76, 0x6f, 0x6c, 0x31, /*fiename: (vol1)*/ + ]; + + let (_, filename_buf) = nfs4_parse_nfsstring(&buf[4..]).unwrap(); + + let (_, request) = nfs4_req_lookup(&buf[4..]).unwrap(); + match request { + Nfs4RequestContent::Lookup(req_lookup) => { + assert_eq!(req_lookup.filename, filename_buf); + } + _ => { panic!("Failure, {:?}", request); } + } + } + + #[test] + fn test_nfs4_request_putfh() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x16, /*opcode*/ + 0x00, 0x00, 0x00, 0x20, /*handle_len*/ + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*handle*/ + 0x00, 0x00, 0x00, 0x00, 0x84, 0x72, 0x00, 0x00, + 0x23, 0xa6, 0xc0, 0x12, 0x00, 0xf2, 0xfa, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + + let (_, handle_buf) = nfs4_parse_handle(&buf[4..]).unwrap(); + + let (_, result) = nfs4_req_putfh(&buf[4..]).unwrap(); + match result { + Nfs4RequestContent::PutFH(putfh_handle) => { + assert_eq!(putfh_handle.value, handle_buf.value); + assert_eq!(putfh_handle.len, handle_buf.len); + } + _ => { panic!("Failure, {:?}", result); } + } + } + + #[test] + fn test_nfs4_attrs() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x09, /*opcode*/ + 0x00, 0x00, 0x00, 0x03, /*attr_cnt*/ + 0x00, 0x00, 0x20, 0x65, /*attr_mask[0]*/ + 0x00, 0x00, 0x00, 0x00, /*attr_mask[1]*/ + 0x00, 0x00, 0x08, 0x00, /*attr_mask[2]*/ + ]; + + let (r, attr) = nfs4_parse_attrbits(&buf[4..]).unwrap(); + assert_eq!(r.len(), 0); + // assert_eq!(attr.attr_mask, 35618163785728); + assert_eq!(attr.attr_mask, ((0x00002065 as u64) << 32 | 0 as u64)); + } + #[test] + fn test_nfs4_response_compound() { + // Operations: SEQUENCE, PUTFH, CLOSE + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x00, /*status*/ + 0x00, 0x00, 0x00, 0x00, /*Tag*/ + 0x00, 0x00, 0x00, 0x03, /*ops_cnt*/ + // SEQUENCE + 0x00, 0x00, 0x00, 0x35, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xd2, + 0xe0, 0x14, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + // PUTFH + 0x00, 0x00, 0x00, 0x16, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, + // CLOSE + 0x00, 0x00, 0x00, 0x04, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, /*status*/ + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + ]; + + let sequence_buf: &[u8] = &buf[16..56]; + let putfh_buf: &[u8] = &buf[60..64]; + let close_buf: &[u8] = &buf[68..]; + + let (_, res_sequence) = nfs4_res_sequence(sequence_buf).unwrap(); + let (_, res_putfh) = nfs4_res_putfh(putfh_buf).unwrap(); + let (_, res_close) = nfs4_res_close(close_buf).unwrap(); + + let (_, compound_ops) = parse_nfs4_response_compound(buf).unwrap(); + assert_eq!(compound_ops.status, 0); + assert_eq!(compound_ops.commands[0], res_sequence); + assert_eq!(compound_ops.commands[1], res_putfh); + assert_eq!(compound_ops.commands[2], res_close); + } + + #[test] + fn test_nfs4_response_open() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x12, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, /*status*/ + // open_data + 0x00, 0x00, 0x00, 0x01, 0x00, 0x82, 0x14, 0xe0, /*stateid*/ + 0x5b, 0x00, 0x88, 0xd9, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x16, 0xf8, 0x2f, 0xd5, /*_change_info*/ + 0xdb, 0xb7, 0xfe, 0x38, 0x16, 0xf8, 0x2f, 0xdf, + 0x21, 0xa8, 0x2a, 0x48, + 0x00, 0x00, 0x00, 0x04, /*result_flags*/ + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, /*_attrs*/ + 0x00, 0x00, 0x00, 0x02, /*delegation_type*/ + // delegate_read + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x82, 0x14, 0xe0, + 0x5b, 0x00, 0x89, 0xd9, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + ]; + + let stateid_buf = &buf[8..24]; + let (_, res_stateid) = nfs4_parse_stateid(stateid_buf).unwrap(); + + let open_data_buf = &buf[8..]; + let (_, res_open_data) = nfs4_res_open_ok(open_data_buf).unwrap(); + assert_eq!(res_open_data.stateid, res_stateid); + assert_eq!(res_open_data.result_flags, 4); + assert_eq!(res_open_data.delegation_type, 2); + assert_eq!(res_open_data.delegate_read, None); + + let (_, response) = nfs4_res_open(&buf[4..]).unwrap(); + match response { + Nfs4ResponseContent::Open(status, open_data) => { + assert_eq!(status, 0); + assert_eq!(open_data, Some(res_open_data)); + } + _ => { panic!("Failure, {:?}", response); } + } + } + + #[test] + fn test_nfs4_response_write() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x26, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, /*status*/ + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, /*wd*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + ]; + + let (_, wd_buf) = nfs4_res_write_ok(&buf[8..]).unwrap(); + assert_eq!(wd_buf.count, 5); + assert_eq!(wd_buf.committed, 2); + + let (_, result) = nfs4_res_write(&buf[4..]).unwrap(); + match result { + Nfs4ResponseContent::Write(status, wd) => { + assert_eq!(status, 0); + assert_eq!(wd, Some(wd_buf)); + } + _ => { panic!("Failure, {:?}", result); } + } + } + + #[test] + fn test_nfs4_response_access() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x03, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, /*status*/ + 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1f, /*ad*/ + ]; + + let (_, ad_buf) = nfs4_res_access_ok(&buf[8..]).unwrap(); + assert_eq!(ad_buf.supported_types, 0x1f); + assert_eq!(ad_buf.access_rights, 0x1f); + + let (_, result) = nfs4_res_access(&buf[4..]).unwrap(); + match result { + Nfs4ResponseContent::Access(status, ad) => { + assert_eq!(status, 0); + assert_eq!(ad, Some(ad_buf)); + } + _ => { panic!("Failure, {:?}", result); } + } + } + + #[test] + fn test_nfs4_response_getfh() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x0a, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, /*status*/ + 0x00, 0x00, 0x00, 0x20, 0x01, 0x01, 0x00, 0x00, /*fh*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x8b, 0xae, 0xea, 0x7f, + 0xff, 0xf1, 0xfa, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + ]; + + let (_, fh_buf) = nfs4_parse_handle(&buf[8..]).unwrap(); + + let (_, result) = nfs4_res_getfh(&buf[4..]).unwrap(); + match result { + Nfs4ResponseContent::GetFH(status, fh) => { + assert_eq!(status, 0); + assert_eq!(fh, Some(fh_buf)); + } + _ => { panic!("Failure, {:?}", result); } + } + } + + #[test] + fn test_nfs4_response_getattr() { + #[rustfmt::skip] + let buf: &[u8] = &[ + 0x00, 0x00, 0x00, 0x09, /*opcode*/ + 0x00, 0x00, 0x00, 0x00, /*status*/ + 0x00, 0x00, 0x00, 0x03, /*attr_cnt*/ + 0x00, 0x00, 0x20, 0x65, 0x00, 0x00, 0x00, 0x00, /*attr_mask*/ + 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, /*attrs*/ + 0xfa, 0xfe, 0xbf, 0xff, 0x60, 0xfd, 0xff, 0xfe, + 0x00, 0x00, 0x08, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, + 0x02, 0x00, 0x10, 0x00, 0x00, 0x24, 0x40, 0x32, + 0x00, 0x00, 0x00, 0x00 + ]; + + let (_, attrs_buf) = nfs4_parse_attrs(&buf[8..]).unwrap(); + + let (_, attr_fields) = nfs4_parse_attr_fields(&buf[24..]).unwrap(); + assert_eq!(attr_fields, 48); + + let (_, result) = nfs4_res_getattr(&buf[4..]).unwrap(); + match result { + Nfs4ResponseContent::GetAttr(status, attrs) => { + assert_eq!(status, 0); + assert_eq!(attrs, Some(attrs_buf)); + } + _ => { panic!("Failure, {:?}", result); } + } + } +}