1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! The ONE process-environment lock shared by every env-touching test in this
//! crate's `embedder` module tree.
//!
//! Why: env vars are process-global and Rust's test harness runs tests in
//! parallel threads within a single binary, so concurrent `setenv`/`getenv`
//! (even on disjoint keys) is unsound across libc implementations — Rust 2024
//! reflects this by marking `std::env::set_var` `unsafe`. It is ALSO a
//! correctness hazard beyond soundness: a test that mutates
//! `TRUSTY_EMBEDDER_MODEL` while another resolves the default model makes the
//! second test silently exercise the wrong model (issue #3711).
//!
//! This module exists because "one shared lock" was previously only true
//! per-file: `mod.rs`'s test module and `provider_tests.rs` each declared their
//! OWN static, and two independent locks do not serialise against each other —
//! so the #3711 race could still occur between a `TRUSTY_DEVICE` /
//! `TRUSTY_EMBEDDER_MODEL` mutation in one file and a model resolution in the
//! other. Hoisting the lock (and its RAII guard) to module scope makes the
//! guarantee real crate-wide instead of aspirational.
//!
//! What: [`ENV_LOCK`], a `std::sync::Mutex` every env-touching test in
//! `embedder` must hold for the whole window in which the env is mutated OR
//! read, plus [`EnvVarGuard`], the RAII set/restore helper.
//!
//! It is deliberately a SYNCHRONOUS mutex. An async test must therefore not
//! hold the guard across an `.await` (`clippy::await_holding_lock`); the
//! convention in this module tree is a plain `#[test]` driving an explicit
//! `tokio::runtime::Builder::new_current_thread()` runtime, which keeps the
//! lock held across the whole construct-and-embed window without an async lock
//! that sync tests could not share.
//! Test: used by `mod.rs`'s `mod tests`, `tests/reference_accuracy_tests.rs`,
//! and `provider_tests.rs`.
/// Process-global lock guarding every test in the `embedder` module tree that
/// mutates or reads the process environment.
///
/// Why/What: see the module docs — one lock for the whole module tree, held
/// across the entire mutate-and-observe window.
/// Test: `resolve_default_embedding_model_int8_opt_in`,
/// `default_model_matches_sentence_transformers_reference`,
/// `resolve_expected_python_provider_forces_cpu`.
pub static ENV_LOCK: Mutex = new;
/// RAII helper: set or clear an env var for the duration of a test and restore
/// it on drop.
///
/// Why: env vars are process-global; without restore, a stray value would skew
/// every later resolver call in the same binary. Restoring on `Drop` means an
/// assertion failure (an unwind) cannot leak the value into sibling tests
/// either.
/// What: captures the prior value, applies the new one (or removes it for
/// `None`), and reinstates the prior value on `Drop`.
/// Test: used by the `cuda_options_*`, `resolve_default_embedding_model_*`, and
/// `resolve_expected_python_provider_*` tests.
pub