diff options
| -rw-r--r-- | tests/common/git_server.rs | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/tests/common/git_server.rs b/tests/common/git_server.rs index 9fb62df..3190901 100644 --- a/tests/common/git_server.rs +++ b/tests/common/git_server.rs | |||
| @@ -128,18 +128,26 @@ impl SimpleGitServer { | |||
| 128 | ); | 128 | ); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | // 4. Find a free port | 131 | // 4. Create and bind listener (eliminates port race condition) |
| 132 | let port = find_free_port(); | 132 | let std_listener = |
| 133 | let addr: SocketAddr = ([127, 0, 0, 1], port).into(); | 133 | std::net::TcpListener::bind("127.0.0.1:0").expect("Failed to bind to random port"); |
| 134 | let port = std_listener | ||
| 135 | .local_addr() | ||
| 136 | .expect("Failed to get local addr") | ||
| 137 | .port(); | ||
| 138 | |||
| 139 | // Convert to tokio listener (keeps port bound) | ||
| 140 | std_listener | ||
| 141 | .set_nonblocking(true) | ||
| 142 | .expect("Failed to set non-blocking"); | ||
| 143 | let listener = | ||
| 144 | TcpListener::from_std(std_listener).expect("Failed to convert to tokio listener"); | ||
| 134 | 145 | ||
| 135 | // 5. Create shutdown channel | 146 | // 5. Create shutdown channel |
| 136 | let (shutdown_tx, mut shutdown_rx) = oneshot::channel::<()>(); | 147 | let (shutdown_tx, mut shutdown_rx) = oneshot::channel::<()>(); |
| 137 | 148 | ||
| 138 | // 6. Start the HTTP server | 149 | // 6. Start the HTTP server |
| 139 | let repo_path = Arc::new(bare_repo_path); | 150 | let repo_path = Arc::new(bare_repo_path); |
| 140 | let listener = TcpListener::bind(addr) | ||
| 141 | .await | ||
| 142 | .expect("Failed to bind to address"); | ||
| 143 | 151 | ||
| 144 | let handle = tokio::spawn(async move { | 152 | let handle = tokio::spawn(async move { |
| 145 | println!("[SmartGitServer] Server loop started on port {}", port); | 153 | println!("[SmartGitServer] Server loop started on port {}", port); |
| @@ -296,19 +304,6 @@ fn guess_content_type(path: &Path) -> &'static str { | |||
| 296 | } | 304 | } |
| 297 | } | 305 | } |
| 298 | 306 | ||
| 299 | /// Find a free port to use for the server. | ||
| 300 | fn find_free_port() -> u16 { | ||
| 301 | use std::net::TcpListener; | ||
| 302 | |||
| 303 | let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind to random port"); | ||
| 304 | let port = listener | ||
| 305 | .local_addr() | ||
| 306 | .expect("Failed to get local addr") | ||
| 307 | .port(); | ||
| 308 | drop(listener); | ||
| 309 | port | ||
| 310 | } | ||
| 311 | |||
| 312 | /// Wait for the server to be ready to accept connections. | 307 | /// Wait for the server to be ready to accept connections. |
| 313 | async fn wait_for_server_ready(port: u16) { | 308 | async fn wait_for_server_ready(port: u16) { |
| 314 | let max_attempts = 50; // 5 seconds total | 309 | let max_attempts = 50; // 5 seconds total |