Setup a test server with custom initialization
(init: F)
| 44 | |
| 45 | /// Setup a test server with custom initialization |
| 46 | pub async fn setup_test_server_with_init<F, Fut>(init: F) -> TestServer |
| 47 | where |
| 48 | F: FnOnce(Arc<pgsqlite::session::DbHandler>) -> Fut + Send + 'static, |
| 49 | Fut: std::future::Future<Output = Result<(), Box<dyn std::error::Error + Send + Sync>>> + Send, |
| 50 | { |
| 51 | // Start test server |
| 52 | let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); |
| 53 | let port = listener.local_addr().unwrap().port(); |
| 54 | |
| 55 | let test_id = Uuid::new_v4().to_string().replace("-", ""); |
| 56 | let db_path = format!("/tmp/pgsqlite_test_{test_id}.db"); |
| 57 | let db_path_clone = db_path.clone(); |
| 58 | |
| 59 | let server_handle = tokio::spawn(async move { |
| 60 | let db_handler = Arc::new( |
| 61 | pgsqlite::session::DbHandler::new(&db_path_clone).unwrap() |
| 62 | ); |
| 63 | |
| 64 | // Run custom initialization |
| 65 | if let Err(e) = init(db_handler.clone()).await { |
| 66 | eprintln!("Init error: {e}"); |
| 67 | return; |
| 68 | } |
| 69 | |
| 70 | // Force a comprehensive cache refresh after initialization |
| 71 | // This ensures that tables created during init are visible to catalog queries |
| 72 | // In connection-per-session mode, we use execute method instead of direct connection access |
| 73 | let _ = db_handler.execute("PRAGMA schema_version").await; |
| 74 | let _ = db_handler.execute("PRAGMA table_list").await; |
| 75 | |
| 76 | // Add a small delay to ensure changes propagate |
| 77 | tokio::time::sleep(tokio::time::Duration::from_millis(10)).await; |
| 78 | |
| 79 | let (stream, addr) = listener.accept().await.unwrap(); |
| 80 | if let Err(e) = pgsqlite::handle_test_connection_with_pool(stream, addr, db_handler).await { |
| 81 | eprintln!("Connection handling error: {e}"); |
| 82 | } |
| 83 | }); |
| 84 | |
| 85 | // Give server time to start |
| 86 | tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; |
| 87 | |
| 88 | // Connect with tokio-postgres |
| 89 | let config = format!("host=localhost port={port} dbname=test user=testuser"); |
| 90 | let (client, connection) = tokio_postgres::connect(&config, NoTls).await.unwrap(); |
| 91 | |
| 92 | tokio::spawn(async move { |
| 93 | if let Err(e) = connection.await { |
| 94 | eprintln!("Connection error: {e}"); |
| 95 | } |
| 96 | }); |
| 97 | |
| 98 | TestServer { |
| 99 | client, |
| 100 | port, |
| 101 | server_handle, |
| 102 | db_path, |
| 103 | } |