use macaddr_ouidb::{MacAddress, OUI_DB, OuiDb};
#[test]
fn test_mac_address_parsing() {
let mac1: MacAddress = "00:55:DA:0A:BB:CC".parse().unwrap();
assert_eq!(mac1.octets(), [0x00, 0x55, 0xDA, 0x0A, 0xBB, 0xCC]);
let mac2: MacAddress = "00-55-DA-0A-BB-CC".parse().unwrap();
assert_eq!(mac2.octets(), [0x00, 0x55, 0xDA, 0x0A, 0xBB, 0xCC]);
let mac3: MacAddress = "00:55:da:0a:bb:cc".parse().unwrap();
assert_eq!(mac3.octets(), [0x00, 0x55, 0xDA, 0x0A, 0xBB, 0xCC]);
}
#[test]
fn test_mac_address_special_addresses() {
let zero = MacAddress::zero();
assert!(zero.is_zero());
assert!(!zero.is_broadcast());
let broadcast = MacAddress::broadcast();
assert!(!broadcast.is_zero());
assert!(broadcast.is_broadcast());
let unicast: MacAddress = "00:11:22:33:44:55".parse().unwrap();
assert!(unicast.is_unicast());
assert!(!unicast.is_multicast());
let multicast: MacAddress = "01:00:00:00:00:00".parse().unwrap();
assert!(!multicast.is_unicast());
assert!(multicast.is_multicast());
let universal: MacAddress = "00:11:22:33:44:55".parse().unwrap();
assert!(universal.is_universal());
assert!(!universal.is_local());
let local: MacAddress = "02:11:22:33:44:55".parse().unwrap();
assert!(!local.is_universal());
assert!(local.is_local());
}
#[test]
fn test_oui_lookup_24bit() {
let mac: MacAddress = "00:00:01:00:00:00".parse().unwrap();
let org = OUI_DB.lookup_mac(mac);
assert_eq!(org, Some("Xerox"));
let mac: MacAddress = "00:00:0C:00:00:00".parse().unwrap();
let org = OUI_DB.lookup_mac(mac);
assert_eq!(org, Some("Cisco Systems"));
let mac: MacAddress = "00:03:FF:00:00:00".parse().unwrap();
let org = OUI_DB.lookup_mac(mac);
assert_eq!(org, Some("Microsoft"));
let mac: MacAddress = "00:03:93:FF:FF:FF".parse().unwrap();
let org = OUI_DB.lookup_mac(mac);
assert_eq!(org, Some("Apple"));
}
#[test]
fn test_oui_lookup_28bit() {
let mac: MacAddress = "00:55:DA:0A:BB:CC".parse().unwrap();
let org = OUI_DB.lookup_mac(mac);
assert!(
org.is_some(),
"28-bit OUI lookup failed for 00:55:DA:0A:BB:CC"
);
println!("28-bit OUI: 00:55:DA:0A:BB:CC -> {}", org.unwrap());
let mac1: MacAddress = "00:55:DA:00:00:00".parse().unwrap();
let mac2: MacAddress = "00:55:DA:10:00:00".parse().unwrap();
let org1 = OUI_DB.lookup_mac(mac1);
let org2 = OUI_DB.lookup_mac(mac2);
assert!(
org1.is_some(),
"28-bit OUI lookup failed for 00:55:DA:00:00:00"
);
assert!(
org2.is_some(),
"28-bit OUI lookup failed for 00:55:DA:10:00:00"
);
let mac_fallback: MacAddress = "00:55:DA:F0:00:00".parse().unwrap();
let org_fallback = OUI_DB.lookup_mac(mac_fallback);
assert!(org_fallback.is_some() || org_fallback.is_none());
}
#[test]
fn test_oui_lookup_36bit() {
let mac: MacAddress = "00:16:E3:00:00:00".parse().unwrap();
let org = OUI_DB.lookup_mac(mac);
assert!(
org.is_some(),
"36-bit OUI lookup failed for 00:16:E3:00:00:00"
);
println!("36-bit OUI: 00:16:E3:00:00:00 -> {:?}", org);
let mac2: MacAddress = "00:16:E3:80:00:00".parse().unwrap();
let org2 = OUI_DB.lookup_mac(mac2);
assert!(
org2.is_some(),
"36-bit OUI lookup failed for 00:16:E3:80:00:00"
);
if org != org2 {
println!("Different 36-bit entries return different organizations:");
println!(" 00:16:E3:00:00:00 -> {:?}", org);
println!(" 00:16:E3:80:00:00 -> {:?}", org2);
}
}
#[test]
fn test_oui_lookup_not_found() {
let mac: MacAddress = "FF:FF:FF:00:00:00".parse().unwrap();
let org = OUI_DB.lookup_mac(mac);
assert_eq!(org, None, "Expected None for unallocated OUI FF:FF:FF");
let mac2: MacAddress = "FE:FF:FF:00:00:00".parse().unwrap();
let org2 = OUI_DB.lookup_mac(mac2);
assert_eq!(org2, None, "Expected None for unallocated OUI FE:FF:FF");
println!("Correctly returns None for unallocated OUI addresses");
}
#[test]
fn test_virtual_nic_detection() {
assert!(OuiDb::is_virtual_nic("QEMU virtual NIC"));
assert!(OuiDb::is_virtual_nic("Bochs virtual NIC"));
assert!(OuiDb::is_virtual_nic("PearPC virtual NIC"));
assert!(OuiDb::is_virtual_nic("Cooperative Linux virtual NIC"));
assert!(OuiDb::is_virtual_nic("Oracle VirtualBox virtual NIC"));
assert!(!OuiDb::is_virtual_nic("Cisco Systems"));
assert!(!OuiDb::is_virtual_nic("Intel"));
assert!(!OuiDb::is_virtual_nic("Unknown"));
}
#[test]
fn test_oui_subtable_name() {
assert_eq!(OuiDb::oui_subtable_name(), "Ieee Registration Authority");
}
#[test]
fn test_mac_address_from_bytes() {
let bytes = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC];
let mac = MacAddress::from(bytes);
assert_eq!(mac.octets(), bytes);
}
#[test]
fn test_mac_address_from_slice() {
let bytes = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC];
let mac = MacAddress::from_slice(&bytes);
assert_eq!(mac, Ok(MacAddress::from(bytes)));
let wrong_bytes = [0x12, 0x34, 0x56];
let mac = MacAddress::from_slice(&wrong_bytes);
assert!(mac.is_err());
}
#[test]
fn test_mac_address_display() {
let mac: MacAddress = "00:11:22:33:44:55".parse().unwrap();
assert_eq!(format!("{}", mac), "00:11:22:33:44:55");
}
#[test]
fn test_mac_address_debug() {
let mac: MacAddress = "00:11:22:33:44:55".parse().unwrap();
assert_eq!(format!("{:?}", mac), "00:11:22:33:44:55");
let mac: MacAddress = "fa:16:3e:05:44:9b".parse().unwrap();
assert!(mac.is_local());
}
#[test]
fn test_oui_lookup_batch() {
let test_cases = vec![
("00:00:00:00:00:00", "Xerox"),
("00:00:01:00:00:00", "Xerox"),
("00:00:02:00:00:00", "Xerox"),
("00:00:0C:00:00:00", "Cisco Systems"),
("00:00:17:00:00:00", "Oracle"),
("00:00:39:00:00:00", "Toshiba"),
("00:00:4C:00:00:00", "NEC"),
("00:00:60:00:00:00", "Kontron Europe GmbH"),
("00:00:85:00:00:00", "Canon"),
("00:00:87:00:00:00", "Hitachi"),
("fa:16:3e:05:44:9b", "OpenStack"),
];
for (mac_str, expected_org) in test_cases {
let mac: MacAddress = mac_str.parse().unwrap();
let org = OUI_DB.lookup_mac(mac);
assert_eq!(org, Some(expected_org), "Failed for MAC: {}", mac_str);
}
}
#[test]
fn test_oui_database_coverage() {
let test_addresses = vec![
"00:00:00:00:00:00",
"00:00:0C:00:00:00",
"00:55:DA:00:00:00",
"00:16:E3:00:00:00",
];
let mut found_count = 0;
for addr in test_addresses {
let mac: MacAddress = addr.parse().unwrap();
if OUI_DB.lookup_mac(mac).is_some() {
found_count += 1;
}
}
assert!(
found_count >= 3,
"Expected to find at least 3 OUI entries, found {}",
found_count
);
}
#[test]
fn test_oui_all_types_coverage() {
let mac_24: MacAddress = "00:00:01:00:00:00".parse().unwrap();
let org_24 = OUI_DB.lookup_mac(mac_24);
assert_eq!(org_24, Some("Xerox"), "24-bit OUI lookup failed");
println!("✓ 24-bit OUI: {} -> {:?}", mac_24, org_24);
let mac_28: MacAddress = "00:55:DA:00:00:00".parse().unwrap();
let org_28 = OUI_DB.lookup_mac(mac_28);
assert!(org_28.is_some(), "28-bit OUI lookup failed");
println!("✓ 28-bit OUI: {} -> {:?}", mac_28, org_28);
let mac_36: MacAddress = "00:16:E3:00:00:00".parse().unwrap();
let org_36 = OUI_DB.lookup_mac(mac_36);
assert!(org_36.is_some(), "36-bit OUI lookup failed");
println!("✓ 36-bit OUI: {} -> {:?}", mac_36, org_36);
let mac_none: MacAddress = "FF:FF:FF:00:00:00".parse().unwrap();
let org_none = OUI_DB.lookup_mac(mac_none);
assert_eq!(org_none, None, "Should return None for unallocated OUI");
println!("✓ Unallocated OUI: {} -> {:?}", mac_none, org_none);
println!("\n✅ All OUI types (24/28/36-bit and unallocated) are properly handled!");
}
#[test]
fn test_mac_address_ord() {
let mac1: MacAddress = "00:11:22:33:44:55".parse().unwrap();
let mac2: MacAddress = "00:11:22:33:44:56".parse().unwrap();
let mac3: MacAddress = "00:11:22:33:44:55".parse().unwrap();
assert!(mac1 < mac2);
assert_eq!(mac1, mac3);
assert!(mac2 > mac1);
}
#[test]
fn test_mac_address_default() {
let mac = MacAddress::default();
assert!(mac.is_zero());
}