use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;
mod common;
#[test]
fn test_concurrent_connections() {
let success_count = Arc::new(AtomicUsize::new(0));
let failure_count = Arc::new(AtomicUsize::new(0));
let connection_count = 3;
let mut handles = Vec::new();
println!(
"Testing concurrent connections (BrlAPI supports multiple simultaneous connections)..."
);
for i in 0..connection_count {
let success_count = Arc::clone(&success_count);
let failure_count = Arc::clone(&failure_count);
let handle = thread::spawn(move || {
match common::try_connect() {
Ok(conn) => {
success_count.fetch_add(1, Ordering::SeqCst);
let fd = conn.file_descriptor();
println!("Concurrent connection {i}: fd={fd}");
if let Ok(driver) = conn.display_driver() {
println!("Concurrent connection {i}: Driver: {driver}");
}
if let Ok((w, h)) = conn.display_size() {
println!("Concurrent connection {i}: Display: {w}x{h}");
}
thread::sleep(std::time::Duration::from_millis(100));
println!("Concurrent connection {i}: completed operations");
}
Err(e) => {
failure_count.fetch_add(1, Ordering::SeqCst);
println!("Concurrent connection {i}: Connection failed: {e}");
}
}
});
handles.push(handle);
}
for handle in handles {
handle
.join()
.expect("Concurrent connection thread should not panic");
}
let successes = success_count.load(Ordering::SeqCst);
let failures = failure_count.load(Ordering::SeqCst);
println!("Concurrent connection test: {successes} successes, {failures} failures");
if successes > 0 {
println!(
"[SUCCESS] Concurrent connections work properly (BrlAPI supports multiple simultaneous connections)"
);
} else {
println!("[INFO] No BrlAPI daemon available - concurrent test skipped");
}
assert!(successes + failures <= connection_count);
}
#[test]
fn test_shared_connection_operations() {
use std::sync::{Arc, Mutex};
if let Ok(connection) = common::try_connect() {
let shared_conn = Arc::new(Mutex::new(connection));
let handle1 = {
let conn_clone = Arc::clone(&shared_conn);
thread::spawn(move || {
let conn = conn_clone
.lock()
.expect("Shared connection mutex should not be poisoned");
if let Ok((w, h)) = conn.display_size() {
println!("Thread 1: Display size {w}x{h}");
}
if let Ok(driver) = conn.display_driver() {
println!("Thread 1: Driver {driver}");
}
println!("Thread 1 completed operations");
})
};
let handle2 = {
let conn_clone = Arc::clone(&shared_conn);
thread::spawn(move || {
let conn = conn_clone
.lock()
.expect("Shared connection mutex should not be poisoned in thread 2");
if let Ok((w, h)) = conn.display_size() {
println!("Thread 2: Display size {w}x{h}");
}
if let Ok(driver) = conn.display_driver() {
println!("Thread 2: Driver {driver}");
}
println!("Thread 2 completed operations");
})
};
handle1
.join()
.expect("Shared connection thread 1 should not panic");
handle2
.join()
.expect("Shared connection thread 2 should not panic");
println!("[SUCCESS] Shared connection operations test completed");
} else {
println!("[INFO] No BrlAPI daemon available - shared connection test skipped");
}
}
#[test]
fn test_sequential_connection_behavior() {
const NUM_ATTEMPTS: usize = 3;
let results = Arc::new(std::sync::Mutex::new(Vec::new()));
println!("Testing sequential connection behavior (one after another)...");
for i in 0..NUM_ATTEMPTS {
let thread_result = match common::try_connect() {
Ok(conn) => {
let fd = conn.file_descriptor();
let result = format!("Attempt {i}: FD {fd}");
println!(" {}", result);
if let Ok((w, h)) = conn.display_size() {
println!(" Display: {w}x{h}");
}
result
}
Err(_) => {
let result = format!("Attempt {i}: No daemon available");
println!(" {}", result);
result
}
};
results
.lock()
.expect("Sequential test results mutex should not be poisoned")
.push(thread_result);
}
let results = results
.lock()
.expect("Sequential test results mutex should not be poisoned for reading");
println!("Sequential connection behavior results:");
for result in results.iter() {
println!(" {result}");
}
println!("[NOTE] Note: BrlAPI supports both patterns:");
println!(" - Multiple simultaneous connections work with running daemon");
println!(" - Sequential connections always work (open/close/open)");
println!(" - Both patterns are valid and supported");
assert_eq!(results.len(), NUM_ATTEMPTS);
}