From 29fce7b17cd7f1f8e6afd8d30273d9e96c8f551b Mon Sep 17 00:00:00 2001 From: Simon Popugaev Date: Mon, 5 Feb 2024 16:19:45 +0300 Subject: [PATCH] tests with no docker --- tests/context.rs | 38 +++++++-- tests/context/db.rs | 143 ++++++++++++++++++++++++--------- tests/context/golem_service.rs | 8 +- tests/worker.rs | 13 +-- 4 files changed, 141 insertions(+), 61 deletions(-) diff --git a/tests/context.rs b/tests/context.rs index 759ebe9..f041507 100644 --- a/tests/context.rs +++ b/tests/context.rs @@ -4,7 +4,7 @@ pub mod redis; pub mod shard_manager; pub mod worker; -use crate::context::db::{DbInfo, Postgres}; +use crate::context::db::{Db, DbInfo}; use crate::context::golem_service::{GolemService, GolemServiceInfo}; use crate::context::redis::{Redis, RedisInfo}; use crate::context::shard_manager::{ShardManager, ShardManagerInfo}; @@ -24,6 +24,26 @@ pub struct EnvConfig { pub redis_key_prefix: String, pub wasi_root: PathBuf, pub local_golem: bool, + pub db_type: DbType, +} + +#[derive(Debug, Clone)] +pub enum DbType { + Postgres, + Sqlite, +} + +impl DbType { + pub fn from_env() -> DbType { + let db_type_str = std::env::var("GOLEM_TEST_DB") + .unwrap_or("".to_string()) + .to_lowercase(); + if db_type_str == "sqlite" { + DbType::Sqlite + } else { + DbType::Postgres + } + } } impl EnvConfig { @@ -37,13 +57,14 @@ impl EnvConfig { std::env::var("GOLEM_TEST_TEMPLATES").unwrap_or("../test-templates".to_string()), ), local_golem: std::env::var("GOLEM_DOCKER_SERVICES").is_err(), + db_type: DbType::from_env(), } } } pub struct Context<'docker_client> { env: EnvConfig, - postgres: Postgres<'docker_client>, + db: Db<'docker_client>, redis: Redis<'docker_client>, shard_manager: ShardManager<'docker_client>, golem_service: GolemService<'docker_client>, @@ -53,11 +74,14 @@ pub struct Context<'docker_client> { impl Context<'_> { pub fn start(docker: &clients::Cli) -> Result { let env_config = EnvConfig::from_env(); - let postgres = Postgres::start(docker, &env_config)?; + + println!("Starting context with env config: {env_config:?}"); + + let db = Db::start(docker, &env_config)?; let redis = Redis::make(docker, &env_config)?; let shard_manager = ShardManager::start(docker, &env_config, &redis.info())?; let golem_service = - GolemService::start(docker, &env_config, &shard_manager.info(), &postgres.info())?; + GolemService::start(docker, &env_config, &shard_manager.info(), &db.info())?; let worker_executors = WorkerExecutors::start( docker, &env_config, @@ -68,7 +92,7 @@ impl Context<'_> { Ok(Context { env: env_config, - postgres, + db, redis, shard_manager, golem_service, @@ -79,7 +103,7 @@ impl Context<'_> { pub fn info(&self) -> ContextInfo { ContextInfo { env: self.env.clone(), - db: Box::new(self.postgres.info()), + db: self.db.info(), redis: self.redis.info(), shard_manager: self.shard_manager.info(), golem_service: self.golem_service.info(), @@ -96,7 +120,7 @@ impl Drop for Context<'_> { pub struct ContextInfo { pub env: EnvConfig, - pub db: Box, + pub db: DbInfo, pub redis: RedisInfo, pub shard_manager: ShardManagerInfo, pub golem_service: GolemServiceInfo, diff --git a/tests/context/db.rs b/tests/context/db.rs index 6cedce2..7661023 100644 --- a/tests/context/db.rs +++ b/tests/context/db.rs @@ -1,19 +1,28 @@ -use crate::context::{EnvConfig, NETWORK}; +use crate::context::{DbType, EnvConfig, NETWORK}; use libtest_mimic::Failed; use std::collections::HashMap; +use std::path::PathBuf; use testcontainers::{clients, Container, RunnableImage}; -pub struct Postgres<'docker_client> { - host: String, - port: u16, - local_port: u16, - _node: Container<'docker_client, testcontainers_modules::postgres::Postgres>, +pub struct Db<'docker_client> { + inner: DbInner<'docker_client>, } -impl<'docker_client> Postgres<'docker_client> { - fn test_started(&self) -> Result<(), Failed> { +pub enum DbInner<'docker_client> { + Sqlite(PathBuf), + Postgres { + host: String, + port: u16, + local_port: u16, + _node: Container<'docker_client, testcontainers_modules::postgres::Postgres>, + }, +} + +impl<'docker_client> Db<'docker_client> { + fn test_started(local_port: u16) -> Result<(), Failed> { let mut conn = - ::postgres::Client::connect(&self.connection_string(), ::postgres::NoTls).unwrap(); + ::postgres::Client::connect(&Db::connection_string(local_port), ::postgres::NoTls) + .unwrap(); let _ = conn.query("SELECT version()", &[])?; Ok(()) @@ -22,12 +31,41 @@ impl<'docker_client> Postgres<'docker_client> { pub fn start( docker: &'docker_client clients::Cli, env_config: &EnvConfig, - ) -> Result, Failed> { + ) -> Result, Failed> { + match &env_config.db_type { + DbType::Sqlite => Db::prepare_sqlite(), + DbType::Postgres => Db::start_postgres(docker, env_config), + } + } + + fn prepare_sqlite() -> Result, Failed> { + let path = PathBuf::from("../target/golem_test_db"); + + if path.exists() { + std::fs::remove_file(&path)? + } + + Ok(Db { + inner: DbInner::Sqlite(path), + }) + } + + fn start_postgres( + docker: &'docker_client clients::Cli, + env_config: &EnvConfig, + ) -> Result, Failed> { + println!("Starting Postgres in docker"); + let name = "golem_postgres"; let image = RunnableImage::from(testcontainers_modules::postgres::Postgres::default()) - .with_tag("12") - .with_container_name(name) - .with_network(NETWORK); + .with_tag("12"); + + let image = if env_config.local_golem { + image + } else { + image.with_container_name(name).with_network(NETWORK) + }; + let node = docker.run(image); let host = if env_config.local_golem { @@ -42,33 +80,70 @@ impl<'docker_client> Postgres<'docker_client> { 5432 }; - let res = Postgres { - host: host.to_string(), - port, - local_port: node.get_host_port_ipv4(5432), - _node: node, + let local_port = node.get_host_port_ipv4(5432); + + let res = Db { + inner: DbInner::Postgres { + host: host.to_string(), + port, + local_port, + _node: node, + }, }; - res.test_started()?; + Db::test_started(local_port)?; Ok(res) } - pub fn connection_string(&self) -> String { + fn connection_string(local_port: u16) -> String { format!( "postgres://postgres:postgres@127.0.0.1:{}/postgres", - self.local_port, + local_port, ) } - pub fn info(&self) -> PostgresInfo { - PostgresInfo { - host: self.host.clone(), - port: self.port, - local_port: self.local_port, - database_name: "postgres".to_owned(), - username: "postgres".to_owned(), - password: "postgres".to_owned(), + pub fn info(&self) -> DbInfo { + match &self.inner { + DbInner::Sqlite(path) => DbInfo::Sqlite(path.clone()), + DbInner::Postgres { + host, + port, + local_port, + _node: _, + } => DbInfo::Postgres(PostgresInfo { + host: host.clone(), + port: port.clone(), + local_port: local_port.clone(), + database_name: "postgres".to_owned(), + username: "postgres".to_owned(), + password: "postgres".to_owned(), + }), + } + } +} + +#[derive(Debug)] +pub enum DbInfo { + Sqlite(PathBuf), + Postgres(PostgresInfo), +} + +impl DbInfo { + pub fn env(&self) -> HashMap { + match self { + DbInfo::Postgres(pg) => pg.env(), + DbInfo::Sqlite(db_path) => [ + ("GOLEM__DB__TYPE".to_string(), "Sqlite".to_string()), + ( + "GOLEM__DB__CONFIG__DATABASE".to_string(), + db_path + .to_str() + .expect("Invalid Sqlite database path") + .to_string(), + ), + ] + .into(), } } } @@ -121,13 +196,3 @@ impl PostgresInfo { ]) } } - -pub trait DbInfo { - fn env(&self) -> HashMap; -} - -impl DbInfo for PostgresInfo { - fn env(&self) -> HashMap { - self.env() - } -} diff --git a/tests/context/golem_service.rs b/tests/context/golem_service.rs index 24ba3bd..45a9e29 100644 --- a/tests/context/golem_service.rs +++ b/tests/context/golem_service.rs @@ -104,7 +104,7 @@ impl<'docker_client> GolemService<'docker_client> { docker: &'docker_client clients::Cli, env_config: &EnvConfig, shard_manager: &ShardManagerInfo, - db: &impl DbInfo, + db: &DbInfo, ) -> Result, Failed> { if env_config.local_golem { GolemService::start_process(env_config, shard_manager, db) @@ -117,7 +117,7 @@ impl<'docker_client> GolemService<'docker_client> { docker: &'docker_client clients::Cli, env_config: &EnvConfig, shard_manager: &ShardManagerInfo, - db: &impl DbInfo, + db: &DbInfo, ) -> Result, Failed> { println!("Starting Golem Service docker with shard manager: {shard_manager:?}"); @@ -146,7 +146,7 @@ impl<'docker_client> GolemService<'docker_client> { http_port: u16, env_config: &EnvConfig, shard_manager: &ShardManagerInfo, - db: &impl DbInfo, + db: &DbInfo, ) -> HashMap { let log_level = if env_config.verbose { "debug" } else { "info" }; @@ -188,7 +188,7 @@ impl<'docker_client> GolemService<'docker_client> { fn start_process( env_config: &EnvConfig, shard_manager: &ShardManagerInfo, - db: &impl DbInfo, + db: &DbInfo, ) -> Result, Failed> { println!("Starting Golem Service"); diff --git a/tests/worker.rs b/tests/worker.rs index 93dfc62..46223f4 100644 --- a/tests/worker.rs +++ b/tests/worker.rs @@ -98,23 +98,14 @@ fn worker_new_instance( make_template(&context, &format!("{name} worker new instance"), &cli)?.template_id; let worker_name = format!("{name}_worker_new_instance"); let cfg = &cli.config; - let worker_id: Result = cli.run(&[ + let worker_id: VersionedWorkerId = cli.run(&[ "worker", "add", &cfg.arg('w', "worker-name"), &worker_name, &cfg.arg('T', "template-id"), &template_id, - ]); - - let worker_id = match worker_id { - Ok(id) => id, - Err(e) => { - println!("Worker add failed: {e:?}"); - std::thread::sleep(Duration::from_secs(6000)); - panic!("PNIC") - } - }; + ])?; assert_eq!(worker_id.worker_id.template_id.to_string(), template_id); assert_eq!(worker_id.worker_id.worker_name, worker_name);