diff --git a/Cargo.toml b/Cargo.toml index 6acc2c4ef..e9bf61321 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,7 +103,7 @@ futures-util = { version = "0.3.14", features = ["io"] } futures-executor = "0.3.14" hex = "0.4.0" hmac = "0.12.1" -lazy_static = "1.4.0" +once_cell = "1.19.0" log = { version = "0.4.17", optional = true } md-5 = "0.10.1" mongocrypt = { git = "https://github.com/mongodb/libmongocrypt-rust.git", branch = "main", optional = true } diff --git a/benchmarks/Cargo.toml b/benchmarks/Cargo.toml index 69ee831fb..b49ceef33 100644 --- a/benchmarks/Cargo.toml +++ b/benchmarks/Cargo.toml @@ -19,7 +19,7 @@ async-std-runtime = ["async-std", "mongodb/async-std-runtime"] [dependencies] mongodb = { path = "..", default-features = false } serde_json = "1.0.59" -lazy_static = "1.4.0" +once_cell = "1.19.0" clap = "2.33.3" indicatif = "0.15.0" async-trait = "0.1.41" diff --git a/benchmarks/src/bench.rs b/benchmarks/src/bench.rs index 56c4c6e35..b172db28c 100644 --- a/benchmarks/src/bench.rs +++ b/benchmarks/src/bench.rs @@ -21,34 +21,41 @@ use std::{ use anyhow::{bail, Result}; use futures::stream::TryStreamExt; use indicatif::{ProgressBar, ProgressStyle}; -use lazy_static::lazy_static; use mongodb::{ bson::{doc, Bson, Document}, options::{Acknowledgment, ClientOptions, SelectionCriteria, WriteConcern}, Client, }; +use once_cell::sync::Lazy; use serde_json::Value; use crate::fs::{BufReader, File}; -lazy_static! { - static ref DATABASE_NAME: String = option_env!("DATABASE_NAME") +static DATABASE_NAME: Lazy = Lazy::new(|| { + option_env!("DATABASE_NAME") .unwrap_or("perftest") - .to_string(); - static ref COLL_NAME: String = option_env!("COLL_NAME").unwrap_or("corpus").to_string(); - static ref MAX_EXECUTION_TIME: u64 = option_env!("MAX_EXECUTION_TIME") + .to_string() +}); +static COLL_NAME: Lazy = + Lazy::new(|| option_env!("COLL_NAME").unwrap_or("corpus").to_string()); +static MAX_EXECUTION_TIME: Lazy = Lazy::new(|| { + option_env!("MAX_EXECUTION_TIME") .unwrap_or("300") .parse::() - .expect("invalid MAX_EXECUTION_TIME"); - static ref MIN_EXECUTION_TIME: u64 = option_env!("MIN_EXECUTION_TIME") + .expect("invalid MAX_EXECUTION_TIME") +}); +static MIN_EXECUTION_TIME: Lazy = Lazy::new(|| { + option_env!("MIN_EXECUTION_TIME") .unwrap_or("60") .parse::() - .expect("invalid MIN_EXECUTION_TIME"); - pub static ref TARGET_ITERATION_COUNT: usize = option_env!("TARGET_ITERATION_COUNT") + .expect("invalid MIN_EXECUTION_TIME") +}); +pub static TARGET_ITERATION_COUNT: Lazy = Lazy::new(|| { + option_env!("TARGET_ITERATION_COUNT") .unwrap_or("100") .parse::() - .expect("invalid TARGET_ITERATION_COUNT"); -} + .expect("invalid TARGET_ITERATION_COUNT") +}); #[async_trait::async_trait] pub trait Benchmark: Sized { @@ -145,13 +152,13 @@ pub async fn drop_database(uri: &str, database: &str) -> Result<()> { .run_command(doc! { "hello": true }, None) .await?; - client.database(&database).drop(None).await?; + client.database(&database).drop().await?; // in sharded clusters, take additional steps to ensure database is dropped completely. // see: https://www.mongodb.com/docs/manual/reference/method/db.dropDatabase/#replica-set-and-sharded-clusters let is_sharded = hello.get_str("msg").ok() == Some("isdbgrid"); if is_sharded { - client.database(&database).drop(None).await?; + client.database(&database).drop().await?; for host in options.hosts { client .database("admin") diff --git a/benchmarks/src/bench/gridfs_multi_download.rs b/benchmarks/src/bench/gridfs_multi_download.rs index d02d070a2..622364ff5 100644 --- a/benchmarks/src/bench/gridfs_multi_download.rs +++ b/benchmarks/src/bench/gridfs_multi_download.rs @@ -5,18 +5,16 @@ use std::{ use anyhow::{Context, Result}; use futures::AsyncWriteExt; -use lazy_static::lazy_static; use mongodb::{bson::oid::ObjectId, gridfs::GridFsBucket, Client}; +use once_cell::sync::Lazy; use crate::{ bench::{drop_database, Benchmark, DATABASE_NAME}, fs::{open_async_read_compat, open_async_write_compat}, }; -lazy_static! { - static ref DOWNLOAD_PATH: PathBuf = - Path::new(env!("CARGO_MANIFEST_DIR")).join("gridfs_multi_download"); -} +static DOWNLOAD_PATH: Lazy = + Lazy::new(|| Path::new(env!("CARGO_MANIFEST_DIR")).join("gridfs_multi_download")); pub struct GridFsMultiDownloadBenchmark { uri: String, diff --git a/benchmarks/src/main.rs b/benchmarks/src/main.rs index dd027e0ea..9c12a983f 100644 --- a/benchmarks/src/main.rs +++ b/benchmarks/src/main.rs @@ -46,8 +46,8 @@ use clap::{App, Arg, ArgMatches}; use futures::Future; #[cfg(feature = "tokio-runtime")] use futures::FutureExt; -use lazy_static::lazy_static; use mongodb::options::ClientOptions; +use once_cell::sync::Lazy; use crate::{ bench::{ @@ -69,9 +69,7 @@ use crate::{ score::{score_test, BenchmarkResult, CompositeScore}, }; -lazy_static! { - static ref DATA_PATH: PathBuf = Path::new(env!("CARGO_MANIFEST_DIR")).join("data"); -} +static DATA_PATH: Lazy = Lazy::new(|| Path::new(env!("CARGO_MANIFEST_DIR")).join("data")); // benchmark names const FLAT_BSON_ENCODING: &'static str = "Flat BSON Encoding"; diff --git a/src/client/auth/aws.rs b/src/client/auth/aws.rs index 807a65f7f..06ec6ed87 100644 --- a/src/client/auth/aws.rs +++ b/src/client/auth/aws.rs @@ -2,7 +2,7 @@ use std::{fs::File, io::Read, time::Duration}; use chrono::{offset::Utc, DateTime}; use hmac::Hmac; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use rand::distributions::{Alphanumeric, DistString}; use serde::Deserialize; use sha2::{Digest, Sha256}; @@ -30,9 +30,7 @@ const AWS_EC2_IP: &str = "169.254.169.254"; const AWS_LONG_DATE_FMT: &str = "%Y%m%dT%H%M%SZ"; const MECH_NAME: &str = "MONGODB-AWS"; -lazy_static! { - static ref CACHED_CREDENTIAL: Mutex> = Mutex::new(None); -} +static CACHED_CREDENTIAL: Lazy>> = Lazy::new(|| Mutex::new(None)); /// Performs MONGODB-AWS authentication for a given stream. pub(super) async fn authenticate_stream( diff --git a/src/client/auth/scram.rs b/src/client/auth/scram.rs index fa5ef97a6..203590f2c 100644 --- a/src/client/auth/scram.rs +++ b/src/client/auth/scram.rs @@ -11,14 +11,14 @@ use hmac::{ Hmac, Mac, }; -use lazy_static::lazy_static; use md5::Md5; +use once_cell::sync::Lazy; use sha1::Sha1; use sha2::Sha256; use tokio::sync::RwLock; use crate::{ - bson::{doc, Bson, Document}, + bson::{Bson, Document}, client::{ auth::{ self, @@ -48,12 +48,9 @@ const NO_CHANNEL_BINDING: char = 'n'; /// The minimum number of iterations of the hash function that we will accept from the server. const MIN_ITERATION_COUNT: u32 = 4096; -lazy_static! { - /// Cache of pre-computed salted passwords. - static ref CREDENTIAL_CACHE: RwLock>> = { - RwLock::new(HashMap::new()) - }; -} +/// Cache of pre-computed salted passwords. +static CREDENTIAL_CACHE: Lazy>>> = + Lazy::new(|| RwLock::new(HashMap::new())); #[derive(Hash, Eq, PartialEq)] struct CacheEntry { diff --git a/src/client/auth/test.rs b/src/client/auth/test.rs index e7695e986..7f186bcda 100644 --- a/src/client/auth/test.rs +++ b/src/client/auth/test.rs @@ -1,15 +1,15 @@ -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use crate::{cmap::StreamDescription, options::AuthMechanism}; use super::sasl::SaslStart; -lazy_static! { - static ref MECHS: [String; 2] = [ +static MECHS: Lazy<[String; 2]> = Lazy::new(|| { + [ AuthMechanism::ScramSha1.as_str().to_string(), - AuthMechanism::ScramSha256.as_str().to_string() - ]; -} + AuthMechanism::ScramSha256.as_str().to_string(), + ] +}); #[test] fn negotiate_both_scram() { diff --git a/src/client/executor.rs b/src/client/executor.rs index 171452a50..4b2cb55b0 100644 --- a/src/client/executor.rs +++ b/src/client/executor.rs @@ -3,7 +3,7 @@ use bson::RawDocumentBuf; use bson::{doc, RawBsonRef, RawDocument, Timestamp}; #[cfg(feature = "in-use-encryption-unstable")] use futures_core::future::BoxFuture; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use serde::de::DeserializeOwned; use std::{ @@ -63,27 +63,25 @@ use crate::{ ClusterTime, }; -lazy_static! { - pub(crate) static ref REDACTED_COMMANDS: HashSet<&'static str> = { - let mut hash_set = HashSet::new(); - hash_set.insert("authenticate"); - hash_set.insert("saslstart"); - hash_set.insert("saslcontinue"); - hash_set.insert("getnonce"); - hash_set.insert("createuser"); - hash_set.insert("updateuser"); - hash_set.insert("copydbgetnonce"); - hash_set.insert("copydbsaslstart"); - hash_set.insert("copydb"); - hash_set - }; - pub(crate) static ref HELLO_COMMAND_NAMES: HashSet<&'static str> = { - let mut hash_set = HashSet::new(); - hash_set.insert("hello"); - hash_set.insert(LEGACY_HELLO_COMMAND_NAME_LOWERCASE); - hash_set - }; -} +pub(crate) static REDACTED_COMMANDS: Lazy> = Lazy::new(|| { + let mut hash_set = HashSet::new(); + hash_set.insert("authenticate"); + hash_set.insert("saslstart"); + hash_set.insert("saslcontinue"); + hash_set.insert("getnonce"); + hash_set.insert("createuser"); + hash_set.insert("updateuser"); + hash_set.insert("copydbgetnonce"); + hash_set.insert("copydbsaslstart"); + hash_set.insert("copydb"); + hash_set +}); +pub(crate) static HELLO_COMMAND_NAMES: Lazy> = Lazy::new(|| { + let mut hash_set = HashSet::new(); + hash_set.insert("hello"); + hash_set.insert(LEGACY_HELLO_COMMAND_NAME_LOWERCASE); + hash_set +}); impl Client { /// Execute the given operation. diff --git a/src/client/options.rs b/src/client/options.rs index 227c5da99..bc8cd5fc2 100644 --- a/src/client/options.rs +++ b/src/client/options.rs @@ -17,7 +17,7 @@ use std::{ use bson::UuidRepresentation; use derivative::Derivative; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use serde::{de::Unexpected, Deserialize, Deserializer, Serialize}; use serde_with::skip_serializing_none; use strsim::jaro_winkler; @@ -83,18 +83,14 @@ const URI_OPTIONS: &[&str] = &[ "zlibcompressionlevel", ]; -lazy_static! { - /// Reserved characters as defined by [Section 2.2 of RFC-3986](https://tools.ietf.org/html/rfc3986#section-2.2). - /// Usernames / passwords that contain these characters must instead include the URL encoded version of them when included - /// as part of the connection string. - static ref USERINFO_RESERVED_CHARACTERS: HashSet<&'static char> = { - [':', '/', '?', '#', '[', ']', '@'].iter().collect() - }; +/// Reserved characters as defined by [Section 2.2 of RFC-3986](https://tools.ietf.org/html/rfc3986#section-2.2). +/// Usernames / passwords that contain these characters must instead include the URL encoded version +/// of them when included as part of the connection string. +static USERINFO_RESERVED_CHARACTERS: Lazy> = + Lazy::new(|| [':', '/', '?', '#', '[', ']', '@'].iter().collect()); - static ref ILLEGAL_DATABASE_CHARACTERS: HashSet<&'static char> = { - ['/', '\\', ' ', '"', '$'].iter().collect() - }; -} +static ILLEGAL_DATABASE_CHARACTERS: Lazy> = + Lazy::new(|| ['/', '\\', ' ', '"', '$'].iter().collect()); /// An enum representing the address of a MongoDB server. #[derive(Clone, Debug, Eq, Serialize)] diff --git a/src/client/session.rs b/src/client/session.rs index eb9aa7f9e..779acc7a2 100644 --- a/src/client/session.rs +++ b/src/client/session.rs @@ -9,7 +9,7 @@ use std::{ time::{Duration, Instant}, }; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use uuid::Uuid; use crate::{ @@ -28,14 +28,12 @@ pub(super) use pool::ServerSessionPool; use super::{options::ServerAddress, AsyncDropToken}; -lazy_static! { - pub(crate) static ref SESSIONS_UNSUPPORTED_COMMANDS: HashSet<&'static str> = { - let mut hash_set = HashSet::new(); - hash_set.insert("killcursors"); - hash_set.insert("parallelcollectionscan"); - hash_set - }; -} +pub(crate) static SESSIONS_UNSUPPORTED_COMMANDS: Lazy> = Lazy::new(|| { + let mut hash_set = HashSet::new(); + hash_set.insert("killcursors"); + hash_set.insert("parallelcollectionscan"); + hash_set +}); /// A MongoDB client session. This struct represents a logical session used for ordering sequential /// operations. To create a `ClientSession`, call `start_session` on a `Client`. diff --git a/src/cmap/conn/wire/util.rs b/src/cmap/conn/wire/util.rs index a746ec273..719a8dfa6 100644 --- a/src/cmap/conn/wire/util.rs +++ b/src/cmap/conn/wire/util.rs @@ -3,13 +3,9 @@ use std::{ sync::atomic::{AtomicI32, Ordering}, }; -use lazy_static::lazy_static; - /// Closure to obtain a new, unique request ID. pub(crate) fn next_request_id() -> i32 { - lazy_static! { - static ref REQUEST_ID: AtomicI32 = AtomicI32::new(0); - } + static REQUEST_ID: AtomicI32 = AtomicI32::new(0); REQUEST_ID.fetch_add(1, Ordering::SeqCst) } diff --git a/src/cmap/establish/handshake.rs b/src/cmap/establish/handshake.rs index 07bbfc721..e58d50d4d 100644 --- a/src/cmap/establish/handshake.rs +++ b/src/cmap/establish/handshake.rs @@ -3,7 +3,7 @@ mod test; use std::env; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use crate::{ bson::{doc, Bson, Document}, @@ -260,28 +260,28 @@ impl FaasEnvironmentName { } } -lazy_static! { - /// Contains the basic handshake information that can be statically determined. This document - /// (potentially with additional fields added) can be cloned and put in the `client` field of - /// the `hello` or legacy hello command. - static ref BASE_CLIENT_METADATA: ClientMetadata = { - ClientMetadata { - application: None, - driver: DriverMetadata { - name: "mongo-rust-driver".into(), - version: env!("CARGO_PKG_VERSION").into(), - }, - os: OsMetadata { - os_type: std::env::consts::OS.into(), - architecture: Some(std::env::consts::ARCH.into()), - name: None, - version: None, - }, - platform: format!("{} with {}", rustc_version_runtime::version_meta().short_version_string, RUNTIME_NAME), - env: None, - } - }; -} +/// Contains the basic handshake information that can be statically determined. This document +/// (potentially with additional fields added) can be cloned and put in the `client` field of +/// the `hello` or legacy hello command. +static BASE_CLIENT_METADATA: Lazy = Lazy::new(|| ClientMetadata { + application: None, + driver: DriverMetadata { + name: "mongo-rust-driver".into(), + version: env!("CARGO_PKG_VERSION").into(), + }, + os: OsMetadata { + os_type: std::env::consts::OS.into(), + architecture: Some(std::env::consts::ARCH.into()), + name: None, + version: None, + }, + platform: format!( + "{} with {}", + rustc_version_runtime::version_meta().short_version_string, + RUNTIME_NAME + ), + env: None, +}); type Truncation = fn(&mut ClientMetadata); diff --git a/src/operation/insert/test.rs b/src/operation/insert/test.rs index 6e221a5d2..c8385338f 100644 --- a/src/operation/insert/test.rs +++ b/src/operation/insert/test.rs @@ -1,4 +1,4 @@ -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use crate::{ @@ -18,13 +18,13 @@ struct TestFixtures { /// Get an Insert operation and the documents/options used to construct it. fn fixtures(opts: Option) -> TestFixtures { - lazy_static! { - static ref DOCUMENTS: Vec = vec![ + static DOCUMENTS: Lazy> = Lazy::new(|| { + vec![ Document::new(), doc! {"_id": 1234, "a": 1}, doc! {"a": 123, "b": "hello world" }, - ]; - } + ] + }); let options = opts.unwrap_or(InsertManyOptions { ordered: Some(true), diff --git a/src/sdam/monitor.rs b/src/sdam/monitor.rs index ab127c133..cb5db9d14 100644 --- a/src/sdam/monitor.rs +++ b/src/sdam/monitor.rs @@ -7,7 +7,6 @@ use std::{ }; use bson::doc; -use lazy_static::lazy_static; use tokio::sync::watch; use super::{ @@ -31,9 +30,8 @@ use crate::{ }; fn next_monitoring_connection_id() -> u32 { - lazy_static! { - static ref MONITORING_CONNECTION_ID: AtomicU32 = AtomicU32::new(0); - } + static MONITORING_CONNECTION_ID: AtomicU32 = AtomicU32::new(0); + MONITORING_CONNECTION_ID.fetch_add(1, Ordering::SeqCst) } diff --git a/src/sdam/srv_polling/test.rs b/src/sdam/srv_polling/test.rs index fac2d5792..109711689 100644 --- a/src/sdam/srv_polling/test.rs +++ b/src/sdam/srv_polling/test.rs @@ -1,5 +1,6 @@ use std::{collections::HashSet, time::Duration}; +use once_cell::sync::Lazy; use pretty_assertions::assert_eq; use super::{LookupHosts, SrvPollingMonitor}; @@ -18,12 +19,12 @@ fn localhost_test_build_10gen(port: u16) -> ServerAddress { } } -lazy_static::lazy_static! { - static ref DEFAULT_HOSTS: Vec = vec![ +static DEFAULT_HOSTS: Lazy> = Lazy::new(|| { + vec![ localhost_test_build_10gen(27017), localhost_test_build_10gen(27108), - ]; -} + ] +}); async fn run_test(new_hosts: Result>, expected_hosts: HashSet) { run_test_srv(None, new_hosts, expected_hosts).await diff --git a/src/sync.rs b/src/sync.rs index 1fc498355..c1bcd7cb2 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -17,11 +17,11 @@ pub use cursor::{Cursor, SessionCursor, SessionCursorIter}; pub use db::Database; #[cfg(feature = "tokio-sync")] -lazy_static::lazy_static! { - pub(crate) static ref TOKIO_RUNTIME: tokio::runtime::Runtime = { - match tokio::runtime::Runtime::new() { - Ok(runtime) => runtime, - Err(err) => panic!("Error occurred when starting the underlying async runtime: {}", err) - } - }; -} +pub(crate) static TOKIO_RUNTIME: once_cell::sync::Lazy = + once_cell::sync::Lazy::new(|| match tokio::runtime::Runtime::new() { + Ok(runtime) => runtime, + Err(err) => panic!( + "Error occurred when starting the underlying async runtime: {}", + err + ), + }); diff --git a/src/sync/test.rs b/src/sync/test.rs index ab40620da..ca8f765dd 100644 --- a/src/sync/test.rs +++ b/src/sync/test.rs @@ -3,7 +3,7 @@ use std::{ io::{Read, Write}, }; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use pretty_assertions::assert_eq; use serde::{Deserialize, Serialize}; @@ -36,10 +36,8 @@ fn init_db_and_typed_coll(client: &Client, db_name: &str, coll_name: &str) -> coll } -lazy_static! { - static ref CLIENT_OPTIONS: ClientOptions = - runtime::block_on(async { crate::test::get_client_options().await.clone() }); -} +static CLIENT_OPTIONS: Lazy = + Lazy::new(|| runtime::block_on(async { crate::test::get_client_options().await.clone() })); #[test] fn client_options() { diff --git a/src/test.rs b/src/test.rs index 67ef6ff44..2f1c47f05 100644 --- a/src/test.rs +++ b/src/test.rs @@ -41,7 +41,7 @@ pub(crate) use self::{ }; use home::home_dir; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use tokio::sync::OnceCell; #[cfg(feature = "tracing-unstable")] @@ -66,54 +66,50 @@ pub(crate) async fn get_client_options() -> &'static ClientOptions { .await } -lazy_static! { - pub(crate) static ref DEFAULT_URI: String = get_default_uri(); - pub(crate) static ref SERVER_API: Option = match std::env::var("MONGODB_API_VERSION") - { +pub(crate) static DEFAULT_URI: Lazy = Lazy::new(get_default_uri); +pub(crate) static SERVER_API: Lazy> = + Lazy::new(|| match std::env::var("MONGODB_API_VERSION") { Ok(server_api_version) if !server_api_version.is_empty() => Some(ServerApi { version: ServerApiVersion::from_str(server_api_version.as_str()).unwrap(), deprecation_errors: None, strict: None, }), _ => None, - }; - pub(crate) static ref SERVERLESS: bool = - matches!(std::env::var("SERVERLESS"), Ok(s) if s == "serverless"); - pub(crate) static ref LOAD_BALANCED_SINGLE_URI: Option = - std::env::var("SINGLE_MONGOS_LB_URI").ok(); - pub(crate) static ref LOAD_BALANCED_MULTIPLE_URI: Option = - std::env::var("MULTI_MONGOS_LB_URI").ok(); - pub(crate) static ref ZSTD_COMPRESSION_ENABLED: bool = - matches!(std::env::var("ZSTD_COMPRESSION_ENABLED"), Ok(s) if s == "true"); - pub(crate) static ref ZLIB_COMPRESSION_ENABLED: bool = - matches!(std::env::var("ZLIB_COMPRESSION_ENABLED"), Ok(s) if s == "true"); - pub(crate) static ref SNAPPY_COMPRESSION_ENABLED: bool = - matches!(std::env::var("SNAPPY_COMPRESSION_ENABLED"), Ok(s) if s == "true"); - pub(crate) static ref SERVERLESS_ATLAS_USER: Option = - std::env::var("SERVERLESS_ATLAS_USER").ok(); - pub(crate) static ref SERVERLESS_ATLAS_PASSWORD: Option = - std::env::var("SERVERLESS_ATLAS_PASSWORD").ok(); -} + }); +pub(crate) static SERVERLESS: Lazy = + Lazy::new(|| matches!(std::env::var("SERVERLESS"), Ok(s) if s == "serverless")); +pub(crate) static LOAD_BALANCED_SINGLE_URI: Lazy> = + Lazy::new(|| std::env::var("SINGLE_MONGOS_LB_URI").ok()); +pub(crate) static LOAD_BALANCED_MULTIPLE_URI: Lazy> = + Lazy::new(|| std::env::var("MULTI_MONGOS_LB_URI").ok()); +pub(crate) static ZSTD_COMPRESSION_ENABLED: Lazy = + Lazy::new(|| matches!(std::env::var("ZSTD_COMPRESSION_ENABLED"), Ok(s) if s == "true")); +pub(crate) static ZLIB_COMPRESSION_ENABLED: Lazy = + Lazy::new(|| matches!(std::env::var("ZLIB_COMPRESSION_ENABLED"), Ok(s) if s == "true")); +pub(crate) static SNAPPY_COMPRESSION_ENABLED: Lazy = + Lazy::new(|| matches!(std::env::var("SNAPPY_COMPRESSION_ENABLED"), Ok(s) if s == "true")); +pub(crate) static SERVERLESS_ATLAS_USER: Lazy> = + Lazy::new(|| std::env::var("SERVERLESS_ATLAS_USER").ok()); +pub(crate) static SERVERLESS_ATLAS_PASSWORD: Lazy> = + Lazy::new(|| std::env::var("SERVERLESS_ATLAS_PASSWORD").ok()); // conditional definitions do not work within the lazy_static! macro, so this // needs to be defined separately. #[cfg(feature = "tracing-unstable")] -lazy_static! { - /// A global default tracing handler that will be installed the first time this - /// value is accessed. A global handler must be used anytime the multi-threaded - /// test runtime is in use, as non-global handlers only apply to the thread - /// they are registered in. - /// By default this handler will collect no tracing events. - /// Its minimum severity levels can be configured on a per-component basis using - /// [`TracingHandler:set_levels`]. The test lock MUST be acquired exclusively in - /// any test that will use the handler to avoid mixing events from multiple tests. - pub(crate) static ref DEFAULT_GLOBAL_TRACING_HANDLER: TracingHandler = { - let handler = TracingHandler::new(); - tracing::subscriber::set_global_default(handler.clone()) - .expect("setting global default tracing subscriber failed"); - handler - }; -} +/// A global default tracing handler that will be installed the first time this +/// value is accessed. A global handler must be used anytime the multi-threaded +/// test runtime is in use, as non-global handlers only apply to the thread +/// they are registered in. +/// By default this handler will collect no tracing events. +/// Its minimum severity levels can be configured on a per-component basis using +/// [`TracingHandler:set_levels`]. The test lock MUST be acquired exclusively in +/// any test that will use the handler to avoid mixing events from multiple tests. +pub(crate) static DEFAULT_GLOBAL_TRACING_HANDLER: Lazy = Lazy::new(|| { + let handler = TracingHandler::new(); + tracing::subscriber::set_global_default(handler.clone()) + .expect("setting global default tracing subscriber failed"); + handler +}); pub(crate) fn update_options_for_testing(options: &mut ClientOptions) { if options.server_api.is_none() { diff --git a/src/test/coll.rs b/src/test/coll.rs index a547de2cd..dd47e04a1 100644 --- a/src/test/coll.rs +++ b/src/test/coll.rs @@ -8,7 +8,7 @@ use crate::{ }; use bson::{rawdoc, RawDocumentBuf}; use futures::stream::{StreamExt, TryStreamExt}; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use semver::VersionReq; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -336,9 +336,9 @@ async fn no_kill_cursors_on_exhausted() { assert!(!kill_cursors_sent(&event_client)); } -lazy_static! { - #[allow(clippy::unreadable_literal)] - static ref LARGE_DOC: Document = doc! { +#[allow(clippy::unreadable_literal)] +static LARGE_DOC: Lazy = Lazy::new(|| { + doc! { "text": "the quick brown fox jumped over the lazy sheep dog", "in_reply_to_status_id": 22213321312i64, "retweet_count": Bson::Null, @@ -386,8 +386,8 @@ lazy_static! { "listed_count": 1, "lang": "en" } - }; -} + } +}); #[cfg_attr(feature = "tokio-runtime", tokio::test)] #[cfg_attr(feature = "async-std-runtime", async_std::test)] diff --git a/src/test/csfle.rs b/src/test/csfle.rs index 91ae9f5a5..577f8a147 100644 --- a/src/test/csfle.rs +++ b/src/test/csfle.rs @@ -24,8 +24,8 @@ use bson::{ RawDocumentBuf, }; use futures_util::TryStreamExt; -use lazy_static::lazy_static; use mongocrypt::ctx::{Algorithm, KmsProvider}; +use once_cell::sync::Lazy; #[cfg(feature = "tokio-runtime")] use tokio::net::TcpListener; @@ -91,85 +91,88 @@ async fn init_client() -> Result<(EventClient, Collection)> { pub(crate) type KmsProviderList = Vec<(KmsProvider, bson::Document, Option)>; -lazy_static! { - static ref KMS_PROVIDERS: KmsProviderList = { - fn env(name: &str) -> String { - std::env::var(name).unwrap() - } - vec![ - ( - KmsProvider::Aws, - doc! { - "accessKeyId": env("AWS_ACCESS_KEY_ID"), - "secretAccessKey": env("AWS_SECRET_ACCESS_KEY"), - }, - None, - ), - ( - KmsProvider::Azure, - doc! { - "tenantId": env("AZURE_TENANT_ID"), - "clientId": env("AZURE_CLIENT_ID"), - "clientSecret": env("AZURE_CLIENT_SECRET"), - }, - None, - ), - ( - KmsProvider::Gcp, - doc! { - "email": env("GCP_EMAIL"), - "privateKey": env("GCP_PRIVATE_KEY"), - }, - None, - ), - ( - KmsProvider::Local, - doc! { - "key": bson::Binary { - subtype: bson::spec::BinarySubtype::Generic, - bytes: base64::decode(env("CSFLE_LOCAL_KEY")).unwrap(), - }, - }, - None, - ), - ( - KmsProvider::Kmip, - doc! { - "endpoint": "localhost:5698", - }, - { - let cert_dir = PathBuf::from(env("CSFLE_TLS_CERT_DIR")); - Some( - TlsOptions::builder() - .ca_file_path(cert_dir.join("ca.pem")) - .cert_key_file_path(cert_dir.join("client.pem")) - .build(), - ) +static KMS_PROVIDERS: Lazy = Lazy::new(|| { + fn env(name: &str) -> String { + std::env::var(name).unwrap() + } + vec![ + ( + KmsProvider::Aws, + doc! { + "accessKeyId": env("AWS_ACCESS_KEY_ID"), + "secretAccessKey": env("AWS_SECRET_ACCESS_KEY"), + }, + None, + ), + ( + KmsProvider::Azure, + doc! { + "tenantId": env("AZURE_TENANT_ID"), + "clientId": env("AZURE_CLIENT_ID"), + "clientSecret": env("AZURE_CLIENT_SECRET"), + }, + None, + ), + ( + KmsProvider::Gcp, + doc! { + "email": env("GCP_EMAIL"), + "privateKey": env("GCP_PRIVATE_KEY"), + }, + None, + ), + ( + KmsProvider::Local, + doc! { + "key": bson::Binary { + subtype: bson::spec::BinarySubtype::Generic, + bytes: base64::decode(env("CSFLE_LOCAL_KEY")).unwrap(), }, - ), - ] - }; - static ref LOCAL_KMS: KmsProviderList = KMS_PROVIDERS + }, + None, + ), + ( + KmsProvider::Kmip, + doc! { + "endpoint": "localhost:5698", + }, + { + let cert_dir = PathBuf::from(env("CSFLE_TLS_CERT_DIR")); + Some( + TlsOptions::builder() + .ca_file_path(cert_dir.join("ca.pem")) + .cert_key_file_path(cert_dir.join("client.pem")) + .build(), + ) + }, + ), + ] +}); +static LOCAL_KMS: Lazy = Lazy::new(|| { + KMS_PROVIDERS .iter() .filter(|(p, ..)| p == &KmsProvider::Local) .cloned() - .collect(); - pub(crate) static ref KMS_PROVIDERS_MAP: HashMap< + .collect() +}); +pub(crate) static KMS_PROVIDERS_MAP: Lazy< + HashMap< mongocrypt::ctx::KmsProvider, (bson::Document, Option), - > = { - let mut map = HashMap::new(); - for (prov, conf, tls) in KMS_PROVIDERS.clone() { - map.insert(prov, (conf, tls)); - } - map - }; - static ref EXTRA_OPTIONS: Document = - doc! { "cryptSharedLibPath": std::env::var("CRYPT_SHARED_LIB_PATH").unwrap() }; - static ref KV_NAMESPACE: Namespace = Namespace::from_str("keyvault.datakeys").unwrap(); - static ref DISABLE_CRYPT_SHARED: bool = - std::env::var("DISABLE_CRYPT_SHARED").map_or(false, |s| s == "true"); -} + >, +> = Lazy::new(|| { + let mut map = HashMap::new(); + for (prov, conf, tls) in KMS_PROVIDERS.clone() { + map.insert(prov, (conf, tls)); + } + map +}); +static EXTRA_OPTIONS: Lazy = + Lazy::new(|| doc! { "cryptSharedLibPath": std::env::var("CRYPT_SHARED_LIB_PATH").unwrap() }); +static KV_NAMESPACE: Lazy = + Lazy::new(|| Namespace::from_str("keyvault.datakeys").unwrap()); +static DISABLE_CRYPT_SHARED: Lazy = + Lazy::new(|| std::env::var("DISABLE_CRYPT_SHARED").map_or(false, |s| s == "true")); fn check_env(name: &str, kmip: bool) -> bool { if std::env::var("CSFLE_LOCAL_KEY").is_err() { diff --git a/src/test/spec/unified_runner/matcher.rs b/src/test/spec/unified_runner/matcher.rs index 3bf7eee70..f37d118ab 100644 --- a/src/test/spec/unified_runner/matcher.rs +++ b/src/test/spec/unified_runner/matcher.rs @@ -82,7 +82,7 @@ pub(crate) fn tracing_events_match( } } - use lazy_static::lazy_static; + use once_cell::sync::Lazy; use regex::Regex; if let Some(failure_should_be_redacted) = expected.failure_is_redacted { @@ -90,17 +90,21 @@ pub(crate) fn tracing_events_match( Some(failure) => { match failure { TracingEventValue::String(failure_str) => { - // lazy_static saves us having to recompile this regex every time this + // `Lazy` saves us having to recompile this regex every time this // function is called. - lazy_static! { - static ref COMMAND_FAILED_REGEX: Regex = Regex::new( - r"^Kind: Command failed: Error code (?P\d+) \((?P.+)\): (?P.+)+, labels: (?P.+)$" - ).unwrap(); - static ref IO_ERROR_REGEX: Regex = Regex::new( - r"^Kind: I/O error: (?P.+), labels: (?P.+)$" - ).unwrap(); - } + static COMMAND_FAILED_REGEX: Lazy = Lazy::new(|| { + Regex::new( + r"^Kind: Command failed: Error code (?P\d+) \((?P.+)\): (?P.+)+, labels: (?P.+)$" + ).unwrap() + }); + + static IO_ERROR_REGEX: Lazy = Lazy::new(|| { + Regex::new( + r"^Kind: I/O error: (?P.+), labels: (?P.+)$", + ) + .unwrap() + }); // We redact all server-returned errors, however at this time the only types // of errors that show up in tracing redaction tests