From 17f25a67934ad10443a4fbb62a563b5f6edcaa5f Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 31 Jul 2023 12:12:01 -0400 Subject: [PATCH] all: better panic messages Always include operands in failing assertions. Use assert_matches over manual match + panic. --- aya-obj/src/btf/btf.rs | 210 ++++++++++++----------- aya-obj/src/btf/relocation.rs | 8 +- aya-obj/src/btf/types.rs | 226 +++++++++---------------- aya-obj/src/obj.rs | 12 +- aya/src/maps/hash_map/hash_map.rs | 2 +- aya/src/maps/perf/perf_buffer.rs | 2 +- aya/src/sys/mod.rs | 32 ++++ test/integration-test/src/tests/elf.rs | 17 +- 8 files changed, 230 insertions(+), 279 deletions(-) diff --git a/aya-obj/src/btf/btf.rs b/aya-obj/src/btf/btf.rs index 4e9abab9..88d43e82 100644 --- a/aya-obj/src/btf/btf.rs +++ b/aya-obj/src/btf/btf.rs @@ -1054,11 +1054,11 @@ pub(crate) struct SecInfo<'a> { #[cfg(test)] mod tests { + use super::*; use crate::btf::{ BtfParam, DataSec, DataSecEntry, DeclTag, Float, Func, FuncProto, Ptr, TypeTag, Var, }; - - use super::*; + use assert_matches::assert_matches; #[test] fn test_parse_header() { @@ -1121,12 +1121,7 @@ mod tests { 0x65, 0x6e, 0x73, 0x65, 0x00, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x00, ]; assert_eq!(data.len(), 517); - let got = Btf::parse(data, Endianness::default()); - match got { - Ok(_) => {} - Err(e) => panic!("{}", e), - } - let btf = got.unwrap(); + let btf = Btf::parse(data, Endianness::default()).unwrap_or_else(|e| panic!("{}", e)); let data2 = btf.to_bytes(); assert_eq!(data2.len(), 517); assert_eq!(data, data2); @@ -1141,10 +1136,8 @@ mod tests { ]; assert_eq!(ext_data.len(), 80); - let got = BtfExt::parse(ext_data, Endianness::default(), &btf); - if let Err(e) = got { - panic!("{}", e) - } + let _: BtfExt = BtfExt::parse(ext_data, Endianness::default(), &btf) + .unwrap_or_else(|e| panic!("{}", e)); } #[test] @@ -1176,16 +1169,9 @@ mod tests { let btf_bytes = btf.to_bytes(); let raw_btf = btf_bytes.as_slice(); - let parsed = Btf::parse(raw_btf, Endianness::default()); - match parsed { - Ok(btf) => { - assert_eq!(btf.string_at(1).unwrap(), "int"); - assert_eq!(btf.string_at(5).unwrap(), "widget"); - } - Err(e) => { - panic!("{}", e) - } - } + let btf = Btf::parse(raw_btf, Endianness::default()).unwrap_or_else(|e| panic!("{}", e)); + assert_eq!(btf.string_at(1).unwrap(), "int"); + assert_eq!(btf.string_at(5).unwrap(), "widget"); } #[test] @@ -1206,15 +1192,9 @@ mod tests { btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) .unwrap(); - if let BtfType::Ptr(fixed) = btf.type_by_id(ptr_type_id).unwrap() { - assert!( - fixed.name_offset == 0, - "expected offset 0, got {}", - fixed.name_offset - ) - } else { - panic!("not a ptr") - } + assert_matches!(btf.type_by_id(ptr_type_id).unwrap(), BtfType::Ptr(fixed) => { + assert_eq!(fixed.name_offset, 0); + }); // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); Btf::parse(&raw, Endianness::default()).unwrap(); @@ -1245,11 +1225,9 @@ mod tests { btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) .unwrap(); - if let BtfType::Int(fixed) = btf.type_by_id(var_type_id).unwrap() { - assert!(fixed.name_offset == name_offset) - } else { - panic!("not an int") - } + assert_matches!(btf.type_by_id(var_type_id).unwrap(), BtfType::Int(fixed) => { + assert_eq!(fixed.name_offset, name_offset); + }); // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); Btf::parse(&raw, Endianness::default()).unwrap(); @@ -1289,14 +1267,16 @@ mod tests { btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) .unwrap(); - if let BtfType::Struct(fixed) = btf.type_by_id(datasec_type_id).unwrap() { - assert!(fixed.name_offset == name_offset); - assert!(fixed.members.len() == 1); - assert!(fixed.members[0].btf_type == var_type_id); - assert!(fixed.members[0].offset == 0) - } else { - panic!("not a struct") - } + assert_matches!(btf.type_by_id(datasec_type_id).unwrap(), BtfType::Struct(fixed) => { + assert_eq!(fixed.name_offset , name_offset); + assert_matches!(*fixed.members, [ + BtfMember { + name_offset: _, + btf_type, + offset: 0, + }, + ] => assert_eq!(btf_type, var_type_id)); + }); // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); Btf::parse(&raw, Endianness::default()).unwrap(); @@ -1341,20 +1321,23 @@ mod tests { ) .unwrap(); - if let BtfType::DataSec(fixed) = btf.type_by_id(datasec_type_id).unwrap() { - assert!(fixed.name_offset != name_offset); - assert!(fixed.size == 32); - assert!(fixed.entries.len() == 1); - assert!(fixed.entries[0].btf_type == var_type_id); - assert!( - fixed.entries[0].offset == 64, - "expected 64, got {}", - fixed.entries[0].offset + assert_matches!(btf.type_by_id(datasec_type_id).unwrap(), BtfType::DataSec(fixed) => { + assert_ne!(fixed.name_offset, name_offset); + assert_eq!(fixed.size, 32); + assert_matches!(*fixed.entries, [ + DataSecEntry { + btf_type, + offset, + size, + }, + ] => { + assert_eq!(btf_type, var_type_id); + assert_eq!(offset, 64); + assert_eq!(size, 4); + } ); - assert!(btf.string_at(fixed.name_offset).unwrap() == ".data.foo") - } else { - panic!("not a datasec") - } + assert_eq!(btf.string_at(fixed.name_offset).unwrap(), ".data.foo"); + }); // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); Btf::parse(&raw, Endianness::default()).unwrap(); @@ -1397,23 +1380,31 @@ mod tests { btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) .unwrap(); - if let BtfType::Enum(fixed) = btf.type_by_id(func_proto_type_id).unwrap() { - assert!(fixed.name_offset == 0); - assert!(fixed.variants.len() == 2); - assert!(btf.string_at(fixed.variants[0].name_offset).unwrap() == "a"); - assert!(fixed.variants[0].value == int_type_id); - assert!(btf.string_at(fixed.variants[1].name_offset).unwrap() == "b"); - assert!(fixed.variants[1].value == int_type_id); - } else { - panic!("not an emum") - } + assert_matches!(btf.type_by_id(func_proto_type_id).unwrap(), BtfType::Enum(fixed) => { + assert_eq!(fixed.name_offset, 0); + assert_matches!(*fixed.variants, [ + BtfEnum { + name_offset: name_offset1, + value: value1, + }, + BtfEnum { + name_offset: name_offset2, + value: value2, + }, + ] => { + assert_eq!(btf.string_at(name_offset1).unwrap(), "a"); + assert_eq!(value1, int_type_id); + assert_eq!(btf.string_at(name_offset2).unwrap(), "b"); + assert_eq!(value2, int_type_id); + } + ); + }); + + assert_matches!(btf.type_by_id(func_type_id).unwrap(), BtfType::Typedef(fixed) => { + assert_eq!(fixed.name_offset, inc); + assert_eq!(fixed.btf_type, func_proto_type_id); + }); - if let BtfType::Typedef(fixed) = btf.type_by_id(func_type_id).unwrap() { - assert!(fixed.name_offset == inc); - assert!(fixed.btf_type == func_proto_type_id); - } else { - panic!("not a typedef") - } // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); Btf::parse(&raw, Endianness::default()).unwrap(); @@ -1447,12 +1438,25 @@ mod tests { btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) .unwrap(); - if let BtfType::FuncProto(fixed) = btf.type_by_id(func_proto_type_id).unwrap() { - assert!(btf.string_at(fixed.params[0].name_offset).unwrap() == "param0"); - assert!(btf.string_at(fixed.params[1].name_offset).unwrap() == "param1"); - } else { - panic!("not a func_proto") - } + assert_matches!(btf.type_by_id(func_proto_type_id).unwrap(), BtfType::FuncProto(fixed) => { + assert_matches!(*fixed.params, [ + BtfParam { + name_offset: name_offset1, + btf_type: btf_type1, + }, + BtfParam { + name_offset: name_offset2, + btf_type: btf_type2, + }, + ] => { + assert_eq!(btf.string_at(name_offset1).unwrap(), "param0"); + assert_eq!(btf_type1, int_type_id); + assert_eq!(btf.string_at(name_offset2).unwrap(), "param1"); + assert_eq!(btf_type2, int_type_id); + } + ); + }); + // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); Btf::parse(&raw, Endianness::default()).unwrap(); @@ -1497,11 +1501,10 @@ mod tests { btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) .unwrap(); - if let BtfType::Func(fixed) = btf.type_by_id(func_type_id).unwrap() { - assert!(fixed.linkage() == FuncLinkage::Static); - } else { - panic!("not a func") - } + assert_matches!(btf.type_by_id(func_type_id).unwrap(), BtfType::Func(fixed) => { + assert_eq!(fixed.linkage(), FuncLinkage::Static); + }); + // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); Btf::parse(&raw, Endianness::default()).unwrap(); @@ -1549,11 +1552,9 @@ mod tests { btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) .unwrap(); - if let BtfType::Func(fixed) = btf.type_by_id(func_type_id).unwrap() { - assert!(fixed.linkage() == FuncLinkage::Static); - } else { - panic!("not a func") - } + assert_matches!(btf.type_by_id(func_type_id).unwrap(), BtfType::Func(fixed) => { + assert_eq!(fixed.linkage(), FuncLinkage::Static); + }); // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); @@ -1574,12 +1575,11 @@ mod tests { btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) .unwrap(); - if let BtfType::Struct(fixed) = btf.type_by_id(float_type_id).unwrap() { - assert!(fixed.name_offset == 0); - assert!(fixed.size == 16); - } else { - panic!("not a struct") - } + assert_matches!(btf.type_by_id(float_type_id).unwrap(), BtfType::Struct(fixed) => { + assert_eq!(fixed.name_offset, 0); + assert_eq!(fixed.size, 16); + }); + // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); Btf::parse(&raw, Endianness::default()).unwrap(); @@ -1614,12 +1614,11 @@ mod tests { btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) .unwrap(); - if let BtfType::Int(fixed) = btf.type_by_id(decl_tag_type_id).unwrap() { - assert!(fixed.name_offset == name_offset); - assert!(fixed.size == 1); - } else { - panic!("not an int") - } + assert_matches!(btf.type_by_id(decl_tag_type_id).unwrap(), BtfType::Int(fixed) => { + assert_eq!(fixed.name_offset, name_offset); + assert_eq!(fixed.size, 1); + }); + // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); Btf::parse(&raw, Endianness::default()).unwrap(); @@ -1642,11 +1641,10 @@ mod tests { btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) .unwrap(); - if let BtfType::Const(fixed) = btf.type_by_id(type_tag_type).unwrap() { - assert!(fixed.btf_type == int_type_id); - } else { - panic!("not a const") - } + assert_matches!(btf.type_by_id(type_tag_type).unwrap(), BtfType::Const(fixed) => { + assert_eq!(fixed.btf_type, int_type_id); + }); + // Ensure we can convert to bytes and back again let raw = btf.to_bytes(); Btf::parse(&raw, Endianness::default()).unwrap(); diff --git a/aya-obj/src/btf/relocation.rs b/aya-obj/src/btf/relocation.rs index c495a19e..898c4e44 100644 --- a/aya-obj/src/btf/relocation.rs +++ b/aya-obj/src/btf/relocation.rs @@ -580,7 +580,7 @@ fn match_member<'target>( // this won't panic, bounds are checked when local_spec is built in AccessSpec::new BtfType::Struct(s) => s.members.get(local_accessor.index).unwrap(), BtfType::Union(u) => u.members.get(local_accessor.index).unwrap(), - _ => panic!("bug! this should only be called for structs and unions"), + local_ty => panic!("unexpected type {:?}", local_ty), }; let local_name = &*local_btf.string_at(local_member.name_offset)?; @@ -1210,8 +1210,10 @@ impl ComputedRelocation { FieldRShift64 => { value.value = 64 - bit_size as u64; } - FieldExists // this is handled at the start of the function - | _ => panic!("bug! this should not be reached"), + kind @ (FieldExists | TypeIdLocal | TypeIdTarget | TypeExists | TypeSize + | EnumVariantExists | EnumVariantValue) => { + panic!("unexpected relocation kind {:?}", kind) + } } Ok(value) diff --git a/aya-obj/src/btf/types.rs b/aya-obj/src/btf/types.rs index 01e1168c..84497ec8 100644 --- a/aya-obj/src/btf/types.rs +++ b/aya-obj/src/btf/types.rs @@ -1327,7 +1327,7 @@ pub(crate) fn types_are_compatible( continue; } } - _ => panic!("this shouldn't be reached"), + local_ty => panic!("unexpected type {:?}", local_ty), } } @@ -1378,7 +1378,7 @@ pub(crate) fn fields_are_compatible( continue; } } - _ => panic!("this shouldn't be reached"), + local_ty => panic!("unexpected type {:?}", local_ty), } } @@ -1392,6 +1392,7 @@ fn bytes_of(val: &T) -> &[u8] { #[cfg(test)] mod tests { use super::*; + use assert_matches::assert_matches; #[test] fn test_read_btf_type_int() { @@ -1400,18 +1401,17 @@ mod tests { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Int(new)) => { - assert_eq!(new.name_offset, 1); - assert_eq!(new.size, 8); + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Int(new @ Int { + name_offset, + info: _, + size, + data: _, + }) => { + assert_eq!(name_offset, 1); + assert_eq!(size, 8); assert_eq!(new.bits(), 64); - let data2 = new.to_bytes(); - assert_eq!(data, data2); - } - Ok(t) => panic!("expected int type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } + assert_eq!(new.to_bytes(), data); + }); } #[test] @@ -1450,14 +1450,9 @@ mod tests { let data: &[u8] = &[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Ptr(_)) => {} - Ok(t) => panic!("expected ptr type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Ptr(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1467,14 +1462,9 @@ mod tests { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Array(_)) => {} - Ok(t) => panic!("expected array type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Array(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1484,14 +1474,9 @@ mod tests { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x47, 0x02, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Struct(_)) => {} - Ok(t) => panic!("expected struct type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Struct(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1501,14 +1486,9 @@ mod tests { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x00, 0x0d, 0x04, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Union(_)) => {} - Ok(t) => panic!("expected union type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Union(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1518,14 +1498,9 @@ mod tests { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Enum(_)) => {} - Ok(t) => panic!("expected enum type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Enum(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1534,14 +1509,9 @@ mod tests { let data: &[u8] = &[ 0x0b, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Fwd(_)) => {} - Ok(t) => panic!("expected fwd type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Fwd(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1550,14 +1520,9 @@ mod tests { let data: &[u8] = &[ 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Typedef(_)) => {} - Ok(t) => panic!("expected typedef type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Typedef(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1566,14 +1531,9 @@ mod tests { let data: &[u8] = &[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x24, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Volatile(_)) => {} - Ok(t) => panic!("expected volatile type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Volatile(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1582,14 +1542,9 @@ mod tests { let data: &[u8] = &[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Const(_)) => {} - Ok(t) => panic!("expected const type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Const(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1598,14 +1553,9 @@ mod tests { let data: &[u8] = &[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Restrict(_)) => {} - Ok(t) => panic!("expected restrict type gpt {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Restrict(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1614,14 +1564,9 @@ mod tests { let data: &[u8] = &[ 0x17, 0x8b, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xe4, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Func(_)) => {} - Ok(t) => panic!("expected func type gpt {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Func(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1631,14 +1576,9 @@ mod tests { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::FuncProto(_)) => {} - Ok(t) => panic!("expected func_proto type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::FuncProto(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1649,14 +1589,9 @@ mod tests { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Var(_)) => {} - Ok(t) => panic!("expected var type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - }; - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Var(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1666,19 +1601,22 @@ mod tests { 0xd9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match &got { - Ok(BtfType::DataSec(ty)) => { - assert_eq!(0, ty.size); - assert_eq!(11, ty.entries[0].btf_type); - assert_eq!(0, ty.entries[0].offset); - assert_eq!(4, ty.entries[0].size); + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::DataSec(DataSec { + name_offset: _, + info: _, + size, + entries, + }) => { + assert_eq!(size, 0); + assert_matches!(*entries, [ + DataSecEntry { + btf_type: 11, + offset: 0, + size: 4, + } + ]); } - Ok(t) => panic!("expected datasec type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + ); } #[test] @@ -1687,14 +1625,9 @@ mod tests { let data: &[u8] = &[ 0x78, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, ]; - let got = unsafe { BtfType::read(data, endianness) }; - match got { - Ok(BtfType::Float(_)) => {} - Ok(t) => panic!("expected float type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } - let data2 = got.unwrap().to_bytes(); - assert_eq!(data, data2) + assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Float(got) => { + assert_eq!(got.to_bytes(), data); + }); } #[test] @@ -1711,14 +1644,17 @@ mod tests { ]; let func_proto = FuncProto::new(params, 2); let data = func_proto.to_bytes(); - let got = unsafe { BtfType::read(&data, Endianness::default()) }; - match got { - Ok(BtfType::FuncProto(fp)) => { - assert_eq!(fp.params.len(), 2); - } - Ok(t) => panic!("expected func proto type, got {t:#?}"), - Err(_) => panic!("unexpected error"), - } + assert_matches!(unsafe { BtfType::read(&data, Endianness::default()) }.unwrap(), BtfType::FuncProto(FuncProto { + name_offset: _, + info: _, + return_type: _, + params, + }) => { + assert_matches!(*params, [ + _, + _, + ]) + }); } #[test] diff --git a/aya-obj/src/obj.rs b/aya-obj/src/obj.rs index a36eb684..0fec2c06 100644 --- a/aya-obj/src/obj.rs +++ b/aya-obj/src/obj.rs @@ -1771,11 +1771,9 @@ mod tests { assert!(obj.maps.get("bar").is_some()); assert!(obj.maps.get("baz").is_some()); for map in obj.maps.values() { - if let Map::Legacy(m) = map { + assert_matches!(map, Map::Legacy(m) => { assert_eq!(&m.def, def); - } else { - panic!("expected a BTF map") - } + }) } } @@ -2462,12 +2460,10 @@ mod tests { obj.parse_section(map_section).unwrap(); let map = obj.maps.get("map_1").unwrap(); - if let Map::Btf(m) = map { + assert_matches!(map, Map::Btf(m) => { assert_eq!(m.def.key_size, 4); assert_eq!(m.def.value_size, 8); assert_eq!(m.def.max_entries, 1); - } else { - panic!("expected a BTF map") - } + }); } } diff --git a/aya/src/maps/hash_map/hash_map.rs b/aya/src/maps/hash_map/hash_map.rs index 2fcb1334..49cb920d 100644 --- a/aya/src/maps/hash_map/hash_map.rs +++ b/aya/src/maps/hash_map/hash_map.rs @@ -623,7 +623,7 @@ mod tests { Some(10) => set_next_key(attr, 20), Some(20) => return sys_error(EFAULT), Some(30) => return sys_error(ENOENT), - Some(_) => panic!(), + Some(i) => panic!("invalid key {}", i), }; Ok(1) diff --git a/aya/src/maps/perf/perf_buffer.rs b/aya/src/maps/perf/perf_buffer.rs index 19813557..1024152a 100644 --- a/aya/src/maps/perf/perf_buffer.rs +++ b/aya/src/maps/perf/perf_buffer.rs @@ -331,7 +331,7 @@ mod tests { fn fake_mmap(buf: &MMappedBuf) { override_syscall(|call| match call { Syscall::PerfEventOpen { .. } | Syscall::PerfEventIoctl { .. } => Ok(42), - _ => panic!(), + call => panic!("unexpected syscall: {:?}", call), }); TEST_MMAP_RET.with(|ret| *ret.borrow_mut() = buf as *const _ as *mut _); } diff --git a/aya/src/sys/mod.rs b/aya/src/sys/mod.rs index 448e7fee..159abee0 100644 --- a/aya/src/sys/mod.rs +++ b/aya/src/sys/mod.rs @@ -38,6 +38,38 @@ pub(crate) enum Syscall<'a> { }, } +impl std::fmt::Debug for Syscall<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Bpf { cmd, attr: _ } => f + .debug_struct("Syscall::Bpf") + .field("cmd", cmd) + .field("attr", &format_args!("_")) + .finish(), + Self::PerfEventOpen { + attr: _, + pid, + cpu, + group, + flags, + } => f + .debug_struct("Syscall::PerfEventOpen") + .field("attr", &format_args!("_")) + .field("pid", pid) + .field("cpu", cpu) + .field("group", group) + .field("flags", flags) + .finish(), + Self::PerfEventIoctl { fd, request, arg } => f + .debug_struct("Syscall::PerfEventIoctl") + .field("fd", fd) + .field("request", request) + .field("arg", arg) + .finish(), + } + } +} + fn syscall(call: Syscall) -> SysResult { #[cfg(test)] return TEST_SYSCALL.with(|test_impl| unsafe { test_impl.borrow()(call) }); diff --git a/test/integration-test/src/tests/elf.rs b/test/integration-test/src/tests/elf.rs index 3ebbdf58..9c68144f 100644 --- a/test/integration-test/src/tests/elf.rs +++ b/test/integration-test/src/tests/elf.rs @@ -3,19 +3,6 @@ use object::{Object, ObjectSymbol}; #[test] fn test_maps() { let obj_file = object::File::parse(crate::MAP_TEST).unwrap(); - if obj_file.section_by_name("maps").is_none() { - panic!("No 'maps' ELF section"); - } - let mut found = false; - for sym in obj_file.symbols() { - if let Ok(name) = sym.name() { - if name == "BAR" { - found = true; - break; - } - } - } - if !found { - panic!("No symbol 'BAR' in ELF file") - } + assert!(obj_file.section_by_name("maps").is_some()); + assert!(obj_file.symbols().any(|sym| sym.name() == Ok("BAR"))); }