diff --git a/Cargo.toml b/Cargo.toml index 30a5028..f46a5cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,16 +15,25 @@ [package] name = "opengemini" version = "0.0.1" -edition = "2021" +edition = "2024" description = "Rust client for OpenGemini" license = "Apache-2.0" repository = "https://github.com/openGemini/opengemini-client-rust" homepage = "https://github.com/openGemini/opengemini-client-rust" [dependencies] -reqwest = { version = "0.12.7", features = ["json", "__rustls", "blocking", "gzip"] } -serde = { version = "1.0.208", features = ["derive"] } -serde_json = "1.0.125" -thiserror = "1.0.64" -tokio = "1.40.0" +log = "0.4.28" +reqwest = { version = "0.12.24", features = [ + "json", + "__rustls", + "blocking", + "gzip", +] } +serde = { version = "1.0.228", features = ["derive"] } +serde_json = "1.0.145" +thiserror = "2.0.17" +tokio = "1.48.0" zigzag = "0.1.0" + +[dev-dependencies] +static_init = "1.0.4" diff --git a/src/lib.rs b/src/lib.rs index e05789f..dbb3e03 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -mod config; -mod error; +pub mod config; +pub mod error; mod opengemini_client; mod url_const; diff --git a/src/opengemini_client.rs b/src/opengemini_client.rs index 94d04b0..53f9ae9 100644 --- a/src/opengemini_client.rs +++ b/src/opengemini_client.rs @@ -50,16 +50,16 @@ impl Client { } pub fn ping(&self, idx: usize) -> Result { - if idx >= self.endpoints.len() as usize { + if idx >= self.endpoints.len() { return Err(ClientError::ValueError("Index out of range".to_string())); } let url: String = self.endpoints[idx].url.clone() + URL_PING; match reqwest::blocking::get(url) { Ok(response) => { if response.status().is_success() { - return Ok(true); + Ok(true) } else { - return Ok(false); + Ok(false) } } Err(_) => Err(ClientError::ConnectionError), @@ -82,10 +82,11 @@ impl Client { todo!(); } - fn get_server_url(&self) -> Option { + pub fn get_server_url(&self) -> Option { let current_index = self.prev_idx.load(Ordering::SeqCst); let endpoint_count = self.endpoints.len() as i32; - let url = if endpoint_count > 0 { + + if endpoint_count > 0 { let url = self.endpoints[current_index as usize % endpoint_count as usize] .url .clone(); @@ -94,8 +95,7 @@ impl Client { Some(url) } else { None - }; - url + } } } @@ -111,79 +111,3 @@ pub fn build_endpoints(addresses: Vec
) -> Vec { }) .collect() } - -#[cfg(test)] -mod tests { - use std::time::Duration; - - use crate::config::{AuthConfig, BatchConfig}; - - use super::*; - - fn create_test_config() -> Config { - Config { - address: vec![Address { - host: "127.0.0.1".to_string(), - port: 8086, - }], - batch_config: BatchConfig { - batch_interval: Duration::from_secs(30), - batch_size: 100, - }, - timeout: Duration::from_secs(30), - connect_timeout: Duration::from_secs(10), - gzip_enabled: true, - auth_config: AuthConfig { - username: "user".to_string(), - password: "password".to_string(), - token: None, - auth_type: 1, - }, - } - } - - #[test] - fn test_get_server_url() { - let addresses = vec![ - Address { - host: "127.0.0.1".to_string(), - port: 8086, - }, - Address { - host: "127.0.0.2".to_string(), - port: 8087, - }, - ]; - let mut config = create_test_config(); - - config.address = addresses; - - let client = Client::new(&config); - - let url1 = client.get_server_url(); - let url2 = client.get_server_url(); - - assert!(url1.is_some()); - assert!(url2.is_some()); - assert_ne!(url1, url2); - } - - /// Tests the `ping` method of the `Client` struct. - /// - /// This test sets up a `Client` with a single address and checks if the `ping` method - /// returns `Ok(true)` when the server is reachable. - /// - /// Before running this test, make sure to start the server using the following Docker command: - /// ```sh - /// docker run -p 8086:8086 --name opengemini --rm opengeminidb/opengemini-server - /// ``` - #[test] - fn test_ping_success() { - let config = create_test_config(); - let client = Client::new(&config); - - let result = client.ping(0); - assert!(result.is_ok()); - assert_eq!(result.unwrap(), true); - } -} diff --git a/src/url_const.rs b/src/url_const.rs index 3282c9c..d5ccf02 100644 --- a/src/url_const.rs +++ b/src/url_const.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub const URL_PING: &'static str = "/ping"; -pub const URL_QUERY: &'static str = "/query"; -pub const URL_STATUS: &'static str = "/status"; -pub const URL_WRITE_OUTPUT: &'static str = "/write"; +pub const URL_PING: &str = "/ping"; +pub const URL_QUERY: &str = "/query"; +pub const URL_STATUS: &str = "/status"; +pub const URL_WRITE_OUTPUT: &str = "/write"; diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..fce16f2 --- /dev/null +++ b/test.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +set -e +DIR=$(realpath $0) && DIR=${DIR%/*} +cd $DIR +# set -x + +PORT_LI="8086 8087" + +stop() { + for i in $PORT_LI; do + docker stop opengemini-rust-client-test-$i || true + done +} + +trap stop EXIT + +boot() { + for i in $PORT_LI; do + docker run --rm -d -p $i:8086 --name opengemini-rust-client-test-$i opengeminidb/opengemini-server:latest || stop + done + for i in $PORT_LI; do + while ! nc -z localhost $i; do + echo "wait for port $i" + sleep 1 + done + done +} + +boot +sleep 3 + +RUST_LOG=debug RUST_BACKTRACE=1 cargo test --all-features -- --nocapture diff --git a/tests/client.rs b/tests/client.rs new file mode 100644 index 0000000..c6f40b0 --- /dev/null +++ b/tests/client.rs @@ -0,0 +1,63 @@ +use opengemini::Client; +use opengemini::config::{Address, AuthConfig, BatchConfig, Config}; +use std::time::Duration; + +#[static_init::dynamic] +static CONFIG: Config = Config { + address: vec![Address { + host: "127.0.0.1".to_string(), + port: 8086, + }], + batch_config: BatchConfig { + batch_interval: Duration::from_secs(30), + batch_size: 100, + }, + timeout: Duration::from_secs(30), + connect_timeout: Duration::from_secs(10), + gzip_enabled: true, + auth_config: AuthConfig { + username: "user".to_string(), + password: "password".to_string(), + token: None, + auth_type: 1, + }, +}; + +#[test] +fn test_get_server_url() { + let mut config = CONFIG.clone(); + config.address.push(Address { + host: "127.0.0.1".to_string(), + port: 8087, + }); + + let client = Client::new(&config); + + let url1 = client.get_server_url(); + let url2 = client.get_server_url(); + + assert!(url1.is_some()); + assert!(url2.is_some()); + assert_ne!(url1, url2); +} + +/// Tests the `ping` method of the `Client` struct. +/// +/// This test sets up a `Client` with a single address and checks if the `ping` method +/// returns `Ok(true)` when the server is reachable. +/// +/// Before running this test, make sure to start the server using the following Docker command: +/// ```sh +/// docker run -p 8086:8086 --name opengemini --rm opengeminidb/opengemini-server +/// ``` +#[test] +fn test_ping_success() { + let client = Client::new(&CONFIG); + + let result = client.ping(0); + if result.is_err() { + log::info!("{:?}", &result); + } + assert!(result.is_ok()); + assert!(result.unwrap()); +}