Skip to content

Commit 1ca63c1

Browse files
committed
Simplify cluster sandbox API
1 parent ddf8cf9 commit 1ca63c1

File tree

8 files changed

+74
-108
lines changed

8 files changed

+74
-108
lines changed

quickwit/quickwit-integration-tests/src/test_utils/cluster_sandbox.rs

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -60,31 +60,12 @@ pub struct TestNodeConfig {
6060
pub enable_otlp: bool,
6161
}
6262

63-
/// A test environment where you can start a Quickwit cluster and use the gRPC
64-
/// or REST clients to test it.
65-
pub struct ClusterSandbox {
66-
pub node_configs: Vec<(NodeConfig, HashSet<QuickwitService>)>,
67-
pub searcher_rest_client: QuickwitClient,
68-
pub indexer_rest_client: QuickwitClient,
69-
pub trace_client: TraceServiceClient<tonic::transport::Channel>,
70-
pub logs_client: LogsServiceClient<tonic::transport::Channel>,
71-
pub jaeger_client: SpanReaderPluginClient<tonic::transport::Channel>,
72-
_temp_dir: TempDir,
73-
node_shutdown_handles: Vec<NodeShutdownHandle>,
74-
}
75-
76-
pub struct ClusterSandboxConfig {
77-
temp_dir: TempDir,
78-
node_configs: Vec<(NodeConfig, HashSet<QuickwitService>)>,
79-
tcp_listener_resolver: TestTcpListenerResolver,
80-
}
81-
82-
pub struct ClusterSandboxConfigBuilder {
63+
pub struct ClusterSandboxBuilder {
8364
temp_dir: TempDir,
8465
node_configs: Vec<TestNodeConfig>,
8566
}
8667

87-
impl Default for ClusterSandboxConfigBuilder {
68+
impl Default for ClusterSandboxBuilder {
8869
fn default() -> Self {
8970
Self {
9071
temp_dir: tempfile::tempdir().unwrap(),
@@ -93,7 +74,7 @@ impl Default for ClusterSandboxConfigBuilder {
9374
}
9475
}
9576

96-
impl ClusterSandboxConfigBuilder {
77+
impl ClusterSandboxBuilder {
9778
pub fn add_node(mut self, services: impl IntoIterator<Item = QuickwitService>) -> Self {
9879
self.node_configs.push(TestNodeConfig {
9980
services: HashSet::from_iter(services),
@@ -113,14 +94,6 @@ impl ClusterSandboxConfigBuilder {
11394
self
11495
}
11596

116-
/// Builds a config that runs all the services in a single process
117-
pub async fn build_standalone() -> ClusterSandboxConfig {
118-
ClusterSandboxConfigBuilder::default()
119-
.add_node(QuickwitService::supported_services())
120-
.build()
121-
.await
122-
}
123-
12497
/// Builds a list of of [`NodeConfig`] from the node definitions added to
12598
/// builder. For each node, a [`NodeConfig`] is built with the right
12699
/// parameters such that we will be able to run `quickwit_serve` on them and
@@ -129,7 +102,7 @@ impl ClusterSandboxConfigBuilder {
129102
/// - `metastore_uri` defined by `root_data_dir/metastore`.
130103
/// - `default_index_root_uri` defined by `root_data_dir/indexes`.
131104
/// - `peers` defined by others nodes `gossip_advertise_addr`.
132-
pub async fn build(self) -> ClusterSandboxConfig {
105+
async fn build_config(self) -> ResolvedClusterConfig {
133106
let root_data_dir = self.temp_dir.path().to_path_buf();
134107
let cluster_id = new_coolid("test-cluster");
135108
let mut resolved_node_configs = Vec::new();
@@ -166,15 +139,36 @@ impl ClusterSandboxConfigBuilder {
166139
.filter(|seed| *seed != node_config.0.gossip_advertise_addr.to_string())
167140
.collect_vec();
168141
}
169-
ClusterSandboxConfig {
142+
ResolvedClusterConfig {
170143
temp_dir: self.temp_dir,
171144
node_configs: resolved_node_configs,
172145
tcp_listener_resolver,
173146
}
174147
}
148+
149+
pub async fn build_and_start(self) -> ClusterSandbox {
150+
self.build_config().await.start().await
151+
}
152+
153+
pub async fn build_and_start_standalone() -> ClusterSandbox {
154+
ClusterSandboxBuilder::default()
155+
.add_node(QuickwitService::supported_services())
156+
.build_config()
157+
.await
158+
.start()
159+
.await
160+
}
161+
}
162+
163+
/// Intermediate state where the ports of all the the test cluster nodes have
164+
/// been reserved and the configurations have been generated.
165+
struct ResolvedClusterConfig {
166+
temp_dir: TempDir,
167+
node_configs: Vec<(NodeConfig, HashSet<QuickwitService>)>,
168+
tcp_listener_resolver: TestTcpListenerResolver,
175169
}
176170

177-
impl ClusterSandboxConfig {
171+
impl ResolvedClusterConfig {
178172
/// Start a cluster using this config and waits for the nodes to be ready
179173
pub async fn start(self) -> ClusterSandbox {
180174
let mut node_shutdown_handles = Vec::new();
@@ -301,6 +295,19 @@ pub(crate) async fn ingest_with_retry(
301295
Ok(())
302296
}
303297

298+
/// A test environment where you can start a Quickwit cluster and use the gRPC
299+
/// or REST clients to test it.
300+
pub struct ClusterSandbox {
301+
pub node_configs: Vec<(NodeConfig, HashSet<QuickwitService>)>,
302+
pub searcher_rest_client: QuickwitClient,
303+
pub indexer_rest_client: QuickwitClient,
304+
pub trace_client: TraceServiceClient<tonic::transport::Channel>,
305+
pub logs_client: LogsServiceClient<tonic::transport::Channel>,
306+
pub jaeger_client: SpanReaderPluginClient<tonic::transport::Channel>,
307+
_temp_dir: TempDir,
308+
node_shutdown_handles: Vec<NodeShutdownHandle>,
309+
}
310+
304311
impl ClusterSandbox {
305312
pub fn enable_ingest_v2(&mut self) {
306313
self.indexer_rest_client.enable_ingest_v2();

quickwit/quickwit-integration-tests/src/test_utils/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@
2020
mod cluster_sandbox;
2121
mod shutdown;
2222

23-
pub(crate) use cluster_sandbox::{ingest_with_retry, ClusterSandbox, ClusterSandboxConfigBuilder};
23+
pub(crate) use cluster_sandbox::{ingest_with_retry, ClusterSandbox, ClusterSandboxBuilder};

quickwit/quickwit-integration-tests/src/tests/basic_tests.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use quickwit_rest_client::models::IngestSource;
2727
use quickwit_rest_client::rest_client::CommitType;
2828
use quickwit_serve::SearchRequestQueryString;
2929

30-
use crate::test_utils::{ingest_with_retry, ClusterSandboxConfigBuilder};
30+
use crate::test_utils::{ingest_with_retry, ClusterSandboxBuilder};
3131

3232
fn get_ndjson_filepath(ndjson_dataset_filename: &str) -> String {
3333
format!(
@@ -40,10 +40,7 @@ fn get_ndjson_filepath(ndjson_dataset_filename: &str) -> String {
4040
#[tokio::test]
4141
async fn test_ui_redirect_on_get() {
4242
quickwit_common::setup_logging_for_tests();
43-
let sandbox = ClusterSandboxConfigBuilder::build_standalone()
44-
.await
45-
.start()
46-
.await;
43+
let sandbox = ClusterSandboxBuilder::build_and_start_standalone().await;
4744
let node_config = sandbox.node_configs.first().unwrap();
4845
let client = hyper::Client::builder()
4946
.pool_idle_timeout(Duration::from_secs(30))
@@ -67,10 +64,7 @@ async fn test_ui_redirect_on_get() {
6764
#[tokio::test]
6865
async fn test_standalone_server() {
6966
quickwit_common::setup_logging_for_tests();
70-
let sandbox = ClusterSandboxConfigBuilder::build_standalone()
71-
.await
72-
.start()
73-
.await;
67+
let sandbox = ClusterSandboxBuilder::build_and_start_standalone().await;
7468
{
7569
// The indexing service should be running.
7670
let counters = sandbox
@@ -127,15 +121,13 @@ async fn test_standalone_server() {
127121
#[tokio::test]
128122
async fn test_multi_nodes_cluster() {
129123
quickwit_common::setup_logging_for_tests();
130-
let sandbox = ClusterSandboxConfigBuilder::default()
124+
let sandbox = ClusterSandboxBuilder::default()
131125
.add_node([QuickwitService::Searcher])
132126
.add_node([QuickwitService::Metastore])
133127
.add_node([QuickwitService::Indexer])
134128
.add_node([QuickwitService::ControlPlane])
135129
.add_node([QuickwitService::Janitor])
136-
.build()
137-
.await
138-
.start()
130+
.build_and_start()
139131
.await;
140132

141133
{

quickwit/quickwit-integration-tests/src/tests/ingest_tests.rs

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use quickwit_rest_client::rest_client::CommitType;
2828
use serde_json::json;
2929

3030
use crate::ingest_json;
31-
use crate::test_utils::{ingest_with_retry, ClusterSandboxConfigBuilder};
31+
use crate::test_utils::{ingest_with_retry, ClusterSandboxBuilder};
3232

3333
fn initialize_tests() {
3434
quickwit_common::setup_logging_for_tests();
@@ -38,10 +38,7 @@ fn initialize_tests() {
3838
#[tokio::test]
3939
async fn test_single_node_cluster() {
4040
initialize_tests();
41-
let mut sandbox = ClusterSandboxConfigBuilder::build_standalone()
42-
.await
43-
.start()
44-
.await;
41+
let mut sandbox = ClusterSandboxBuilder::build_and_start_standalone().await;
4542
let index_id = "test-single-node-cluster";
4643
let index_config = format!(
4744
r#"
@@ -204,17 +201,15 @@ async fn test_single_node_cluster() {
204201
#[tokio::test]
205202
async fn test_ingest_v2_index_not_found() {
206203
initialize_tests();
207-
let mut sandbox = ClusterSandboxConfigBuilder::default()
204+
let mut sandbox = ClusterSandboxBuilder::default()
208205
.add_node([QuickwitService::Indexer, QuickwitService::Janitor])
209206
.add_node([QuickwitService::Indexer, QuickwitService::Janitor])
210207
.add_node([
211208
QuickwitService::ControlPlane,
212209
QuickwitService::Metastore,
213210
QuickwitService::Searcher,
214211
])
215-
.build()
216-
.await
217-
.start()
212+
.build_and_start()
218213
.await;
219214
sandbox.enable_ingest_v2();
220215
let missing_index_err: Error = sandbox
@@ -241,17 +236,15 @@ async fn test_ingest_v2_index_not_found() {
241236
#[tokio::test]
242237
async fn test_ingest_v2_happy_path() {
243238
initialize_tests();
244-
let mut sandbox = ClusterSandboxConfigBuilder::default()
239+
let mut sandbox = ClusterSandboxBuilder::default()
245240
.add_node([QuickwitService::Indexer, QuickwitService::Janitor])
246241
.add_node([QuickwitService::Indexer, QuickwitService::Janitor])
247242
.add_node([
248243
QuickwitService::ControlPlane,
249244
QuickwitService::Metastore,
250245
QuickwitService::Searcher,
251246
])
252-
.build()
253-
.await
254-
.start()
247+
.build_and_start()
255248
.await;
256249
sandbox.enable_ingest_v2();
257250
let index_id = "test_happy_path";
@@ -326,10 +319,7 @@ async fn test_ingest_v2_happy_path() {
326319
#[tokio::test]
327320
async fn test_commit_modes() {
328321
initialize_tests();
329-
let sandbox = ClusterSandboxConfigBuilder::build_standalone()
330-
.await
331-
.start()
332-
.await;
322+
let sandbox = ClusterSandboxBuilder::build_and_start_standalone().await;
333323
let index_id = "test_commit_modes";
334324
let index_config = format!(
335325
r#"
@@ -411,15 +401,13 @@ async fn test_commit_modes() {
411401
#[tokio::test]
412402
async fn test_very_large_index_name() {
413403
initialize_tests();
414-
let mut sandbox = ClusterSandboxConfigBuilder::default()
404+
let mut sandbox = ClusterSandboxBuilder::default()
415405
.add_node([QuickwitService::Searcher])
416406
.add_node([QuickwitService::Metastore])
417407
.add_node([QuickwitService::Indexer])
418408
.add_node([QuickwitService::ControlPlane])
419409
.add_node([QuickwitService::Janitor])
420-
.build()
421-
.await
422-
.start()
410+
.build_and_start()
423411
.await;
424412
sandbox.enable_ingest_v2();
425413

@@ -512,10 +500,7 @@ async fn test_very_large_index_name() {
512500
#[tokio::test]
513501
async fn test_shutdown_single_node() {
514502
initialize_tests();
515-
let mut sandbox = ClusterSandboxConfigBuilder::build_standalone()
516-
.await
517-
.start()
518-
.await;
503+
let mut sandbox = ClusterSandboxBuilder::build_and_start_standalone().await;
519504
let index_id = "test_shutdown_single_node";
520505

521506
sandbox.enable_ingest_v2();
@@ -577,17 +562,15 @@ async fn test_shutdown_single_node() {
577562
#[tokio::test]
578563
async fn test_shutdown_control_plane_early_shutdown() {
579564
initialize_tests();
580-
let sandbox = ClusterSandboxConfigBuilder::default()
565+
let sandbox = ClusterSandboxBuilder::default()
581566
.add_node([QuickwitService::Indexer])
582567
.add_node([
583568
QuickwitService::ControlPlane,
584569
QuickwitService::Searcher,
585570
QuickwitService::Metastore,
586571
QuickwitService::Janitor,
587572
])
588-
.build()
589-
.await
590-
.start()
573+
.build_and_start()
591574
.await;
592575
let index_id = "test_shutdown_separate_indexer";
593576

@@ -638,17 +621,15 @@ async fn test_shutdown_control_plane_early_shutdown() {
638621
#[tokio::test]
639622
async fn test_shutdown_separate_indexer() {
640623
initialize_tests();
641-
let sandbox = ClusterSandboxConfigBuilder::default()
624+
let sandbox = ClusterSandboxBuilder::default()
642625
.add_node([QuickwitService::Indexer])
643626
.add_node([
644627
QuickwitService::ControlPlane,
645628
QuickwitService::Searcher,
646629
QuickwitService::Metastore,
647630
QuickwitService::Janitor,
648631
])
649-
.build()
650-
.await
651-
.start()
632+
.build_and_start()
652633
.await;
653634
let index_id = "test_shutdown_separate_indexer";
654635

quickwit/quickwit-integration-tests/src/tests/otlp_tests.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use quickwit_proto::opentelemetry::proto::logs::v1::{LogRecord, ResourceLogs, Sc
3737
use quickwit_proto::opentelemetry::proto::trace::v1::{ResourceSpans, ScopeSpans, Span};
3838
use tonic::codec::CompressionEncoding;
3939

40-
use crate::test_utils::ClusterSandboxConfigBuilder;
40+
use crate::test_utils::ClusterSandboxBuilder;
4141

4242
fn initialize_tests() {
4343
quickwit_common::setup_logging_for_tests();
@@ -47,15 +47,13 @@ fn initialize_tests() {
4747
#[tokio::test]
4848
async fn test_ingest_traces_with_otlp_grpc_api() {
4949
initialize_tests();
50-
let mut sandbox = ClusterSandboxConfigBuilder::default()
50+
let mut sandbox = ClusterSandboxBuilder::default()
5151
.add_node([QuickwitService::Searcher])
5252
.add_node([QuickwitService::Metastore])
5353
.add_node_with_otlp([QuickwitService::Indexer])
5454
.add_node([QuickwitService::ControlPlane])
5555
.add_node([QuickwitService::Janitor])
56-
.build()
57-
.await
58-
.start()
56+
.build_and_start()
5957
.await;
6058
// Wait for the pipelines to start (one for logs and one for traces)
6159
sandbox.wait_for_indexing_pipelines(2).await.unwrap();
@@ -142,15 +140,13 @@ async fn test_ingest_traces_with_otlp_grpc_api() {
142140
#[tokio::test]
143141
async fn test_ingest_logs_with_otlp_grpc_api() {
144142
initialize_tests();
145-
let mut sandbox = ClusterSandboxConfigBuilder::default()
143+
let mut sandbox = ClusterSandboxBuilder::default()
146144
.add_node([QuickwitService::Searcher])
147145
.add_node([QuickwitService::Metastore])
148146
.add_node_with_otlp([QuickwitService::Indexer])
149147
.add_node([QuickwitService::ControlPlane])
150148
.add_node([QuickwitService::Janitor])
151-
.build()
152-
.await
153-
.start()
149+
.build_and_start()
154150
.await;
155151
// Wait fo the pipelines to start (one for logs and one for traces)
156152
sandbox.wait_for_indexing_pipelines(2).await.unwrap();
@@ -218,15 +214,13 @@ async fn test_ingest_logs_with_otlp_grpc_api() {
218214
#[tokio::test]
219215
async fn test_jaeger_api() {
220216
initialize_tests();
221-
let mut sandbox = ClusterSandboxConfigBuilder::default()
217+
let mut sandbox = ClusterSandboxBuilder::default()
222218
.add_node([QuickwitService::Searcher])
223219
.add_node([QuickwitService::Metastore])
224220
.add_node_with_otlp([QuickwitService::Indexer])
225221
.add_node([QuickwitService::ControlPlane])
226222
.add_node([QuickwitService::Janitor])
227-
.build()
228-
.await
229-
.start()
223+
.build_and_start()
230224
.await;
231225
// Wait fo the pipelines to start (one for logs and one for traces)
232226
sandbox.wait_for_indexing_pipelines(2).await.unwrap();

0 commit comments

Comments
 (0)