85 lines
2.4 KiB
Rust
85 lines
2.4 KiB
Rust
#![no_main]
|
|
|
|
use libfuzzer_sys::fuzz_target;
|
|
use announcement::Announcement;
|
|
|
|
fuzz_target!(|data: &[u8]| {
|
|
if data.is_empty() {
|
|
return;
|
|
}
|
|
|
|
let action = data[0] % 4;
|
|
|
|
match action {
|
|
0 => {
|
|
// Test drop without announce
|
|
let (announcer, announcement) = Announcement::<u32>::new();
|
|
let listener = announcement.listener();
|
|
|
|
assert!(!announcement.is_closed());
|
|
drop(announcer);
|
|
|
|
// Should be closed now
|
|
assert!(announcement.is_closed());
|
|
assert!(listener.is_closed());
|
|
}
|
|
1 => {
|
|
// Test explicit close
|
|
let (announcer, announcement) = Announcement::<u32>::new();
|
|
let listener = announcement.listener();
|
|
|
|
assert!(!announcement.is_closed());
|
|
announcer.close();
|
|
|
|
// Should be closed now
|
|
assert!(announcement.is_closed());
|
|
assert!(listener.is_closed());
|
|
}
|
|
2 => {
|
|
// Test announce then drop (should not be closed)
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
|
|
let _ = announcer.announce(42u32);
|
|
// announcer is consumed by announce(), no need to drop
|
|
|
|
// Should NOT be closed (announced successfully)
|
|
assert!(!announcement.is_closed());
|
|
assert!(!listener.is_closed());
|
|
|
|
// Listener should get value
|
|
assert_eq!(listener.try_listen(), Some(42u32));
|
|
}
|
|
_ => {
|
|
// Test listener created after close
|
|
let (announcer, announcement) = Announcement::<u32>::new();
|
|
|
|
announcer.close();
|
|
|
|
// Create listener after close
|
|
let listener = announcement.listener();
|
|
|
|
// Should immediately know it's closed
|
|
assert!(listener.is_closed());
|
|
}
|
|
}
|
|
|
|
// Test with multiple listeners
|
|
if data.len() >= 2 {
|
|
let num_listeners = (data[1] % 10) as usize + 1; // 1-10 listeners
|
|
|
|
let (announcer, announcement) = Announcement::<u32>::new();
|
|
let listeners: Vec<_> = (0..num_listeners)
|
|
.map(|_| announcement.listener())
|
|
.collect();
|
|
|
|
// Drop announcer
|
|
drop(announcer);
|
|
|
|
// All should see closed state
|
|
for listener in listeners {
|
|
assert!(listener.is_closed());
|
|
}
|
|
}
|
|
});
|