diff --git a/agdb/src/type_def.rs b/agdb/src/type_def.rs index 7e38bbd3..d0e1dec9 100644 --- a/agdb/src/type_def.rs +++ b/agdb/src/type_def.rs @@ -268,6 +268,34 @@ impl TypeDefinition for (T, V) { } } +impl TypeDefinition for std::sync::Arc { + fn type_def() -> Type { + Type::Pointer(Pointer { + kind: PointerKind::Arc, + ty: T::type_def, + }) + } +} + +impl TypeDefinition for [T; N] { + fn type_def() -> Type { + Type::Slice(T::type_def) + } +} + +impl TypeDefinition for std::path::PathBuf { + fn type_def() -> Type { + Type::Struct(Struct { + name: "PathBuf", + generics: &[], + fields: &[Variable { + name: "inner", + ty: Some(|| Type::Vec(u8::type_def)), + }], + }) + } +} + macro_rules! impl_type_def_fn_ptr { ($(($($arg:ident),*)),* $(,)?) => { $( diff --git a/agdb_api/rust/Cargo.toml b/agdb_api/rust/Cargo.toml index 4abf2d73..41f724b8 100644 --- a/agdb_api/rust/Cargo.toml +++ b/agdb_api/rust/Cargo.toml @@ -17,6 +17,7 @@ categories = ["database", "api-bindings"] default = [] tls = ["reqwest/default-tls"] api = ["agdb/api"] +test_server = ["dep:tokio"] [dependencies] agdb = { version = "0.12.10", path = "../../agdb", features = ["serde", "openapi"] } @@ -24,3 +25,5 @@ reqwest = { version = "0.13", default-features = false, features = ["charset", " serde = { version = "1", features = ["derive"] } serde_json = "1" utoipa = "5" +tokio = { version = "1", features = ["full"], optional = true } + diff --git a/agdb_api/rust/src/api_types.rs b/agdb_api/rust/src/api_types.rs index f6d862da..49376e94 100644 --- a/agdb_api/rust/src/api_types.rs +++ b/agdb_api/rust/src/api_types.rs @@ -1,3 +1,5 @@ +pub mod config_impl; + use agdb::DbError; use agdb::DbSerialize; use agdb::DbValue; diff --git a/agdb_api/rust/src/api_types/config_impl.rs b/agdb_api/rust/src/api_types/config_impl.rs new file mode 100644 index 00000000..6fb0aa93 --- /dev/null +++ b/agdb_api/rust/src/api_types/config_impl.rs @@ -0,0 +1,72 @@ +use crate::LogLevelFilter; + +pub const SALT_LEN: usize = 16; +pub const DEFAULT_LOG_BODY_LIMIT: u64 = 10 * 1024; +pub const DEFAULT_REQUEST_BODY_LIMIT: u64 = 10 * 1024 * 1024; + +#[derive(Debug)] +#[cfg_attr(feature = "api", derive(agdb::TypeDefImpl))] +pub struct ConfigImpl { + pub bind: String, + pub address: String, + pub basepath: String, + pub static_roots: Vec, + pub admin: String, + pub log_level: LogLevelFilter, + pub log_body_limit: u64, + pub request_body_limit: u64, + pub data_dir: String, + pub pepper_path: String, + pub tls_certificate: String, + pub tls_key: String, + pub tls_root: String, + pub cluster_token: String, + pub cluster_heartbeat_timeout_ms: u64, + pub cluster_term_timeout_ms: u64, + pub cluster: Vec, + pub cluster_node_id: usize, + pub start_time: u64, + pub pepper: Option<[u8; SALT_LEN]>, +} + +impl ConfigImpl { + pub fn server_url(&self) -> String { + format!("{}{}", self.address, self.basepath) + } +} + +#[cfg_attr(feature = "api", agdb::fn_def())] +pub fn config_to_str(config: &ConfigImpl) -> String { + let mut buffer = String::new(); + buffer.push_str(&format!("bind: {}\n", config.bind)); + buffer.push_str(&format!("address: {}\n", config.address)); + buffer.push_str(&format!("basepath: {}\n", config.basepath)); + buffer.push_str(&format!( + "static_roots: {}\n", + config.static_roots.join(", ") + )); + buffer.push_str(&format!("admin: {}\n", config.admin)); + buffer.push_str(&format!("log_level: {}\n", config.log_level)); + buffer.push_str(&format!("log_body_limit: {}\n", config.log_body_limit)); + buffer.push_str(&format!( + "request_body_limit: {}\n", + config.request_body_limit + )); + buffer.push_str(&format!("data_dir: {}\n", config.data_dir)); + buffer.push_str(&format!("pepper_path: {}\n", config.pepper_path)); + buffer.push_str(&format!("tls_certificate: {}\n", config.tls_certificate)); + buffer.push_str(&format!("tls_key: {}\n", config.tls_key)); + buffer.push_str(&format!("tls_root: {}\n", config.tls_root)); + buffer.push_str(&format!("cluster_token: {}\n", config.cluster_token)); + + buffer.push_str(&format!( + "cluster_heartbeat_timeout_ms: {}\n", + config.cluster_heartbeat_timeout_ms + )); + buffer.push_str(&format!( + "cluster_term_timeout_ms: {}\n", + config.cluster_term_timeout_ms + )); + buffer.push_str(&format!("cluster: [{}]\n", config.cluster.join(", "))); + buffer +} diff --git a/agdb_api/rust/src/lib.rs b/agdb_api/rust/src/lib.rs index 1f0d7f82..f524c8d5 100644 --- a/agdb_api/rust/src/lib.rs +++ b/agdb_api/rust/src/lib.rs @@ -5,6 +5,8 @@ mod api_result; mod api_types; mod client; mod http_client; +#[cfg(feature = "test_server")] +pub mod test_server; pub use api_error::AgdbApiError; pub use api_result::AgdbApiResult; @@ -24,6 +26,7 @@ pub use api_types::ServerDatabase; pub use api_types::UserCredentials; pub use api_types::UserLogin; pub use api_types::UserStatus; +pub use api_types::config_impl; pub use client::AgdbApi; pub use http_client::HttpClient; pub use http_client::ReqwestClient; diff --git a/agdb_server/tests/test_server.rs b/agdb_api/rust/src/test_server.rs similarity index 56% rename from agdb_server/tests/test_server.rs rename to agdb_api/rust/src/test_server.rs index 068dffc1..6c238dce 100644 --- a/agdb_server/tests/test_server.rs +++ b/agdb_api/rust/src/test_server.rs @@ -1,16 +1,15 @@ -#[path = "../src/config.rs"] -pub mod config; -mod routes; -#[cfg(feature = "tls")] -mod tls; - -use crate::config::ConfigImpl; -use crate::config::DEFAULT_LOG_BODY_LIMIT; -use crate::config::DEFAULT_REQUEST_BODY_LIMIT; -use crate::config::to_str; -use agdb_api::AgdbApi; -use agdb_api::ClusterStatus; -use agdb_api::ReqwestClient; +pub mod test_cluster; +pub mod test_dir; +pub mod test_error; + +use crate::AgdbApi; +use crate::ReqwestClient; +use crate::config_impl::ConfigImpl; +use crate::config_impl::DEFAULT_LOG_BODY_LIMIT; +use crate::config_impl::DEFAULT_REQUEST_BODY_LIMIT; +use crate::config_impl::config_to_str; +use crate::test_server::test_error::TestError; +use crate::test_server::test_error::bail; use std::collections::HashMap; use std::path::Path; use std::path::PathBuf; @@ -19,39 +18,75 @@ use std::sync::Weak; use std::sync::atomic::AtomicU16; use std::sync::atomic::Ordering; use std::time::Duration; -use std::time::Instant; use tokio::process::Child; use tokio::process::Command; use tokio::sync::RwLock; -const ADMIN: &str = "admin"; +pub const ADMIN: &str = "admin"; +pub const CONFIG_FILE: &str = "agdb_server.yaml"; +pub const SERVER_DATA_DIR: &str = "agdb_server_data"; + +pub(crate) const HOST: &str = "localhost"; + const BINARY: &str = "agdb_server"; -const CONFIG_FILE: &str = "agdb_server.yaml"; const DEFAULT_PORT: u16 = 3000; -const HOST: &str = "localhost"; const POLL_INTERVAL: u64 = 100; const RETRY_TIMEOUT: Duration = Duration::from_secs(1); const RETRY_ATTEMPS: u16 = 10; -const SERVER_DATA_DIR: &str = "agdb_server_data"; const SHUTDOWN_RETRY_TIMEOUT: Duration = Duration::from_millis(100); const SHUTDOWN_RETRY_ATTEMPTS: u16 = 100; const TEST_TIMEOUT: u128 = 30000; const CLIENT_TIMEOUT: Duration = Duration::from_secs(30); -type ClusterImpl = Vec; - static PORT: AtomicU16 = AtomicU16::new(DEFAULT_PORT); static COUNTER: AtomicU16 = AtomicU16::new(1); static SERVER: std::sync::OnceLock>> = std::sync::OnceLock::new(); -static CLUSTER: std::sync::OnceLock>> = std::sync::OnceLock::new(); -fn server_bin() -> anyhow::Result { +pub struct TestServerProcess(pub Child); + +#[cfg(feature = "api")] +impl agdb::type_def::TypeDefinition for TestServerProcess { + fn type_def() -> agdb::type_def::Type { + agdb::type_def::Type::Struct(agdb::type_def::Struct { + name: "TestServerProcess", + generics: &[], + fields: &[], + }) + } +} + +#[cfg_attr(feature = "api", agdb::fn_def())] +fn server_bin() -> Result { let mut path = std::env::current_exe()?; path.pop(); path.pop(); Ok(path.join(format!("{BINARY}{}", std::env::consts::EXE_SUFFIX))) } +#[cfg_attr(feature = "api", agdb::fn_def())] +pub fn next_user_name() -> String { + format!("db_user{}", COUNTER.fetch_add(1, Ordering::SeqCst)) +} + +#[cfg_attr(feature = "api", agdb::fn_def())] +pub fn next_db_name() -> String { + format!("db{}", COUNTER.fetch_add(1, Ordering::SeqCst)) +} + +#[cfg_attr(feature = "api", agdb::fn_def())] +pub async fn wait_for_ready(api: &AgdbApi) -> Result<(), TestError> { + for _ in 0..RETRY_ATTEMPS { + if api.status().await.is_ok() { + return Ok(()); + } + + std::thread::sleep(RETRY_TIMEOUT); + } + + bail!("Server not ready") +} + +#[cfg_attr(feature = "api", derive(agdb::TypeDef))] pub struct TestServer { pub dir: String, pub data_dir: String, @@ -59,16 +94,12 @@ pub struct TestServer { pub server: Arc, } +#[cfg_attr(feature = "api", derive(agdb::TypeDef))] pub struct TestServerImpl { pub dir: String, pub data_dir: String, pub address: String, - pub process: Option, -} - -pub struct TestCluster { - apis: Vec>, - _cluster: Arc, + pub process: Option, } #[cfg(feature = "tls")] @@ -103,8 +134,9 @@ pub fn reqwest_client() -> reqwest::Client { .unwrap() } +#[cfg_attr(feature = "api", agdb::impl_def())] impl TestServerImpl { - pub async fn with_config(mut config: ConfigImpl) -> anyhow::Result { + pub async fn with_config(mut config: ConfigImpl) -> Result { if config.address.is_empty() { let port = Self::next_port(); let address = format!("http://{HOST}:{port}"); @@ -121,7 +153,7 @@ impl TestServerImpl { Self::remove_dir_if_exists(&dir)?; std::fs::create_dir(&dir)?; - std::fs::write(Path::new(&dir).join(CONFIG_FILE), to_str(&config))?; + std::fs::write(Path::new(&dir).join(CONFIG_FILE), config_to_str(&config))?; let api_address = if config.basepath.is_empty() { config.address.clone() @@ -142,7 +174,7 @@ impl TestServerImpl { dir, data_dir, address: api_address, - process: Some(process), + process: Some(TestServerProcess(process)), }); } Ok(status) => println!("Server at {api_address} is not ready: {status}"), @@ -159,17 +191,17 @@ impl TestServerImpl { status = code.to_string() } - anyhow::bail!("Failed to start server '{api_address}' ({status})") + bail!("Failed to start server '{api_address}' ({status})") } - pub async fn new() -> anyhow::Result { + pub async fn new() -> Result { let config = ConfigImpl { bind: String::new(), address: String::new(), basepath: String::new(), static_roots: Vec::new(), admin: ADMIN.to_string(), - log_level: agdb_api::LogLevelFilter::Info, + log_level: crate::LogLevelFilter::Info, log_body_limit: DEFAULT_LOG_BODY_LIMIT, request_body_limit: DEFAULT_REQUEST_BODY_LIMIT, data_dir: SERVER_DATA_DIR.into(), @@ -193,26 +225,29 @@ impl TestServerImpl { PORT.fetch_add(1, Ordering::Relaxed) + std::process::id() as u16 } - pub fn restart(&mut self) -> anyhow::Result<()> { - self.process = Some( + pub fn restart(&mut self) -> Result<(), TestError> { + self.process = Some(TestServerProcess( Command::new(server_bin()?) .current_dir(&self.dir) .kill_on_drop(true) .spawn()?, - ); + )); Ok(()) } - pub async fn wait(&mut self) -> anyhow::Result<()> { + pub async fn wait(&mut self) -> Result<(), TestError> { if let Some(p) = self.process.as_mut() { - p.wait().await?; + p.0.wait().await?; } Ok(()) } - async fn shutdown_server(mut process: Child, mut address: String) -> anyhow::Result<()> { - if process.try_wait()?.is_some() { + async fn shutdown_server( + mut process: TestServerProcess, + mut address: String, + ) -> Result<(), TestError> { + if process.0.try_wait()?.is_some() { return Ok(()); } @@ -243,25 +278,25 @@ impl TestServerImpl { .await?; for _ in 0..SHUTDOWN_RETRY_ATTEMPTS { - if process.try_wait()?.is_some() { + if process.0.try_wait()?.is_some() { return Ok(()); } std::thread::sleep(SHUTDOWN_RETRY_TIMEOUT); } - process.kill().await?; + process.0.kill().await?; for _ in 0..SHUTDOWN_RETRY_ATTEMPTS { - if process.try_wait()?.is_some() { + if process.0.try_wait()?.is_some() { return Ok(()); } std::thread::sleep(SHUTDOWN_RETRY_TIMEOUT); } - anyhow::bail!("Failed to shutdown server") + bail!("Failed to shutdown server") } - fn remove_dir_if_exists(dir: &str) -> anyhow::Result<()> { + fn remove_dir_if_exists(dir: &str) -> Result<(), TestError> { if Path::new(dir).exists() { std::fs::remove_dir_all(dir)?; } @@ -270,8 +305,9 @@ impl TestServerImpl { } } +#[cfg_attr(feature = "api", agdb::impl_def())] impl TestServer { - pub async fn new() -> anyhow::Result { + pub async fn new() -> Result { let global_server = SERVER.get_or_init(|| RwLock::new(Weak::new())); let mut server_guard = global_server.write().await; @@ -303,6 +339,7 @@ impl TestServer { } } +#[cfg_attr(feature = "api", agdb::impl_def())] impl Drop for TestServerImpl { fn drop(&mut self) { static DROP_RUNTIME: std::sync::OnceLock = @@ -332,178 +369,3 @@ impl Drop for TestServerImpl { } } } - -impl TestCluster { - async fn new() -> anyhow::Result { - let global_cluster = CLUSTER.get_or_init(|| RwLock::new(Weak::new())); - let mut cluster_guard = global_cluster.write().await; - - let nodes = if let Some(nodes) = cluster_guard.upgrade() { - nodes - } else { - let nodes = Arc::new(create_cluster(3, false).await?); - *cluster_guard = Arc::downgrade(&nodes); - nodes - }; - - let mut cluster = Self { - apis: nodes - .iter() - .map(|s| { - Ok(AgdbApi::new( - ReqwestClient::with_client(reqwest_client()), - &s.address, - )) - }) - .collect::>>>()?, - _cluster: nodes, - }; - - cluster.apis[1].cluster_user_login(ADMIN, ADMIN).await?; - - Ok(cluster) - } -} - -pub fn next_user_name() -> String { - format!("db_user{}", COUNTER.fetch_add(1, Ordering::SeqCst)) -} - -pub fn next_db_name() -> String { - format!("db{}", COUNTER.fetch_add(1, Ordering::SeqCst)) -} - -pub async fn wait_for_ready(api: &AgdbApi) -> anyhow::Result<()> { - for _ in 0..RETRY_ATTEMPS { - if api.status().await.is_ok() { - return Ok(()); - } - - std::thread::sleep(RETRY_TIMEOUT); - } - - anyhow::bail!("Server not ready") -} - -pub async fn wait_for_leader(api: &AgdbApi) -> anyhow::Result> { - let now = Instant::now(); - - while now.elapsed().as_millis() < TEST_TIMEOUT { - let status = api.cluster_status().await?; - - if status.1.iter().any(|s| s.leader) { - return Ok(status.1); - } - - std::thread::sleep(std::time::Duration::from_millis(POLL_INTERVAL)); - } - - Err(anyhow::anyhow!( - "Leader not found within {TEST_TIMEOUT}seconds" - )) -} - -pub async fn create_cluster(nodes: usize, tls: bool) -> anyhow::Result> { - let mut configs = Vec::with_capacity(nodes); - let mut cluster = Vec::with_capacity(nodes); - let mut servers = Vec::with_capacity(nodes); - let protocol = if tls { "https" } else { "http" }; - let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")?; - let tls_cert = if tls { - format!("{manifest_dir}/tests/test_cert.pem") - } else { - String::new() - }; - let tls_key = if tls { - format!("{manifest_dir}/tests/test_cert.key.pem") - } else { - String::new() - }; - let tls_root = if tls { - format!("{manifest_dir}/tests/test_root_ca.pem") - } else { - String::new() - }; - - for _ in 0..nodes { - let port = TestServerImpl::next_port(); - let config = ConfigImpl { - bind: format!("{HOST}:{port}"), - address: format!("{protocol}://{HOST}:{port}"), - basepath: String::new(), - static_roots: Vec::new(), - admin: ADMIN.to_string(), - log_level: agdb_api::LogLevelFilter::Info, - log_body_limit: DEFAULT_LOG_BODY_LIMIT, - request_body_limit: DEFAULT_REQUEST_BODY_LIMIT, - data_dir: SERVER_DATA_DIR.into(), - pepper_path: String::new(), - tls_certificate: tls_cert.clone(), - tls_key: tls_key.clone(), - tls_root: tls_root.clone(), - cluster_token: "test".to_string(), - cluster_heartbeat_timeout_ms: 1000, - cluster_term_timeout_ms: 3000, - cluster: Vec::new(), - cluster_node_id: 0, - start_time: 0, - pepper: None, - }; - - configs.push(config); - cluster.push(format!("{protocol}://{HOST}:{port}")); - } - - for config in &mut configs { - config.cluster = cluster.clone(); - } - - for server in configs - .into_iter() - .map(|c| tokio::spawn(async move { TestServerImpl::with_config(c).await })) - { - let server = server.await??; - let api = AgdbApi::new( - ReqwestClient::with_client(reqwest_client()), - &server.address, - ); - servers.push((server, api)); - } - - let mut statuses = Vec::with_capacity(nodes); - - for server in &servers { - statuses.push(wait_for_leader(&server.1).await?); - } - - for status in &statuses[1..] { - assert_eq!(statuses[0], *status); - } - - let leader = statuses[0] - .iter() - .enumerate() - .find_map(|(i, s)| if s.leader { Some(i) } else { None }) - .unwrap(); - servers.swap(0, leader); - - Ok(servers.into_iter().map(|(s, _)| s).collect()) -} - -pub struct TestDir { - pub dir: PathBuf, -} - -impl TestDir { - pub fn new() -> anyhow::Result { - let dir = format!("static_files_test{}", TestServerImpl::next_port()).into(); - std::fs::create_dir_all(&dir)?; - Ok(Self { dir }) - } -} - -impl Drop for TestDir { - fn drop(&mut self) { - let _ = std::fs::remove_dir_all(&self.dir); - } -} diff --git a/agdb_api/rust/src/test_server/test_cluster.rs b/agdb_api/rust/src/test_server/test_cluster.rs new file mode 100644 index 00000000..12151989 --- /dev/null +++ b/agdb_api/rust/src/test_server/test_cluster.rs @@ -0,0 +1,166 @@ +use crate::AgdbApi; +use crate::ClusterStatus; +use crate::ReqwestClient; +use crate::config_impl::ConfigImpl; +use crate::test_server::ADMIN; +use crate::test_server::HOST; +use crate::test_server::POLL_INTERVAL; +use crate::test_server::TEST_TIMEOUT; +use crate::test_server::TestServerImpl; +use crate::test_server::reqwest_client; +use crate::test_server::test_error::TestError; +use crate::test_server::test_error::bail; +use std::sync::Arc; +use std::sync::Weak; +use std::time::Instant; +use tokio::sync::RwLock; + +type ClusterImpl = Vec; + +static CLUSTER: std::sync::OnceLock>> = std::sync::OnceLock::new(); + +#[cfg_attr(feature = "api", derive(agdb::TypeDef))] +pub struct TestCluster { + pub apis: Vec>, + pub cluster: Arc, +} + +#[cfg_attr(feature = "api", agdb::impl_def())] +impl TestCluster { + pub async fn new() -> Result { + let global_cluster = CLUSTER.get_or_init(|| RwLock::new(Weak::new())); + let mut cluster_guard = global_cluster.write().await; + + let nodes = if let Some(nodes) = cluster_guard.upgrade() { + nodes + } else { + let nodes = Arc::new(create_cluster(3, false).await?); + *cluster_guard = Arc::downgrade(&nodes); + nodes + }; + + let mut cluster = Self { + apis: nodes + .iter() + .map(|s| { + Ok(AgdbApi::new( + ReqwestClient::with_client(reqwest_client()), + &s.address, + )) + }) + .collect::>, TestError>>()?, + cluster: nodes, + }; + + cluster.apis[1].cluster_user_login(ADMIN, ADMIN).await?; + + Ok(cluster) + } +} + +#[cfg_attr(feature = "api", agdb::fn_def())] +pub async fn wait_for_leader( + api: &AgdbApi, +) -> Result, TestError> { + let now = Instant::now(); + + while now.elapsed().as_millis() < TEST_TIMEOUT { + let status = api.cluster_status().await?; + + if status.1.iter().any(|s| s.leader) { + return Ok(status.1); + } + + std::thread::sleep(std::time::Duration::from_millis(POLL_INTERVAL)); + } + + bail!("Leader not found within {TEST_TIMEOUT}seconds") +} + +#[cfg_attr(feature = "api", agdb::fn_def())] +pub async fn create_cluster(nodes: usize, tls: bool) -> Result, TestError> { + let mut configs = Vec::with_capacity(nodes); + let mut cluster = Vec::with_capacity(nodes); + let mut servers = Vec::with_capacity(nodes); + let protocol = if tls { "https" } else { "http" }; + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")?; + let tls_cert = if tls { + format!("{manifest_dir}/tests/test_cert.pem") + } else { + String::new() + }; + let tls_key = if tls { + format!("{manifest_dir}/tests/test_cert.key.pem") + } else { + String::new() + }; + let tls_root = if tls { + format!("{manifest_dir}/tests/test_root_ca.pem") + } else { + String::new() + }; + + for _ in 0..nodes { + let port = TestServerImpl::next_port(); + let config = ConfigImpl { + bind: format!("{HOST}:{port}"), + address: format!("{protocol}://{HOST}:{port}"), + basepath: String::new(), + static_roots: Vec::new(), + admin: ADMIN.to_string(), + log_level: crate::LogLevelFilter::Info, + log_body_limit: crate::config_impl::DEFAULT_LOG_BODY_LIMIT, + request_body_limit: crate::config_impl::DEFAULT_REQUEST_BODY_LIMIT, + data_dir: super::SERVER_DATA_DIR.into(), + pepper_path: String::new(), + tls_certificate: tls_cert.clone(), + tls_key: tls_key.clone(), + tls_root: tls_root.clone(), + cluster_token: "test".to_string(), + cluster_heartbeat_timeout_ms: 1000, + cluster_term_timeout_ms: 3000, + cluster: Vec::new(), + cluster_node_id: 0, + start_time: 0, + pepper: None, + }; + + configs.push(config); + cluster.push(format!("{protocol}://{HOST}:{port}")); + } + + for config in &mut configs { + config.cluster = cluster.clone(); + } + + for server in configs + .into_iter() + .map(|c| tokio::spawn(async move { TestServerImpl::with_config(c).await })) + { + let server = server.await??; + let api = AgdbApi::new( + ReqwestClient::with_client(reqwest_client()), + &server.address, + ); + servers.push((server, api)); + } + + let mut statuses = Vec::with_capacity(nodes); + + for server in &servers { + statuses.push(wait_for_leader(&server.1).await?); + } + + for status in &statuses[1..] { + assert_eq!(statuses[0], *status); + } + + let leader = statuses[0] + .iter() + .enumerate() + .find_map(|x| if x.1.leader { Some(x.0) } else { None }) + .unwrap(); + servers.swap(0, leader); + + Ok(servers.into_iter().map(|x| x.0).collect()) +} diff --git a/agdb_api/rust/src/test_server/test_dir.rs b/agdb_api/rust/src/test_server/test_dir.rs new file mode 100644 index 00000000..651c5427 --- /dev/null +++ b/agdb_api/rust/src/test_server/test_dir.rs @@ -0,0 +1,21 @@ +use crate::test_server::TestServerImpl; +use crate::test_server::test_error::TestError; +use std::path::PathBuf; + +pub struct TestDir { + pub dir: PathBuf, +} + +impl TestDir { + pub fn new() -> Result { + let dir = format!("static_files_test{}", TestServerImpl::next_port()).into(); + std::fs::create_dir_all(&dir)?; + Ok(Self { dir }) + } +} + +impl Drop for TestDir { + fn drop(&mut self) { + let _ = std::fs::remove_dir_all(&self.dir); + } +} diff --git a/agdb_api/rust/src/test_server/test_error.rs b/agdb_api/rust/src/test_server/test_error.rs new file mode 100644 index 00000000..2713ccb2 --- /dev/null +++ b/agdb_api/rust/src/test_server/test_error.rs @@ -0,0 +1,81 @@ +use crate::AgdbApiError; +use std::env::VarError; + +#[derive(Debug)] +#[cfg_attr(feature = "api", derive(agdb::TypeDefImpl))] +pub struct TestError { + description: String, +} + +impl TestError { + pub(crate) fn new(description: impl Into) -> Self { + TestError { + description: description.into(), + } + } +} + +impl std::fmt::Display for TestError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.description) + } +} + +impl std::error::Error for TestError {} + +/// Early-returns an `Err(TestError)` from the current function. +/// Supports the same format-string syntax as `format!`. +macro_rules! bail { + ($fmt:literal $(,)?) => { + return Err(crate::test_server::test_error::TestError::new(format!($fmt))) + }; + ($fmt:literal, $($arg:tt)*) => { + return Err(crate::test_server::test_error::TestError::new(format!($fmt, $($arg)*))) + }; +} +pub(crate) use bail; + +impl From for TestError { + #[track_caller] + fn from(error: std::io::Error) -> Self { + TestError { + description: error.to_string(), + } + } +} + +impl From for TestError { + #[track_caller] + fn from(error: reqwest::Error) -> Self { + TestError { + description: error.to_string(), + } + } +} + +impl From for TestError { + #[track_caller] + fn from(error: AgdbApiError) -> Self { + TestError { + description: error.to_string(), + } + } +} + +impl From for TestError { + #[track_caller] + fn from(error: VarError) -> Self { + TestError { + description: error.to_string(), + } + } +} + +impl From for TestError { + #[track_caller] + fn from(error: tokio::task::JoinError) -> Self { + TestError { + description: error.to_string(), + } + } +} diff --git a/agdb_derive/src/type_def_parser/expression_parser.rs b/agdb_derive/src/type_def_parser/expression_parser.rs index 2f27ed2c..dee2f34f 100644 --- a/agdb_derive/src/type_def_parser/expression_parser.rs +++ b/agdb_derive/src/type_def_parser/expression_parser.rs @@ -744,7 +744,7 @@ fn parse_macro_by_name( // Common macros treated as function calls "panic" | "todo" | "unimplemented" | "println" | "eprintln" | "dbg" | "assert" | "assert_eq" | "assert_ne" | "debug_assert" | "debug_assert_eq" | "debug_assert_ne" - | "matches" | "unreachable" | "write" | "writeln" => { + | "matches" | "unreachable" | "write" | "writeln" | "bail" => { let macro_args = args.iter().map(|arg| parse_expression(arg, generics)); quote! { ::agdb::type_def::Expression::Call { diff --git a/agdb_server/Cargo.toml b/agdb_server/Cargo.toml index cc126b87..244dfb68 100644 --- a/agdb_server/Cargo.toml +++ b/agdb_server/Cargo.toml @@ -39,4 +39,5 @@ utoipa-rapidoc = { version = "6", features = ["axum"] } uuid = { version = "1", features = ["v4"] } [dev-dependencies] +agdb_api = { version = "0.12.10", path = "../agdb_api/rust", features = ["test_server"] } anyhow = "1" diff --git a/agdb_server/src/config.rs b/agdb_server/src/config.rs index 4bf778c7..64a0ac3d 100644 --- a/agdb_server/src/config.rs +++ b/agdb_server/src/config.rs @@ -1,4 +1,8 @@ use agdb_api::LogLevelFilter; +use agdb_api::config_impl::ConfigImpl; +use agdb_api::config_impl::DEFAULT_LOG_BODY_LIMIT; +use agdb_api::config_impl::DEFAULT_REQUEST_BODY_LIMIT; +use agdb_api::config_impl::SALT_LEN; use std::sync::Arc; use std::time::SystemTime; use std::time::UNIX_EPOCH; @@ -6,40 +10,6 @@ use tracing::warn; pub(crate) type Config = Arc; -pub(crate) const SALT_LEN: usize = 16; -pub(crate) const DEFAULT_LOG_BODY_LIMIT: u64 = 10 * 1024; -pub(crate) const DEFAULT_REQUEST_BODY_LIMIT: u64 = 10 * 1024 * 1024; - -#[derive(Debug)] -pub struct ConfigImpl { - pub(crate) bind: String, - pub(crate) address: String, - pub(crate) basepath: String, - pub(crate) static_roots: Vec, - pub(crate) admin: String, - pub(crate) log_level: LogLevelFilter, - pub(crate) log_body_limit: u64, - pub(crate) request_body_limit: u64, - pub(crate) data_dir: String, - pub(crate) pepper_path: String, - pub(crate) tls_certificate: String, - pub(crate) tls_key: String, - pub(crate) tls_root: String, - pub(crate) cluster_token: String, - pub(crate) cluster_heartbeat_timeout_ms: u64, - pub(crate) cluster_term_timeout_ms: u64, - pub(crate) cluster: Vec, - pub(crate) cluster_node_id: usize, - pub(crate) start_time: u64, - pub(crate) pepper: Option<[u8; SALT_LEN]>, -} - -impl ConfigImpl { - pub fn server_url(&self) -> String { - format!("{}{}", self.address, self.basepath) - } -} - pub(crate) fn new(config_file: &str) -> Result { if let Ok(content) = std::fs::read_to_string(config_file) { let mut config_impl: ConfigImpl = from_str(&content)?; @@ -117,7 +87,7 @@ pub(crate) fn new(config_file: &str) -> Result { pepper: None, }; - std::fs::write(config_file, to_str(&config)) + std::fs::write(config_file, agdb_api::config_impl::config_to_str(&config)) .map_err(|e| format!("Failed to write config file '{}': {e:?}", config_file))?; Ok(Config::new(config)) @@ -249,41 +219,6 @@ fn normalize_address(config: &mut ConfigImpl) { } } -pub(crate) fn to_str(config: &ConfigImpl) -> String { - let mut buffer = String::new(); - buffer.push_str(&format!("bind: {}\n", config.bind)); - buffer.push_str(&format!("address: {}\n", config.address)); - buffer.push_str(&format!("basepath: {}\n", config.basepath)); - buffer.push_str(&format!( - "static_roots: {}\n", - config.static_roots.join(", ") - )); - buffer.push_str(&format!("admin: {}\n", config.admin)); - buffer.push_str(&format!("log_level: {}\n", config.log_level)); - buffer.push_str(&format!("log_body_limit: {}\n", config.log_body_limit)); - buffer.push_str(&format!( - "request_body_limit: {}\n", - config.request_body_limit - )); - buffer.push_str(&format!("data_dir: {}\n", config.data_dir)); - buffer.push_str(&format!("pepper_path: {}\n", config.pepper_path)); - buffer.push_str(&format!("tls_certificate: {}\n", config.tls_certificate)); - buffer.push_str(&format!("tls_key: {}\n", config.tls_key)); - buffer.push_str(&format!("tls_root: {}\n", config.tls_root)); - buffer.push_str(&format!("cluster_token: {}\n", config.cluster_token)); - - buffer.push_str(&format!( - "cluster_heartbeat_timeout_ms: {}\n", - config.cluster_heartbeat_timeout_ms - )); - buffer.push_str(&format!( - "cluster_term_timeout_ms: {}\n", - config.cluster_term_timeout_ms - )); - buffer.push_str(&format!("cluster: [{}]\n", config.cluster.join(", "))); - buffer -} - #[cfg(test)] mod tests { use super::*; @@ -344,7 +279,11 @@ mod tests { pepper: None, }; - std::fs::write(test_file.filename, to_str(&config)).unwrap(); + std::fs::write( + test_file.filename, + agdb_api::config_impl::config_to_str(&config), + ) + .unwrap(); let config = config::new(test_file.filename).unwrap(); @@ -376,7 +315,11 @@ mod tests { start_time: 0, pepper: None, }; - std::fs::write(test_file.filename, to_str(&config)).unwrap(); + std::fs::write( + test_file.filename, + agdb_api::config_impl::config_to_str(&config), + ) + .unwrap(); config::new(test_file.filename).unwrap_err(); } @@ -408,7 +351,11 @@ mod tests { start_time: 0, pepper: None, }; - std::fs::write(test_file.filename, to_str(&config)).unwrap(); + std::fs::write( + test_file.filename, + agdb_api::config_impl::config_to_str(&config), + ) + .unwrap(); config::new(test_file.filename).unwrap_err(); } diff --git a/agdb_server/src/password.rs b/agdb_server/src/password.rs index e86c6371..6f5844d8 100644 --- a/agdb_server/src/password.rs +++ b/agdb_server/src/password.rs @@ -1,5 +1,6 @@ use crate::error_code::ErrorCode; use crate::server_error::ServerResult; +use agdb_api::config_impl::SALT_LEN; use ring::digest; use ring::pbkdf2; use ring::rand::SecureRandom; @@ -10,7 +11,6 @@ use std::num::NonZeroU32; use std::sync::OnceLock; pub(crate) const PASSWORD_LEN: usize = digest::SHA256_OUTPUT_LEN; -pub(crate) const SALT_LEN: usize = 16; pub(crate) static BUILTIN_PEPPER: &[u8; SALT_LEN] = std::include_bytes!("../pepper"); pub(crate) static PEPPER: OnceLock<[u8; SALT_LEN]> = OnceLock::new(); diff --git a/agdb_server/tests/routes/admin_db_add_test.rs b/agdb_server/tests/routes/admin_db_add_test.rs index 02580675..b7dd242a 100644 --- a/agdb_server/tests/routes/admin_db_add_test.rs +++ b/agdb_server/tests/routes/admin_db_add_test.rs @@ -1,8 +1,8 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/admin_db_audit_test.rs b/agdb_server/tests/routes/admin_db_audit_test.rs index 6091d274..f51798f0 100644 --- a/agdb_server/tests/routes/admin_db_audit_test.rs +++ b/agdb_server/tests/routes/admin_db_audit_test.rs @@ -1,9 +1,9 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::QueryBuilder; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn admin_audit() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_db_backup_restore_test.rs b/agdb_server/tests/routes/admin_db_backup_restore_test.rs index 4398e773..7547cec0 100644 --- a/agdb_server/tests/routes/admin_db_backup_restore_test.rs +++ b/agdb_server/tests/routes/admin_db_backup_restore_test.rs @@ -1,12 +1,12 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::DbElement; use agdb::DbId; use agdb::QueryBuilder; use agdb::QueryResult; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/admin_db_clear_test.rs b/agdb_server/tests/routes/admin_db_clear_test.rs index 2b8566c0..e3904df8 100644 --- a/agdb_server/tests/routes/admin_db_clear_test.rs +++ b/agdb_server/tests/routes/admin_db_clear_test.rs @@ -1,11 +1,11 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::QueryBuilder; use agdb_api::DbKind; use agdb_api::DbResource; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/admin_db_convert_test.rs b/agdb_server/tests/routes/admin_db_convert_test.rs index f31887ad..0cf3665a 100644 --- a/agdb_server/tests/routes/admin_db_convert_test.rs +++ b/agdb_server/tests/routes/admin_db_convert_test.rs @@ -1,8 +1,8 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn memory_to_mapped() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_db_copy_test.rs b/agdb_server/tests/routes/admin_db_copy_test.rs index 577003de..2d846ce4 100644 --- a/agdb_server/tests/routes/admin_db_copy_test.rs +++ b/agdb_server/tests/routes/admin_db_copy_test.rs @@ -1,12 +1,12 @@ -use crate::ADMIN; -use crate::TestCluster; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::DbElement; use agdb::DbId; use agdb::QueryBuilder; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; +use agdb_api::test_server::test_cluster::TestCluster; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/admin_db_delete_test.rs b/agdb_server/tests/routes/admin_db_delete_test.rs index e8a0a090..fe7a53da 100644 --- a/agdb_server/tests/routes/admin_db_delete_test.rs +++ b/agdb_server/tests/routes/admin_db_delete_test.rs @@ -1,8 +1,8 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/admin_db_exec_test.rs b/agdb_server/tests/routes/admin_db_exec_test.rs index c9968777..41d174a8 100644 --- a/agdb_server/tests/routes/admin_db_exec_test.rs +++ b/agdb_server/tests/routes/admin_db_exec_test.rs @@ -1,12 +1,12 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::DbElement; use agdb::DbId; use agdb::QueryBuilder; use agdb::QueryResult; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn read_write() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_db_list_test.rs b/agdb_server/tests/routes/admin_db_list_test.rs index c3c9ef74..879ba2b4 100644 --- a/agdb_server/tests/routes/admin_db_list_test.rs +++ b/agdb_server/tests/routes/admin_db_list_test.rs @@ -1,10 +1,10 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUserRole; use agdb_api::ServerDatabase; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn db_list() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_db_optimize_test.rs b/agdb_server/tests/routes/admin_db_optimize_test.rs index 3f1ace82..cfd7aaeb 100644 --- a/agdb_server/tests/routes/admin_db_optimize_test.rs +++ b/agdb_server/tests/routes/admin_db_optimize_test.rs @@ -1,9 +1,9 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::QueryBuilder; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn optimize() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_db_remove_test.rs b/agdb_server/tests/routes/admin_db_remove_test.rs index 044ce224..b0ce711b 100644 --- a/agdb_server/tests/routes/admin_db_remove_test.rs +++ b/agdb_server/tests/routes/admin_db_remove_test.rs @@ -1,8 +1,8 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/admin_db_rename_test.rs b/agdb_server/tests/routes/admin_db_rename_test.rs index ef6593ae..7b48d858 100644 --- a/agdb_server/tests/routes/admin_db_rename_test.rs +++ b/agdb_server/tests/routes/admin_db_rename_test.rs @@ -1,8 +1,8 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/admin_db_user_add_test.rs b/agdb_server/tests/routes/admin_db_user_add_test.rs index 351c5c24..a028a812 100644 --- a/agdb_server/tests/routes/admin_db_user_add_test.rs +++ b/agdb_server/tests/routes/admin_db_user_add_test.rs @@ -1,10 +1,10 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUserRole; use agdb_api::ServerDatabase; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn db_user_add() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_db_user_list_test.rs b/agdb_server/tests/routes/admin_db_user_list_test.rs index db803303..c7f157e7 100644 --- a/agdb_server/tests/routes/admin_db_user_list_test.rs +++ b/agdb_server/tests/routes/admin_db_user_list_test.rs @@ -1,10 +1,10 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUser; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn list() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_db_user_remove_test.rs b/agdb_server/tests/routes/admin_db_user_remove_test.rs index 2f4174c5..8e63f158 100644 --- a/agdb_server/tests/routes/admin_db_user_remove_test.rs +++ b/agdb_server/tests/routes/admin_db_user_remove_test.rs @@ -1,9 +1,9 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn remove() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_set_log_level_test.rs b/agdb_server/tests/routes/admin_set_log_level_test.rs index ea5f82b9..fb5b391c 100644 --- a/agdb_server/tests/routes/admin_set_log_level_test.rs +++ b/agdb_server/tests/routes/admin_set_log_level_test.rs @@ -1,10 +1,10 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::TestServerImpl; -use crate::next_user_name; -use crate::reqwest_client; use agdb_api::AgdbApi; use agdb_api::ReqwestClient; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::TestServerImpl; +use agdb_api::test_server::next_user_name; +use agdb_api::test_server::reqwest_client; #[tokio::test] async fn set_log_level() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_status_test.rs b/agdb_server/tests/routes/admin_status_test.rs index c0c89337..6742c0c7 100644 --- a/agdb_server/tests/routes/admin_status_test.rs +++ b/agdb_server/tests/routes/admin_status_test.rs @@ -1,7 +1,7 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_user_name; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn status() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_user_add_test.rs b/agdb_server/tests/routes/admin_user_add_test.rs index c38705ad..b99032aa 100644 --- a/agdb_server/tests/routes/admin_user_add_test.rs +++ b/agdb_server/tests/routes/admin_user_add_test.rs @@ -1,6 +1,6 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_user_name; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn add() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_user_change_password_test.rs b/agdb_server/tests/routes/admin_user_change_password_test.rs index 5f875728..86c87df3 100644 --- a/agdb_server/tests/routes/admin_user_change_password_test.rs +++ b/agdb_server/tests/routes/admin_user_change_password_test.rs @@ -1,6 +1,6 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_user_name; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn change_password() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_user_delete_test.rs b/agdb_server/tests/routes/admin_user_delete_test.rs index 5e67abc2..d3243376 100644 --- a/agdb_server/tests/routes/admin_user_delete_test.rs +++ b/agdb_server/tests/routes/admin_user_delete_test.rs @@ -1,9 +1,9 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/admin_user_list_test.rs b/agdb_server/tests/routes/admin_user_list_test.rs index dc0fd971..df25bd30 100644 --- a/agdb_server/tests/routes/admin_user_list_test.rs +++ b/agdb_server/tests/routes/admin_user_list_test.rs @@ -1,7 +1,7 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_user_name; use agdb_api::UserStatus; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn user_list() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_user_logout_all.rs b/agdb_server/tests/routes/admin_user_logout_all.rs index 59665c59..bf8100c9 100644 --- a/agdb_server/tests/routes/admin_user_logout_all.rs +++ b/agdb_server/tests/routes/admin_user_logout_all.rs @@ -1,10 +1,10 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::TestServerImpl; -use crate::next_user_name; -use crate::reqwest_client; use agdb_api::AgdbApi; use agdb_api::ReqwestClient; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::TestServerImpl; +use agdb_api::test_server::next_user_name; +use agdb_api::test_server::reqwest_client; #[tokio::test] async fn logout_all() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/admin_user_logout_test.rs b/agdb_server/tests/routes/admin_user_logout_test.rs index 8e8fed43..735008df 100644 --- a/agdb_server/tests/routes/admin_user_logout_test.rs +++ b/agdb_server/tests/routes/admin_user_logout_test.rs @@ -1,6 +1,6 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_user_name; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn logout() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/cluster_test.rs b/agdb_server/tests/routes/cluster_test.rs index 32dd8fb3..eb8eec3f 100644 --- a/agdb_server/tests/routes/cluster_test.rs +++ b/agdb_server/tests/routes/cluster_test.rs @@ -1,12 +1,3 @@ -use crate::ADMIN; -use crate::TestCluster; -use crate::TestServer; -use crate::create_cluster; -use crate::next_db_name; -use crate::next_user_name; -use crate::reqwest_client; -use crate::wait_for_leader; -use crate::wait_for_ready; use agdb::Comparison; use agdb::QueryBuilder; use agdb_api::AgdbApi; @@ -14,6 +5,15 @@ use agdb_api::DbKind; use agdb_api::DbResource; use agdb_api::DbUserRole; use agdb_api::ReqwestClient; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; +use agdb_api::test_server::reqwest_client; +use agdb_api::test_server::test_cluster::TestCluster; +use agdb_api::test_server::test_cluster::create_cluster; +use agdb_api::test_server::test_cluster::wait_for_leader; +use agdb_api::test_server::wait_for_ready; #[tokio::test] async fn rebalance() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/db_add_test.rs b/agdb_server/tests/routes/db_add_test.rs index a000dc4f..f4a63a05 100644 --- a/agdb_server/tests/routes/db_add_test.rs +++ b/agdb_server/tests/routes/db_add_test.rs @@ -1,8 +1,8 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/db_audit_test.rs b/agdb_server/tests/routes/db_audit_test.rs index 6f4e9b6c..f1c3db4c 100644 --- a/agdb_server/tests/routes/db_audit_test.rs +++ b/agdb_server/tests/routes/db_audit_test.rs @@ -1,9 +1,9 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::QueryBuilder; use agdb_api::DbKind; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/db_backup_restore_test.rs b/agdb_server/tests/routes/db_backup_restore_test.rs index 3aae385a..b6b9d9cb 100644 --- a/agdb_server/tests/routes/db_backup_restore_test.rs +++ b/agdb_server/tests/routes/db_backup_restore_test.rs @@ -1,13 +1,13 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::DbElement; use agdb::DbId; use agdb::QueryBuilder; use agdb::QueryResult; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/db_clear_test.rs b/agdb_server/tests/routes/db_clear_test.rs index fefcb36e..8ffd8c9b 100644 --- a/agdb_server/tests/routes/db_clear_test.rs +++ b/agdb_server/tests/routes/db_clear_test.rs @@ -1,11 +1,11 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::QueryBuilder; use agdb_api::DbKind; use agdb_api::DbResource; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/db_convert_test.rs b/agdb_server/tests/routes/db_convert_test.rs index 9269872c..abe3036f 100644 --- a/agdb_server/tests/routes/db_convert_test.rs +++ b/agdb_server/tests/routes/db_convert_test.rs @@ -1,10 +1,10 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::QueryBuilder; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn memory_to_mapped() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/db_copy_test.rs b/agdb_server/tests/routes/db_copy_test.rs index 43613325..72d45e1c 100644 --- a/agdb_server/tests/routes/db_copy_test.rs +++ b/agdb_server/tests/routes/db_copy_test.rs @@ -1,12 +1,12 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::DbElement; use agdb::DbId; use agdb::QueryBuilder; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/db_delete_test.rs b/agdb_server/tests/routes/db_delete_test.rs index 3b44f1ab..554dd0a4 100644 --- a/agdb_server/tests/routes/db_delete_test.rs +++ b/agdb_server/tests/routes/db_delete_test.rs @@ -1,9 +1,9 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/db_exec_test.rs b/agdb_server/tests/routes/db_exec_test.rs index 42b7bd7c..0ddf20db 100644 --- a/agdb_server/tests/routes/db_exec_test.rs +++ b/agdb_server/tests/routes/db_exec_test.rs @@ -1,13 +1,13 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::DbElement; use agdb::DbId; use agdb::QueryBuilder; use agdb::QueryResult; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn read_write() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/db_list_test.rs b/agdb_server/tests/routes/db_list_test.rs index 0654b0de..ba2c1d15 100644 --- a/agdb_server/tests/routes/db_list_test.rs +++ b/agdb_server/tests/routes/db_list_test.rs @@ -1,10 +1,10 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUserRole; use agdb_api::ServerDatabase; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn list() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/db_optimize_test.rs b/agdb_server/tests/routes/db_optimize_test.rs index 1a4e4602..601a716f 100644 --- a/agdb_server/tests/routes/db_optimize_test.rs +++ b/agdb_server/tests/routes/db_optimize_test.rs @@ -1,10 +1,10 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb::QueryBuilder; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn optimize() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/db_remove_test.rs b/agdb_server/tests/routes/db_remove_test.rs index 978a0736..afdcdfcd 100644 --- a/agdb_server/tests/routes/db_remove_test.rs +++ b/agdb_server/tests/routes/db_remove_test.rs @@ -1,9 +1,9 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/db_rename_test.rs b/agdb_server/tests/routes/db_rename_test.rs index 27e78afa..7eb42979 100644 --- a/agdb_server/tests/routes/db_rename_test.rs +++ b/agdb_server/tests/routes/db_rename_test.rs @@ -1,9 +1,9 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; use std::path::Path; #[tokio::test] diff --git a/agdb_server/tests/routes/db_user_add_test.rs b/agdb_server/tests/routes/db_user_add_test.rs index 0c811733..aac84c47 100644 --- a/agdb_server/tests/routes/db_user_add_test.rs +++ b/agdb_server/tests/routes/db_user_add_test.rs @@ -1,10 +1,10 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUserRole; use agdb_api::ServerDatabase; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn add_db_user() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/db_user_list.rs b/agdb_server/tests/routes/db_user_list.rs index 139101ef..b1219b66 100644 --- a/agdb_server/tests/routes/db_user_list.rs +++ b/agdb_server/tests/routes/db_user_list.rs @@ -1,10 +1,10 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUser; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn list() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/db_user_remove_test.rs b/agdb_server/tests/routes/db_user_remove_test.rs index ca0ef2f9..e5cfa103 100644 --- a/agdb_server/tests/routes/db_user_remove_test.rs +++ b/agdb_server/tests/routes/db_user_remove_test.rs @@ -1,9 +1,9 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_db_name; -use crate::next_user_name; use agdb_api::DbKind; use agdb_api::DbUserRole; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn remove() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/misc_routes.rs b/agdb_server/tests/routes/misc_routes.rs index 1b4d5e45..f5eba40e 100644 --- a/agdb_server/tests/routes/misc_routes.rs +++ b/agdb_server/tests/routes/misc_routes.rs @@ -1,16 +1,15 @@ -use crate::ADMIN; -use crate::CONFIG_FILE; -use crate::DEFAULT_LOG_BODY_LIMIT; -use crate::TestDir; -use crate::TestServer; -use crate::TestServerImpl; -use crate::next_db_name; -use crate::reqwest_client; -use crate::wait_for_ready; use agdb::QueryBuilder; use agdb_api::AgdbApi; use agdb_api::DbKind; use agdb_api::ReqwestClient; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::CONFIG_FILE; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::TestServerImpl; +use agdb_api::test_server::next_db_name; +use agdb_api::test_server::reqwest_client; +use agdb_api::test_server::test_dir::TestDir; +use agdb_api::test_server::wait_for_ready; use reqwest::StatusCode; use std::path::Path; @@ -152,10 +151,10 @@ async fn db_list_after_shutdown_corrupted_data() -> anyhow::Result<()> { #[cfg(feature = "studio")] #[tokio::test] async fn basepath_test() -> anyhow::Result<()> { - use crate::DEFAULT_LOG_BODY_LIMIT; - use crate::DEFAULT_REQUEST_BODY_LIMIT; + use agdb_api::config_impl::DEFAULT_LOG_BODY_LIMIT; + use agdb_api::config_impl::DEFAULT_REQUEST_BODY_LIMIT; - let config = crate::config::ConfigImpl { + let config = agdb_api::config_impl::ConfigImpl { bind: String::new(), address: String::new(), basepath: "/public".to_string(), @@ -164,7 +163,7 @@ async fn basepath_test() -> anyhow::Result<()> { log_level: agdb_api::LogLevelFilter::Info, log_body_limit: DEFAULT_LOG_BODY_LIMIT, request_body_limit: DEFAULT_REQUEST_BODY_LIMIT, - data_dir: crate::SERVER_DATA_DIR.into(), + data_dir: agdb_api::test_server::SERVER_DATA_DIR.into(), pepper_path: String::new(), tls_certificate: String::new(), tls_key: String::new(), @@ -329,16 +328,16 @@ async fn studio() -> anyhow::Result<()> { #[tokio::test] async fn large_payload() -> anyhow::Result<()> { - let config = crate::config::ConfigImpl { + let config = agdb_api::config_impl::ConfigImpl { bind: String::new(), address: String::new(), basepath: String::new(), static_roots: Vec::new(), admin: ADMIN.to_string(), log_level: agdb_api::LogLevelFilter::Info, - log_body_limit: DEFAULT_LOG_BODY_LIMIT, + log_body_limit: agdb_api::config_impl::DEFAULT_LOG_BODY_LIMIT, request_body_limit: 1024, - data_dir: crate::SERVER_DATA_DIR.into(), + data_dir: agdb_api::test_server::SERVER_DATA_DIR.into(), pepper_path: String::new(), tls_certificate: String::new(), tls_key: String::new(), @@ -408,7 +407,7 @@ async fn static_files() -> anyhow::Result<()> { let test_dir1 = TestDir::new()?; let test_dir2 = TestDir::new()?; - let config = crate::config::ConfigImpl { + let config = agdb_api::config_impl::ConfigImpl { bind: String::new(), address: String::new(), basepath: String::new(), @@ -424,9 +423,9 @@ async fn static_files() -> anyhow::Result<()> { ], admin: ADMIN.to_string(), log_level: agdb_api::LogLevelFilter::Info, - log_body_limit: DEFAULT_LOG_BODY_LIMIT, - request_body_limit: 1024, - data_dir: crate::SERVER_DATA_DIR.into(), + log_body_limit: agdb_api::config_impl::DEFAULT_LOG_BODY_LIMIT, + request_body_limit: agdb_api::config_impl::DEFAULT_REQUEST_BODY_LIMIT, + data_dir: agdb_api::test_server::SERVER_DATA_DIR.into(), pepper_path: String::new(), tls_certificate: String::new(), tls_key: String::new(), @@ -473,7 +472,7 @@ async fn static_files_with_basepath() -> anyhow::Result<()> { let test_dir1 = TestDir::new()?; let test_dir2 = TestDir::new()?; - let config = crate::config::ConfigImpl { + let config = agdb_api::config_impl::ConfigImpl { bind: String::new(), address: String::new(), basepath: "/some_basepath".to_string(), @@ -489,9 +488,9 @@ async fn static_files_with_basepath() -> anyhow::Result<()> { ], admin: ADMIN.to_string(), log_level: agdb_api::LogLevelFilter::Info, - log_body_limit: DEFAULT_LOG_BODY_LIMIT, - request_body_limit: 1024, - data_dir: crate::SERVER_DATA_DIR.into(), + log_body_limit: agdb_api::config_impl::DEFAULT_LOG_BODY_LIMIT, + request_body_limit: agdb_api::config_impl::DEFAULT_REQUEST_BODY_LIMIT, + data_dir: agdb_api::test_server::SERVER_DATA_DIR.into(), pepper_path: String::new(), tls_certificate: String::new(), tls_key: String::new(), diff --git a/agdb_server/tests/routes/user_change_password_test.rs b/agdb_server/tests/routes/user_change_password_test.rs index 8eec9d53..be941047 100644 --- a/agdb_server/tests/routes/user_change_password_test.rs +++ b/agdb_server/tests/routes/user_change_password_test.rs @@ -1,6 +1,6 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_user_name; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn change_password() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/user_login_test.rs b/agdb_server/tests/routes/user_login_test.rs index 3f1e8aa4..d619d9a1 100644 --- a/agdb_server/tests/routes/user_login_test.rs +++ b/agdb_server/tests/routes/user_login_test.rs @@ -1,6 +1,6 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_user_name; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn login() -> anyhow::Result<()> { @@ -74,7 +74,7 @@ async fn concurrent_logins() -> anyhow::Result<()> { for _ in 0..3 { apis.push(( agdb_api::AgdbApi::new( - agdb_api::ReqwestClient::with_client(crate::reqwest_client()), + agdb_api::ReqwestClient::with_client(agdb_api::test_server::reqwest_client()), server.api.address(), ), user.to_string(), diff --git a/agdb_server/tests/routes/user_logout_test.rs b/agdb_server/tests/routes/user_logout_test.rs index 44e6b24f..ea48c948 100644 --- a/agdb_server/tests/routes/user_logout_test.rs +++ b/agdb_server/tests/routes/user_logout_test.rs @@ -1,6 +1,6 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_user_name; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn logout() -> anyhow::Result<()> { diff --git a/agdb_server/tests/routes/user_status.rs b/agdb_server/tests/routes/user_status.rs index 2a162451..e6be9d0f 100644 --- a/agdb_server/tests/routes/user_status.rs +++ b/agdb_server/tests/routes/user_status.rs @@ -1,6 +1,6 @@ -use crate::ADMIN; -use crate::TestServer; -use crate::next_user_name; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServer; +use agdb_api::test_server::next_user_name; #[tokio::test] async fn user() -> anyhow::Result<()> { diff --git a/agdb_server/tests/tests.rs b/agdb_server/tests/tests.rs new file mode 100644 index 00000000..631fc7df --- /dev/null +++ b/agdb_server/tests/tests.rs @@ -0,0 +1,3 @@ +mod routes; +#[cfg(feature = "tls")] +mod tls; diff --git a/agdb_server/tests/tls/mod.rs b/agdb_server/tests/tls/mod.rs index fc936768..9007e2fc 100644 --- a/agdb_server/tests/tls/mod.rs +++ b/agdb_server/tests/tls/mod.rs @@ -1,15 +1,12 @@ -use crate::ADMIN; -use crate::ConfigImpl; -use crate::DEFAULT_LOG_BODY_LIMIT; -use crate::DEFAULT_REQUEST_BODY_LIMIT; -use crate::SERVER_DATA_DIR; -use crate::TestServerImpl; -use crate::create_cluster; -use crate::reqwest_client; -use crate::wait_for_leader; -use crate::wait_for_ready; use agdb_api::AgdbApi; use agdb_api::ReqwestClient; +use agdb_api::config_impl::ConfigImpl; +use agdb_api::test_server::ADMIN; +use agdb_api::test_server::TestServerImpl; +use agdb_api::test_server::reqwest_client; +use agdb_api::test_server::test_cluster::create_cluster; +use agdb_api::test_server::test_cluster::wait_for_leader; +use agdb_api::test_server::wait_for_ready; #[tokio::test] async fn https() -> anyhow::Result<()> { @@ -22,9 +19,9 @@ async fn https() -> anyhow::Result<()> { static_roots: Vec::new(), admin: ADMIN.to_string(), log_level: agdb_api::LogLevelFilter::Info, - log_body_limit: DEFAULT_LOG_BODY_LIMIT, - request_body_limit: DEFAULT_REQUEST_BODY_LIMIT, - data_dir: SERVER_DATA_DIR.into(), + log_body_limit: agdb_api::config_impl::DEFAULT_LOG_BODY_LIMIT, + request_body_limit: agdb_api::config_impl::DEFAULT_REQUEST_BODY_LIMIT, + data_dir: agdb_api::test_server::SERVER_DATA_DIR.into(), pepper_path: String::new(), tls_certificate: format!("{manifest_dir}/tests/test_cert.pem"), tls_key: format!("{manifest_dir}/tests/test_cert.key.pem"),