rusteron_media_driver/
testing.rs1use crate::{Aeron, AeronCError, AeronDriver, AeronDriverContext, IntoCString};
8use std::sync::atomic::{AtomicBool, Ordering};
9use std::sync::Arc;
10use std::thread::JoinHandle;
11
12pub struct EmbeddedDriver {
22 dir: String,
23 context: AeronDriverContext,
24 stop: Arc<AtomicBool>,
25 handle: Option<JoinHandle<Result<(), AeronCError>>>,
26}
27
28impl EmbeddedDriver {
29 pub fn launch() -> Result<Self, AeronCError> {
31 Self::launch_with(|_| Ok(()))
32 }
33
34 pub fn launch_with(
37 configure: impl FnOnce(&AeronDriverContext) -> Result<(), AeronCError>,
38 ) -> Result<Self, AeronCError> {
39 let context = AeronDriverContext::new()?;
40 context.set_dir_delete_on_shutdown(true)?;
41 context.set_dir_delete_on_start(true)?;
42 context.set_dir(&format!("{}{}", context.get_dir(), Aeron::nano_clock()).into_c_string())?;
43 configure(&context)?;
44 let dir = context.get_dir().to_string();
45 let (stop, handle) = AeronDriver::launch_embedded(context.clone(), false);
46 Ok(Self {
47 dir,
48 context,
49 stop,
50 handle: Some(handle),
51 })
52 }
53
54 #[inline]
56 pub fn dir(&self) -> &str {
57 &self.dir
58 }
59
60 #[inline]
62 pub fn context(&self) -> &AeronDriverContext {
63 &self.context
64 }
65
66 pub fn stop(mut self) {
68 self.stop_and_join();
69 }
70
71 fn stop_and_join(&mut self) {
72 self.stop.store(true, Ordering::SeqCst);
73 if let Some(handle) = self.handle.take() {
74 let _ = handle.join();
75 }
76 }
77}
78
79impl Drop for EmbeddedDriver {
80 fn drop(&mut self) {
81 self.stop_and_join();
82 }
83}
84
85pub fn find_unused_udp_port(start: u16) -> Option<u16> {
87 (start..65535).find(|p| std::net::UdpSocket::bind(("127.0.0.1", *p)).is_ok())
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn embedded_driver_launches_and_stops_on_drop() {
96 let driver = EmbeddedDriver::launch().unwrap();
97 assert!(!driver.dir().is_empty());
98 let dir = driver.dir().to_string();
99 drop(driver); assert!(!std::path::Path::new(&dir).join("cnc.dat").exists());
101 }
102
103 #[test]
104 fn find_unused_udp_port_returns_bindable_port() {
105 let port = find_unused_udp_port(23000).unwrap();
106 assert!(std::net::UdpSocket::bind(("127.0.0.1", port)).is_ok());
107 }
108}