From 7aff2e2e7e49e4b3978f40445466c343bd461e8d Mon Sep 17 00:00:00 2001 From: Patrick Freed Date: Mon, 11 Jan 2021 18:17:14 -0500 Subject: [PATCH] RUST-610 Test that monitors wait at least minHeartbeatFrequencyMS between failed checks (#273) --- src/sdam/monitor.rs | 7 +---- src/sdam/test.rs | 62 +++++++++++++++++++++++++++++++++++++++++++- src/test/auth_aws.rs | 6 ++++- 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/sdam/monitor.rs b/src/sdam/monitor.rs index 7b40e2cbc..cbdee9c23 100644 --- a/src/sdam/monitor.rs +++ b/src/sdam/monitor.rs @@ -210,12 +210,7 @@ impl HeartbeatMonitor { } }; - if result - .as_ref() - .err() - .map(|e| e.kind.is_network_error()) - .unwrap_or(false) - { + if result.is_err() { self.connection.take(); } diff --git a/src/sdam/test.rs b/src/sdam/test.rs index 87e74ab86..95da33093 100644 --- a/src/sdam/test.rs +++ b/src/sdam/test.rs @@ -1,4 +1,7 @@ -use std::{sync::Arc, time::Duration}; +use std::{ + sync::Arc, + time::{Duration, Instant}, +}; use bson::doc; use semver::VersionReq; @@ -22,6 +25,63 @@ use crate::{ RUNTIME, }; +#[cfg_attr(feature = "tokio-runtime", tokio::test(threaded_scheduler))] +#[cfg_attr(feature = "async-std-runtime", async_std::test)] +async fn min_heartbeat_frequency() { + let _guard: RwLockWriteGuard<_> = LOCK.run_exclusively().await; + + let mut setup_client_options = CLIENT_OPTIONS.clone(); + setup_client_options.hosts.drain(1..); + setup_client_options.direct_connection = Some(true); + + let setup_client = TestClient::with_options(Some(setup_client_options.clone()), true).await; + + if !setup_client.supports_fail_command().await { + println!("skipping min_heartbeat_frequency test due to server not supporting fail points"); + return; + } + + if setup_client.server_version_lt(4, 9) { + println!("skipping min_heartbeat_frequency test due to server version being less than 4.9"); + return; + } + + let fp_options = FailCommandOptions::builder() + .app_name("SDAMMinHeartbeatFrequencyTest".to_string()) + .error_code(1234) + .build(); + let failpoint = FailPoint::fail_command(&["isMaster"], FailPointMode::Times(5), fp_options); + + let _fp_guard = setup_client + .enable_failpoint(failpoint, None) + .await + .expect("enabling failpoint should succeed"); + + let mut options = setup_client_options; + options.app_name = Some("SDAMMinHeartbeatFrequencyTest".to_string()); + options.server_selection_timeout = Some(Duration::from_secs(5)); + let client = Client::with_options(options).expect("client creation succeeds"); + + let start = Instant::now(); + client + .database("admin") + .run_command(doc! { "ping": 1 }, None) + .await + .expect("ping should eventually succeed"); + + let elapsed = Instant::now().duration_since(start).as_millis(); + assert!( + elapsed >= 2000, + "expected to take at least 2 seconds, instead took {}ms", + elapsed + ); + assert!( + elapsed <= 3500, + "expected to take at most 3.5 seconds, instead took {}ms", + elapsed + ); +} + // TODO: RUST-232 update this test to incorporate SDAM events #[cfg_attr(feature = "tokio-runtime", tokio::test(threaded_scheduler))] #[cfg_attr(feature = "async-std-runtime", async_std::test)] diff --git a/src/test/auth_aws.rs b/src/test/auth_aws.rs index 588a8f7eb..2cc44091e 100644 --- a/src/test/auth_aws.rs +++ b/src/test/auth_aws.rs @@ -1,8 +1,12 @@ -use super::TestClient; +use tokio::sync::RwLockReadGuard; + +use super::{TestClient, LOCK}; #[cfg_attr(feature = "tokio-runtime", tokio::test)] #[cfg_attr(feature = "async-std-runtime", async_std::test)] async fn auth_aws() { + let _guard: RwLockReadGuard<()> = LOCK.run_concurrently().await; + let client = TestClient::new().await; let coll = client.database("aws").collection("somecoll");