Skip to content

Commit 56bc1b5

Browse files
apollo_infra: move server connection eviction test to designated module
1 parent 47f3aef commit 56bc1b5

3 files changed

Lines changed: 70 additions & 52 deletions

File tree

crates/apollo_infra/src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ mod local_component_client_server_test;
55
mod local_request_prioritization_test;
66
mod remote_client_connection_eviction_test;
77
mod remote_component_client_server_test;
8+
mod remote_server_connection_eviction_test;
89
mod server_metrics_test;

crates/apollo_infra/src/tests/remote_component_client_server_test.rs

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,10 @@ use rstest::rstest;
2424
use serde::de::DeserializeOwned;
2525
use serde::Serialize;
2626
use starknet_types_core::felt::Felt;
27-
use tokio::io::AsyncReadExt;
2827
use tokio::net::TcpListener;
2928
use tokio::sync::mpsc::channel;
3029
use tokio::sync::{Mutex, Semaphore};
3130
use tokio::task;
32-
use tokio::time::{sleep, timeout};
3331

3432
use crate::component_client::{
3533
ClientError,
@@ -54,13 +52,11 @@ use crate::component_server::{
5452
LocalComponentServer,
5553
LocalServerConfig,
5654
RemoteComponentServer,
57-
RemoteServerConfig,
5855
};
5956
use crate::serde_utils::SerdeWrapper;
6057
use crate::tests::test_utils::{
6158
available_ports_factory,
6259
client_socket_keepalive_time,
63-
connect_zombie,
6460
dummy_remote_server_config,
6561
test_a_b_functionality,
6662
ComponentA,
@@ -639,54 +635,6 @@ async fn retry_request() {
639635
verify_error(a_client_no_retry.clone(), &expected_error_contained_keywords).await;
640636
}
641637

642-
/// Verifies that the server closes a zombie connection after the keepalive interval and
643-
/// timeout elapse without receiving a PING response.
644-
#[tokio::test]
645-
async fn zombie_connection_is_evicted() {
646-
const KEEPALIVE_INTERVAL_MS: u64 = 100;
647-
const KEEPALIVE_TIMEOUT_MS: u64 = 100;
648-
const MARGIN_MS: u64 = 500;
649-
650-
let socket = available_ports_factory(unique_u16!()).get_next_local_host_socket();
651-
652-
// Start a RemoteComponentServer with very short keepalive values.
653-
// The local channel receiver is intentionally dropped — no requests will be sent.
654-
let (tx, _rx) = channel::<RequestWrapper<ComponentARequest, ComponentAResponse>>(32);
655-
let local_client = LocalComponentClient::<ComponentARequest, ComponentAResponse>::new(
656-
tx,
657-
&TEST_LOCAL_CLIENT_METRICS,
658-
);
659-
let config = RemoteServerConfig {
660-
keepalive_interval_ms: KEEPALIVE_INTERVAL_MS,
661-
keepalive_timeout_ms: KEEPALIVE_TIMEOUT_MS,
662-
..dummy_remote_server_config(socket.ip(), MAX_CONCURRENCY)
663-
};
664-
let mut server = RemoteComponentServer::new(
665-
local_client,
666-
config,
667-
socket.port(),
668-
&TEST_REMOTE_SERVER_METRICS,
669-
);
670-
task::spawn(async move { server.start().await });
671-
task::yield_now().await;
672-
673-
let mut zombie = connect_zombie(socket).await;
674-
675-
// Wait for the keepalive cycle to fire and time out.
676-
sleep(Duration::from_millis(KEEPALIVE_INTERVAL_MS + KEEPALIVE_TIMEOUT_MS + MARGIN_MS)).await;
677-
678-
// The server should have closed the connection; read_to_end should return quickly with
679-
// whatever GOAWAY bytes were sent, and then EOF.
680-
let mut remainder = Vec::new();
681-
let read_result =
682-
timeout(Duration::from_millis(MARGIN_MS), zombie.read_to_end(&mut remainder)).await;
683-
assert!(
684-
read_result.is_ok(),
685-
"Server should have closed the zombie connection after keepalive timeout, but the \
686-
connection is still open"
687-
);
688-
}
689-
690638
/// Verifies that `TCP_KEEPIDLE` on the client's outbound socket equals
691639
/// `keepalive_timeout_ms * TCP_KEEPALIVE_FACTOR`, confirming the socket is armed to probe after
692640
/// exactly the expected idle period.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use std::time::Duration;
2+
3+
use apollo_proc_macros::unique_u16;
4+
use tokio::io::AsyncReadExt;
5+
use tokio::sync::mpsc::channel;
6+
use tokio::task;
7+
use tokio::time::{sleep, timeout};
8+
9+
use crate::component_client::LocalComponentClient;
10+
use crate::component_definitions::RequestWrapper;
11+
use crate::component_server::{ComponentServerStarter, RemoteComponentServer, RemoteServerConfig};
12+
use crate::tests::test_utils::{
13+
available_ports_factory,
14+
connect_zombie,
15+
dummy_remote_server_config,
16+
ComponentARequest,
17+
ComponentAResponse,
18+
MAX_CONCURRENCY,
19+
TEST_LOCAL_CLIENT_METRICS,
20+
TEST_REMOTE_SERVER_METRICS,
21+
};
22+
23+
/// Verifies that the server closes a zombie connection after the HTTP keepalive interval and
24+
/// timeout elapse without receiving a PING response.
25+
#[tokio::test]
26+
async fn zombie_connection_is_evicted_via_http_keepalive() {
27+
const KEEPALIVE_INTERVAL_MS: u64 = 100;
28+
const KEEPALIVE_TIMEOUT_MS: u64 = 100;
29+
const MARGIN_MS: u64 = 500;
30+
31+
let socket = available_ports_factory(unique_u16!()).get_next_local_host_socket();
32+
33+
// Start a RemoteComponentServer with very short keepalive values.
34+
// The local channel receiver is intentionally dropped — no requests will be sent.
35+
let (tx, _rx) = channel::<RequestWrapper<ComponentARequest, ComponentAResponse>>(32);
36+
let local_client = LocalComponentClient::<ComponentARequest, ComponentAResponse>::new(
37+
tx,
38+
&TEST_LOCAL_CLIENT_METRICS,
39+
);
40+
let config = RemoteServerConfig {
41+
keepalive_interval_ms: KEEPALIVE_INTERVAL_MS,
42+
keepalive_timeout_ms: KEEPALIVE_TIMEOUT_MS,
43+
..dummy_remote_server_config(socket.ip(), MAX_CONCURRENCY)
44+
};
45+
let mut server = RemoteComponentServer::new(
46+
local_client,
47+
config,
48+
socket.port(),
49+
&TEST_REMOTE_SERVER_METRICS,
50+
);
51+
task::spawn(async move { server.start().await });
52+
task::yield_now().await;
53+
54+
let mut zombie = connect_zombie(socket).await;
55+
56+
// Wait for the keepalive cycle to fire and time out.
57+
sleep(Duration::from_millis(KEEPALIVE_INTERVAL_MS + KEEPALIVE_TIMEOUT_MS + MARGIN_MS)).await;
58+
59+
// The server should have closed the connection; read_to_end should return quickly with
60+
// whatever GOAWAY bytes were sent, and then EOF.
61+
let mut remainder = Vec::new();
62+
let read_result =
63+
timeout(Duration::from_millis(MARGIN_MS), zombie.read_to_end(&mut remainder)).await;
64+
assert!(
65+
read_result.is_ok(),
66+
"Server should have closed the zombie connection after keepalive timeout, but the \
67+
connection is still open"
68+
);
69+
}

0 commit comments

Comments
 (0)