Skip to content

Commit 6db2c6a

Browse files
apollo_integration_tests: add restart service on single node test (#10456)
1 parent 9161564 commit 6db2c6a

File tree

7 files changed

+141
-15
lines changed

7 files changed

+141
-15
lines changed

crates/apollo_infra_utils/src/test_utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub enum TestIdentifier {
3636
PositiveFlowIntegrationTest,
3737
RestartFlowIntegrationTest,
3838
RestartServiceMultipleNodesFlowIntegrationTest,
39+
RestartServiceSingleNodeFlowIntegrationTest,
3940
RevertFlowIntegrationTest,
4041
SystemTestDumpSingleNodeConfig,
4142
HttpServerUnitTests,

crates/apollo_integration_tests/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ path = "src/bin/sequencer_node_end_to_end_integration_tests/integration_test_res
100100
name = "integration_test_restart_service_multiple_nodes_flow"
101101
path = "src/bin/sequencer_node_end_to_end_integration_tests/integration_test_restart_service_multiple_nodes_flow.rs"
102102

103+
[[bin]]
104+
name = "integration_test_restart_service_single_node_flow"
105+
path = "src/bin/sequencer_node_end_to_end_integration_tests/integration_test_restart_service_single_node_flow.rs"
106+
103107
[[bin]]
104108
name = "integration_test_revert_flow"
105109
path = "src/bin/sequencer_node_end_to_end_integration_tests/integration_test_revert_flow.rs"

crates/apollo_integration_tests/src/bin/sequencer_node_end_to_end_integration_tests/integration_test_restart_flow.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use apollo_integration_tests::integration_test_manager::{
99
};
1010
use apollo_integration_tests::integration_test_utils::integration_test_setup;
1111
use strum::IntoEnumIterator;
12-
use tokio::select;
1312
use tracing::info;
1413

1514
#[tokio::main]
@@ -74,11 +73,6 @@ async fn main() {
7473
// Create a simulator for sustained transaction sending.
7574
let simulator = integration_test_manager.create_simulator();
7675
let mut tx_generator = integration_test_manager.tx_generator().snapshot();
77-
// TODO(noamsp/itay): Try to refactor this test to spawn threads for each task instead of using
78-
// select!
79-
// Task that sends sustained transactions without ever finishing.
80-
let continuous_tx_sending_task =
81-
simulator.run_simulation(&mut tx_generator, true, DEFAULT_SENDER_ACCOUNT);
8276

8377
// Task that awaits transactions and restarts nodes in phases.
8478
let await_and_restart_nodes_task = async {
@@ -116,15 +110,13 @@ async fn main() {
116110
integration_test_manager.poll_all_running_nodes_received_more_txs(LONG_TIMEOUT).await;
117111
};
118112

119-
select! {
120-
_ = continuous_tx_sending_task => {
121-
panic!("This task should never complete");
122-
}
123-
_ = await_and_restart_nodes_task => {
124-
// If await_and_restart_nodes_task completes normally, it finished successfully.
125-
// If it panicked, the panic would have already propagated.
126-
}
127-
}
113+
simulator
114+
.run_test_with_nonstop_tx_sending(
115+
&mut tx_generator,
116+
DEFAULT_SENDER_ACCOUNT,
117+
await_and_restart_nodes_task,
118+
)
119+
.await;
128120

129121
integration_test_manager.shutdown_nodes(node_indices);
130122
info!("Restart flow integration test completed successfully!");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
use std::collections::HashMap;
2+
use std::time::Duration;
3+
4+
use apollo_deployments::deployments::hybrid::HybridNodeServiceName;
5+
use apollo_infra_utils::test_utils::TestIdentifier;
6+
use apollo_integration_tests::integration_test_manager::{
7+
IntegrationTestManager,
8+
DEFAULT_SENDER_ACCOUNT,
9+
};
10+
use apollo_integration_tests::integration_test_utils::integration_test_setup;
11+
use strum::IntoEnumIterator;
12+
use tracing::info;
13+
14+
#[tokio::main]
15+
async fn main() {
16+
integration_test_setup("restart_service_single_node").await;
17+
const TIMEOUT: Duration = Duration::from_secs(30);
18+
const LONG_TIMEOUT: Duration = Duration::from_secs(90);
19+
/// The number of consolidated local sequencers that participate in the test.
20+
const N_CONSOLIDATED_SEQUENCERS: usize = 0;
21+
/// The number of distributed remote sequencers that participate in the test.
22+
const N_DISTRIBUTED_SEQUENCERS: usize = 0;
23+
/// The number of hybrid sequencers that participate in the test.
24+
const N_HYBRID_SEQUENCERS: usize = 3;
25+
// The indices of the nodes that we will be shutting down.
26+
// The test restarts a hybrid node's service and shuts down a non-consolidated
27+
// (hybrid/distributed) node.
28+
const RESTART_NODE: usize = N_HYBRID_SEQUENCERS - 1;
29+
30+
// Get the sequencer configurations.
31+
let mut integration_test_manager = IntegrationTestManager::new(
32+
N_CONSOLIDATED_SEQUENCERS,
33+
N_DISTRIBUTED_SEQUENCERS,
34+
N_HYBRID_SEQUENCERS,
35+
None,
36+
TestIdentifier::RestartServiceSingleNodeFlowIntegrationTest,
37+
)
38+
.await;
39+
40+
// Assert that RESTART_NODE is a hybrid node.
41+
assert_eq!(
42+
integration_test_manager
43+
.get_idle_nodes()
44+
.get(&RESTART_NODE)
45+
.unwrap()
46+
.get_executables()
47+
.len(),
48+
HybridNodeServiceName::iter().count()
49+
);
50+
51+
let node_indices = integration_test_manager.get_node_indices();
52+
integration_test_manager.run_nodes(node_indices.clone()).await;
53+
54+
integration_test_manager.send_deploy_and_invoke_txs_and_verify().await;
55+
56+
integration_test_manager.send_declare_txs_and_verify().await;
57+
58+
// Create a simulator for sustained transaction sending.
59+
let simulator = integration_test_manager.create_simulator();
60+
let mut tx_generator = integration_test_manager.tx_generator().snapshot();
61+
62+
// The indices of the nodes that are healthy throughout the test.
63+
let mut healthy_node_indices = node_indices.clone();
64+
healthy_node_indices.remove(&RESTART_NODE);
65+
// Task that awaits transactions and restarts nodes in phases.
66+
let await_and_restart_nodes_task = async {
67+
for hybrid_node_service in HybridNodeServiceName::iter() {
68+
// TODO(noamsp): Remove this once the equivocaton feature is merged.
69+
if hybrid_node_service == HybridNodeServiceName::Core {
70+
continue;
71+
}
72+
73+
info!("Shutting down service {hybrid_node_service:?} for node {RESTART_NODE}.");
74+
let restart_node_service =
75+
HashMap::from([(RESTART_NODE, vec![hybrid_node_service.into()])]);
76+
integration_test_manager.shutdown_node_services(restart_node_service.clone());
77+
78+
// Verify that the other nodes are still running properly.
79+
integration_test_manager
80+
.poll_running_nodes_received_more_txs(TIMEOUT, &healthy_node_indices)
81+
.await;
82+
83+
info!("Running service {hybrid_node_service:?} for node {RESTART_NODE}.");
84+
integration_test_manager.run_node_services(restart_node_service.clone()).await;
85+
86+
integration_test_manager
87+
.poll_node_reaches_consensus_decisions_after_restart(RESTART_NODE, LONG_TIMEOUT)
88+
.await;
89+
90+
integration_test_manager.poll_all_running_nodes_received_more_txs(LONG_TIMEOUT).await;
91+
}
92+
};
93+
94+
simulator
95+
.run_test_with_nonstop_tx_sending(
96+
&mut tx_generator,
97+
DEFAULT_SENDER_ACCOUNT,
98+
await_and_restart_nodes_task,
99+
)
100+
.await;
101+
102+
integration_test_manager.shutdown_nodes(node_indices);
103+
info!("Restart service single node flow integration test completed successfully!");
104+
}

crates/apollo_integration_tests/src/sequencer_simulator_utils.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::future::Future;
12
use std::net::{SocketAddr, ToSocketAddrs};
23
use std::time::Duration;
34

@@ -6,6 +7,7 @@ use apollo_monitoring_endpoint::test_utils::MonitoringClient;
67
use mempool_test_utils::starknet_api_test_utils::{AccountId, MultiAccountTransactionGenerator};
78
use starknet_api::rpc_transaction::RpcTransaction;
89
use starknet_api::transaction::TransactionHash;
10+
use tokio::select;
911
use tokio::time::sleep;
1012
use tracing::info;
1113
use url::Url;
@@ -117,6 +119,26 @@ impl SequencerSimulator {
117119
i += 1;
118120
}
119121
}
122+
123+
pub async fn run_test_with_nonstop_tx_sending(
124+
&self,
125+
tx_generator: &mut MultiAccountTransactionGenerator,
126+
sender_account: AccountId,
127+
test_future: impl Future<Output = ()>,
128+
) {
129+
// TODO(noamsp/itay): Try to refactor this to spawn threads for each task instead of using
130+
// select!
131+
let simulation_task = self.run_simulation(tx_generator, true, sender_account);
132+
select! {
133+
_ = simulation_task => {
134+
panic!("Simulation task should not complete before the test task");
135+
}
136+
_ = test_future => {
137+
// If test_future completes normally, it finished successfully.
138+
// If it panicked, the panic would have already propagated.
139+
}
140+
}
141+
}
120142
}
121143

122144
fn get_socket_addr(url_str: &str, port: u16) -> Result<SocketAddr, Box<dyn std::error::Error>> {

scripts/run_tests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"integration_test_positive_flow",
2525
"integration_test_restart_flow",
2626
"integration_test_restart_service_multiple_nodes_flow",
27+
"integration_test_restart_service_single_node_flow",
2728
"integration_test_revert_flow",
2829
"integration_test_central_and_p2p_sync_flow",
2930
]

scripts/sequencer_integration_test.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# - "positive" to run the positive flow test,
1010
# - "restart" to run the restart flow test,
1111
# - "restart_multiple_nodes" to run the restart flow test with multiple nodes,
12+
# - "restart_single_node" to run the restart flow test with a single node,
1213
# - "revert" to run the revert flow test,
1314
# - "sync" to run the central and p2p sync flow test,
1415
# - "all" to run all tests.
@@ -22,6 +23,7 @@ declare -A TEST_ALIASES=(
2223
[positive]="integration_test_positive_flow"
2324
[restart]="integration_test_restart_flow"
2425
[restart_multiple_nodes]="integration_test_restart_service_multiple_nodes_flow"
26+
[restart_single_node]="integration_test_restart_service_single_node_flow"
2527
[revert]="integration_test_revert_flow"
2628
[sync]="integration_test_central_and_p2p_sync_flow"
2729
)

0 commit comments

Comments
 (0)