use absurder_sql::storage::block_storage::{BLOCK_SIZE, BlockStorage};
#[cfg(not(target_arch = "wasm32"))]
use absurder_sql::types::DatabaseError;
#[cfg(not(target_arch = "wasm32"))]
use std::sync::{Arc, Mutex};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test_configure!(run_in_browser);
#[cfg(not(target_arch = "wasm32"))]
#[tokio::test]
async fn test_sync_event_callbacks() {
let mut storage = BlockStorage::new("events_test")
.await
.expect("create storage");
let events = Arc::new(Mutex::new(Vec::<String>::new()));
let events_clone = events.clone();
storage.set_sync_callbacks(
Box::new(move |dirty_count, dirty_bytes| {
events_clone
.lock()
.unwrap()
.push(format!("sync_start:{}:{}", dirty_count, dirty_bytes));
}),
{
let events_clone = events.clone();
Box::new(move |duration_ms, blocks_synced| {
events_clone
.lock()
.unwrap()
.push(format!("sync_success:{}:{}", duration_ms, blocks_synced));
})
},
{
let events_clone = events.clone();
Box::new(move |error: &DatabaseError| {
events_clone
.lock()
.unwrap()
.push(format!("sync_failure:{}", error.message));
})
},
);
let block1 = storage.allocate_block().await.expect("allocate block1");
storage
.write_block(block1, vec![1u8; BLOCK_SIZE])
.await
.expect("write block1");
storage.sync().await.expect("sync blocks");
let events = events.lock().unwrap();
assert!(events.len() >= 2);
assert!(events.iter().any(|e| e.starts_with("sync_start:1:")));
assert!(events.iter().any(|e| e.starts_with("sync_success:")));
}
#[cfg(not(target_arch = "wasm32"))]
#[tokio::test]
async fn test_backpressure_signals() {
let mut storage = BlockStorage::new("backpressure_test")
.await
.expect("create storage");
let backpressure_events = Arc::new(Mutex::new(Vec::<String>::new()));
let events_clone = backpressure_events.clone();
storage.set_backpressure_callback(Box::new(move |level, reason| {
events_clone
.lock()
.unwrap()
.push(format!("backpressure:{}:{}", level, reason));
}));
for i in 0..200 {
let block = storage.allocate_block().await.expect("allocate block");
storage
.write_block(block, vec![i as u8; BLOCK_SIZE])
.await
.expect("write block");
}
let events = backpressure_events.lock().unwrap();
assert!(!events.is_empty());
assert!(events.iter().any(|e| e.contains("backpressure")));
}
#[cfg(not(target_arch = "wasm32"))]
#[tokio::test]
async fn test_error_event_callbacks() {
let mut storage = BlockStorage::new("error_events_test")
.await
.expect("create storage");
let errors = Arc::new(Mutex::new(Vec::<String>::new()));
let errors_clone = errors.clone();
storage.set_error_callback(Box::new(move |error: &DatabaseError| {
errors_clone.lock().unwrap().push(error.message.clone());
}));
let _ = storage.read_block(999).await; let _ = storage.read_block(1000).await; let _ = storage.read_block(9999).await;
let block_id = storage.allocate_block().await.expect("allocate block");
storage
.write_block(block_id, vec![42u8; 4096])
.await
.expect("write block");
storage.sync().await.expect("sync block");
for i in 10000..10010 {
let _ = storage.read_block(i).await;
}
let errors = errors.lock().unwrap();
let metrics = storage.get_metrics();
println!(
"Error callback captured {} errors: {:?}",
errors.len(),
*errors
);
println!("Metrics show {} errors", metrics.error_count);
if metrics.error_count > 0 {
assert!(
!errors.is_empty(),
"Metrics show {} errors but callback wasn't fired",
metrics.error_count
);
} else {
println!("No errors generated in fs_persist mode - this is expected behavior");
return; }
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen_test]
async fn test_wasm_sync_callbacks() {
let mut storage = BlockStorage::new("wasm_events_test")
.await
.expect("create storage");
storage.set_sync_success_callback(Box::new(move |duration_ms, blocks_synced| {
web_sys::console::log_1(
&format!(
"WASM sync success: {}ms, {} blocks",
duration_ms, blocks_synced
)
.into(),
);
}));
let block1 = storage.allocate_block().await.expect("allocate block1");
storage
.write_block(block1, vec![1u8; BLOCK_SIZE])
.await
.expect("write block1");
storage.sync().await.expect("sync blocks");
assert!(true); }