diff --git a/cli/tests/integration/mod.rs b/cli/tests/integration/mod.rs index 3d55f4c47c1..fbac8821a9d 100644 --- a/cli/tests/integration/mod.rs +++ b/cli/tests/integration/mod.rs @@ -51,6 +51,9 @@ fn set_env(tmp_dir: &str, url: &ParsecAddr) { std::env::set_var(PARSEC_BASE_HOME_DIR, format!("{tmp_dir}/cache")); std::env::set_var(PARSEC_BASE_DATA_DIR, format!("{tmp_dir}/share")); std::env::set_var(PARSEC_BASE_CONFIG_DIR, format!("{tmp_dir}/config")); + // Hidden environ variable only used for CLI testing to customize the throttling time + // in invitation polling, without that the tests would be much slower for no reason. + std::env::set_var("_PARSEC_INVITE_POLLING_THROTTLE_MS", "10"); } fn unique_org_id() -> OrganizationID { diff --git a/libparsec/crates/client/src/invite/common.rs b/libparsec/crates/client/src/invite/common.rs index 5b5129dc5bf..249b8d469b8 100644 --- a/libparsec/crates/client/src/invite/common.rs +++ b/libparsec/crates/client/src/invite/common.rs @@ -2,32 +2,52 @@ use libparsec_types::prelude::*; -// The throttle duration is defined to 100 ms. +// The default throttle duration is too slow when testing the CLI, hence this environ +// variable than allows us to customize it (typically setting it to 10ms during tests) +// +// Note the `_` prefix and the fact this environ variable is not documented: it is only +// here for testing the CLI. +// This is because the CLI's tests run the default CLI binary (i.e. the test code is +// first compiled and run by `cargo test`, and in turn runs the CLI binary to do the tests). +// That means we cannot use time provider to mock time (since the CLI binary is not +// compiled in debug, and since the test code cannot communicate with a time provider +// in the CLI binary). +// +// Also note we don't use a feature-flag given this would further add complexity to +// the steps to obtain a valid CLI binary and do the CLI tests. +const CUSTOMIZE_THROTTLE_ENVIRON_VARIABLE: &str = "_PARSEC_INVITE_POLLING_THROTTLE_MS"; + +// The throttle duration is defined to 1 second. // This value limits the amount of polling done by the peer -// to 10 requests per second. This is deliberately fast in order -// improve user experience and to accelerate the tests. However, -// this might be too much for the server and this value might need -// to be adjusted for production. In this case, a decoupling between -// testing and production might be necessary. This could be achieved -// by mocking the time provider passed to the throttler. -static THROTTLE_DURATION: Duration = Duration::milliseconds(100); +// to 1 requests per second. +const THROTTLE_DEFAULT_DURATION: Duration = Duration::milliseconds(1000); pub struct Throttle<'a> { time_provider: &'a TimeProvider, last_call: Option, + throttle_duration: Duration, } impl<'a> Throttle<'a> { pub fn new(time_provider: &'a TimeProvider) -> Self { + let throttle_duration = std::env::var(CUSTOMIZE_THROTTLE_ENVIRON_VARIABLE) + .ok() + // Parse as u32 to avoid corner cases with negative numbers + // and overflow when converting to i64. + .and_then(|raw| raw.parse::().ok()) + .map(|raw| Duration::milliseconds(raw as i64)) + .unwrap_or(THROTTLE_DEFAULT_DURATION); + Self { time_provider, last_call: None, + throttle_duration, } } pub async fn throttle(&mut self) { if let Some(last_call) = self.last_call { - let duration = last_call + THROTTLE_DURATION - self.time_provider.now(); + let duration = last_call + self.throttle_duration - self.time_provider.now(); self.time_provider.sleep(duration).await; } self.last_call = Some(self.time_provider.now());