diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b56b977..a05b08c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -9,6 +9,7 @@ on: jobs: # this checks that the readme created from rustdoc is up to date readmecheck: + if: false name: README Format Check runs-on: ubuntu-latest steps: @@ -20,6 +21,7 @@ jobs: # this checks that there are no clippy lints clippy: + if: false name: Style Check (clippy) runs-on: ubuntu-latest steps: @@ -34,6 +36,7 @@ jobs: # this checks that the code is formatted with rustfmt rustfmt: + if: false name: Style Checks (rustfmt) runs-on: ubuntu-latest steps: @@ -46,6 +49,7 @@ jobs: # this tests that all unit and doc tests are successful unit_tests: + if: false name: Unit and Doc Tests (Rust ${{matrix.rust.name}} on ${{matrix.os}}) runs-on: ${{matrix.os}} continue-on-error: ${{matrix.rust.nightly}} @@ -94,7 +98,7 @@ jobs: - name: Stable toolchain: stable nightly: false - http-backend: [curl-client, h1-client, h1-client-rustls, hyper-client, reqwest-client, reqwest-client-rustls] + http-backend: [curl-client] #, h1-client, h1-client-rustls, hyper-client, reqwest-client, reqwest-client-rustls] services: influxdb: image: influxdb:1.8 @@ -134,15 +138,33 @@ jobs: ~/.cargo/registry target key: "${{runner.os}} Rust ${{steps.rust-toolchain.outputs.cachekey}}" - - name: Run tests + + - name: Setup InfluxDB + uses: influxdata/influxdb-action@v3 + with: + influxdb_version: 2.6.1 + influxdb_start: false +# - name: Run tests +# run: | +# for test in integration_tests{,_v2} +# do +# cargo test -p influxdb --no-default-features --features 'use-serde derive ${{matrix.http-backend}}' --no-fail-fast --test $test +# done + + - name: Create Org + run: | + influx org create --name testing2 --token admintoken --skip-verify --host http://localhost:2086 + NEW_BUCKET_ID=$(influx bucket create --name mydb --org testing2 --token admintoken --skip-verify --host http://localhost:2086 --json | jq -r .id) + influx v1 dbrp create --db mydb --rp testing2 --org testing2 --bucket-id "$NEW_BUCKET_ID" --token admintoken --skip-verify --host http://localhost:2086 + + - name: Run dbrp tests run: | - for test in integration_tests{,_v2} - do - cargo test -p influxdb --no-default-features --features 'use-serde derive ${{matrix.http-backend}}' --no-fail-fast --test $test - done + cargo test -p influxdb --no-default-features --features 'use-serde derive ${{matrix.http-backend}}' --no-fail-fast --test integration_tests_dbrp + # this uses cargo-tarpaulin to inspect the code coverage coverage: + if: false name: Code Coverage (stable/ubuntu-latest) runs-on: ubuntu-latest services: @@ -202,10 +224,11 @@ jobs: # this uploads the code coverage to github pages pages: + if: false runs-on: ubuntu-latest needs: - coverage - if: github.ref == 'refs/heads/main' +# if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v3 with: diff --git a/influxdb/src/client/mod.rs b/influxdb/src/client/mod.rs index ad198bc..7d0ead1 100644 --- a/influxdb/src/client/mod.rs +++ b/influxdb/src/client/mod.rs @@ -141,6 +141,23 @@ impl Client { self } + /// Add a retention policy to [`Client`](crate::Client) + /// + /// This is designed for InfluxDB 2.x's backward-compatible API, which + /// maps databases and retention policies to buckets using the **database + /// and retention policy (DBRP) mapping service**. + /// See [InfluxDB Docs](https://docs.influxdata.com/influxdb/v2/reference/api/influxdb-1x/dbrp/) for more details. + #[must_use = "Creating a client is pointless unless you use it"] + pub fn with_retention_policy(mut self, retention_policy: S) -> Self + where + S: Into, + { + let mut with_retention_policy = self.parameters.as_ref().clone(); + with_retention_policy.insert("rp", retention_policy.into()); + self.parameters = Arc::new(with_retention_policy); + self + } + /// Returns the name of the database the client is using pub fn database_name(&self) -> &str { // safe to unwrap: we always set the database name in `Self::new` diff --git a/influxdb/src/query/mod.rs b/influxdb/src/query/mod.rs index 0546b2b..b0f8304 100644 --- a/influxdb/src/query/mod.rs +++ b/influxdb/src/query/mod.rs @@ -89,7 +89,12 @@ where T: TimeZone, { fn from(date_time: DateTime) -> Self { - Timestamp::Nanoseconds(date_time.timestamp_nanos() as u128) + Timestamp::Nanoseconds( + date_time + .timestamp_nanos_opt() + .expect("value can not be represented in a timestamp with nanosecond precision.") + as u128, + ) } } diff --git a/influxdb/src/query/write_query.rs b/influxdb/src/query/write_query.rs index 7014731..75d8b02 100644 --- a/influxdb/src/query/write_query.rs +++ b/influxdb/src/query/write_query.rs @@ -267,7 +267,7 @@ impl Query for Vec { fn get_type(&self) -> QueryType { QueryType::WriteQuery( - self.get(0) + self.first() .map(|q| q.get_precision()) // use "ms" as placeholder if query is empty .unwrap_or_else(|| "ms".to_owned()), diff --git a/influxdb/tests/integration_tests_dbrp.rs b/influxdb/tests/integration_tests_dbrp.rs new file mode 100644 index 0000000..e198bda --- /dev/null +++ b/influxdb/tests/integration_tests_dbrp.rs @@ -0,0 +1,67 @@ +extern crate influxdb; + +#[path = "./utilities.rs"] +pub mod utilities; +use utilities::{assert_result_err, assert_result_ok, run_test}; + +use influxdb::InfluxDbWriteable; +use influxdb::{Client, Error, ReadQuery, Timestamp}; + +/// INTEGRATION TEST +/// +/// This test case tests connection error +#[async_std::test] +#[cfg(not(tarpaulin_include))] +async fn test_no_rp() { + let client = Client::new("http://127.0.0.1:2086", "mydb").with_token("admintoken"); + let read_query = ReadQuery::new("SELECT * FROM weather"); + let read_result = client.query(read_query).await; + assert_result_err(&read_result); + match read_result { + Err(Error::ConnectionError { error: s }) => { + println!("NO_RP_ERROR: {}", s); + } + _ => panic!( + "Should cause a ConnectionError: {}", + read_result.unwrap_err() + ), + } +} + +/// INTEGRATION TEST +/// +/// This test case tests using the retention policy with DBRP mapping +#[async_std::test] +#[cfg(not(tarpaulin))] +pub async fn test_authed_write_and_read_with_rp() { + run_test( + || async move { + let client = Client::new("http://127.0.0.1:2086", "mydb") + .with_token("admintoken") + .with_retention_policy("testing2"); + let write_query = Timestamp::Hours(11) + .into_query("weather") + .add_field("temperature", 82); + let write_result = client.query(&write_query).await; + assert_result_ok(&write_result); + + let read_query = ReadQuery::new("SELECT * FROM weather"); + let read_result = client.query(read_query).await; + assert_result_ok(&read_result); + assert!( + !read_result.unwrap().contains("error"), + "Data contained a database error" + ); + }, + || async move { + let client = Client::new("http://127.0.0.1:2086", "mydb") + .with_token("admintoken") + .with_retention_policy("testing2"); + let read_query = ReadQuery::new("DELETE MEASUREMENT weather"); + let read_result = client.query(read_query).await; + assert_result_ok(&read_result); + assert!(!read_result.unwrap().contains("error"), "Teardown failed"); + }, + ) + .await; +} diff --git a/influxdb/tests/integration_tests_v2.rs b/influxdb/tests/integration_tests_v2.rs index 74e17a7..0beca5d 100644 --- a/influxdb/tests/integration_tests_v2.rs +++ b/influxdb/tests/integration_tests_v2.rs @@ -9,7 +9,6 @@ use influxdb::{Client, Error, ReadQuery, Timestamp}; /// INTEGRATION TEST /// - /// This test case tests the Authentication #[async_std::test] #[cfg(not(tarpaulin))]