From f36b483459c3e8bfa92f7c7cc110c36c5f5647c2 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Fri, 26 Jul 2024 17:20:25 +0530 Subject: [PATCH] update: Replaced Build_Config Fixture with TestConfigBuilder --- crates/orchestrator/src/config.rs | 115 ++++++++++++++++++ crates/orchestrator/src/tests/common/mod.rs | 37 +----- .../src/tests/data_storage/mod.rs | 5 +- crates/orchestrator/src/tests/database/mod.rs | 16 +-- 4 files changed, 123 insertions(+), 50 deletions(-) diff --git a/crates/orchestrator/src/config.rs b/crates/orchestrator/src/config.rs index 55761526..828df754 100644 --- a/crates/orchestrator/src/config.rs +++ b/crates/orchestrator/src/config.rs @@ -183,3 +183,118 @@ pub async fn build_storage_client() -> Box { _ => panic!("Unsupported Storage Client"), } } + +#[cfg(test)] +use httpmock::MockServer; + +// Inspiration : https://rust-unofficial.github.io/patterns/patterns/creational/builder.html +// TestConfigBuilder allows to heavily customise the global configs based on the test's requirement. +// Eg: We want to mock only the da client and leave rest to be as it is, use mock_da_client. + +// TestBuilder for Config +#[cfg(test)] +pub struct TestConfigBuilder { + /// The starknet client to get data from the node + starknet_client: Option>>, + /// The DA client to interact with the DA layer + da_client: Option>, + /// The service that produces proof and registers it onchain + prover_client: Option>, + /// Settlement client + settlement_client: Option>, + /// The database client + database: Option>, + /// Queue client + queue: Option>, + /// Storage client + storage: Option>, +} + +#[cfg(test)] +impl Default for TestConfigBuilder { + fn default() -> Self { + Self::new() + } +} + +#[cfg(test)] +impl TestConfigBuilder { + /// Create a new config + pub fn new() -> TestConfigBuilder { + TestConfigBuilder { + starknet_client: None, + da_client: None, + prover_client: None, + settlement_client: None, + database: None, + queue: None, + storage: None, + } + } + + pub fn mock_da_client(mut self, da_client: Box) -> TestConfigBuilder { + self.da_client = Some(da_client); + self + } + + pub async fn build(mut self) -> MockServer { + dotenv().ok(); + + // init starknet client + if self.starknet_client.is_none() { + let provider = JsonRpcClient::new(HttpTransport::new( + Url::parse(get_env_var_or_panic("MADARA_RPC_URL").as_str()).expect("Failed to parse URL"), + )); + self.starknet_client = Some(Arc::new(provider)); + } + + // init database + if self.database.is_none() { + self.database = Some(Box::new(MongoDb::new(MongoDbConfig::new_from_env()).await)); + } + + // init queue + if self.queue.is_none() { + self.queue = Some(Box::new(SqsQueue {})); + } + + // init the DA client + if self.da_client.is_none() { + self.da_client = Some(build_da_client().await); + } + + let settings_provider = DefaultSettingsProvider {}; + + // init the Settings client + if self.settlement_client.is_none() { + self.settlement_client = Some(build_settlement_client(&settings_provider).await); + } + + // init the Prover client + if self.prover_client.is_none() { + self.prover_client = Some(build_prover_service(&settings_provider)); + } + + // init the storage client + if self.storage.is_none() { + self.storage = Some(build_storage_client().await); + } + + // return config and server as tuple + let config = Config::new( + self.starknet_client.unwrap(), + self.da_client.unwrap(), + self.prover_client.unwrap(), + self.settlement_client.unwrap(), + self.database.unwrap(), + self.queue.unwrap(), + self.storage.unwrap(), + ); + + config_force_init(config).await; + + let server = MockServer::connect(get_env_var_or_panic("MADARA_RPC_URL").as_str()); + + server + } +} diff --git a/crates/orchestrator/src/tests/common/mod.rs b/crates/orchestrator/src/tests/common/mod.rs index 0a97fa33..96337c68 100644 --- a/crates/orchestrator/src/tests/common/mod.rs +++ b/crates/orchestrator/src/tests/common/mod.rs @@ -13,10 +13,8 @@ use settlement_client_interface::MockSettlementClient; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; use url::Url; -use utils::env_utils::get_env_var_or_panic; -use utils::settings::default::DefaultSettingsProvider; -use crate::config::{build_storage_client, config_force_init, Config}; +use crate::config::Config; use crate::data_storage::MockDataStorage; use crate::database::mongodb::config::MongoDbConfig; use crate::database::mongodb::MongoDb; @@ -80,39 +78,6 @@ pub fn custom_job_item(default_job_item: JobItem, #[default(String::from("0"))] job_item } -/// For implementation of integration tests -#[fixture] -pub async fn build_config() -> color_eyre::Result<()> { - // Getting .env.test variables - dotenvy::from_filename("../.env.test")?; - - // init starknet client - let provider = JsonRpcClient::new(HttpTransport::new( - Url::parse(get_env_var_or_panic("MADARA_RPC_URL").as_str()).expect("Failed to parse URL"), - )); - - // init database - let database = Box::new(MongoDb::new(MongoDbConfig::new_from_env()).await); - - // init the queue - let queue = Box::new(crate::queue::sqs::SqsQueue {}); - - let da_client = crate::config::build_da_client().await; - let settings_provider = DefaultSettingsProvider {}; - let settlement_client = crate::config::build_settlement_client(&settings_provider).await; - let prover_client = crate::config::build_prover_service(&settings_provider); - let storage_client = build_storage_client().await; - - // building a test bucket : - storage_client.build_test_bucket(&get_env_var_or_panic("AWS_S3_BUCKET_NAME")).await?; - - let config = - Config::new(Arc::new(provider), da_client, prover_client, settlement_client, database, queue, storage_client); - config_force_init(config).await; - - Ok(()) -} - pub async fn drop_database() -> color_eyre::Result<()> { let db_client: Client = MongoDb::new(MongoDbConfig::new_from_env()).await.client(); // dropping `jobs` collection. diff --git a/crates/orchestrator/src/tests/data_storage/mod.rs b/crates/orchestrator/src/tests/data_storage/mod.rs index ef1dd0ec..1fdb73f3 100644 --- a/crates/orchestrator/src/tests/data_storage/mod.rs +++ b/crates/orchestrator/src/tests/data_storage/mod.rs @@ -1,7 +1,7 @@ +use crate::config::TestConfigBuilder; use crate::data_storage::aws_s3::config::AWSS3Config; use crate::data_storage::aws_s3::AWSS3; use crate::data_storage::{DataStorage, DataStorageConfig}; -use crate::tests::common::build_config; use bytes::Bytes; use rstest::rstest; use serde_json::json; @@ -9,7 +9,8 @@ use serde_json::json; #[rstest] #[tokio::test] async fn test_put_and_get_data_s3() -> color_eyre::Result<()> { - build_config().await?; + TestConfigBuilder::new().build().await; + dotenvy::from_filename("../.env.test")?; let config = AWSS3Config::new_from_env(); diff --git a/crates/orchestrator/src/tests/database/mod.rs b/crates/orchestrator/src/tests/database/mod.rs index 5e8a651c..9e9e3dea 100644 --- a/crates/orchestrator/src/tests/database/mod.rs +++ b/crates/orchestrator/src/tests/database/mod.rs @@ -1,18 +1,13 @@ -use crate::config::config; +use crate::config::{config, TestConfigBuilder}; use crate::jobs::types::{ExternalId, JobItem, JobStatus, JobType}; -use crate::tests::common::{build_config, drop_database}; -use color_eyre::eyre::eyre; +use crate::tests::common::drop_database; use rstest::*; use uuid::Uuid; #[rstest] #[tokio::test] async fn test_database_connection() -> color_eyre::Result<()> { - let init_config_error = build_config().await.is_err(); - if init_config_error { - return Err(eyre!("Not able to init config.")); - } - + TestConfigBuilder::new().build().await; Ok(()) } @@ -21,10 +16,7 @@ async fn test_database_connection() -> color_eyre::Result<()> { #[rstest] #[tokio::test] async fn test_database_create_job() -> color_eyre::Result<()> { - let init_config = build_config().await.is_ok(); - if !init_config { - return Err(eyre!("Not able to init config.")); - } + TestConfigBuilder::new().build().await; drop_database().await.unwrap();