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
//! Shared helpers for tests with process-wide side effects.
//!
//! Some tests touch process-global state — redirecting std fds, closing
//! inherited fds, forking, changing the umask — that corrupts the shared test
//! harness or clobbers state used by tests running in parallel. Two tools
//! contain the damage:
//!
//! - A test whose effects cannot be undone in-process (fd closing, forking) is
//! marked `#[ignore]` and paired with a wrapper that re-invokes the test
//! binary for just that one test via [`run_in_subprocess`]. The body guards
//! on [`is_subprocess`] so it executes only when spawned this way.
//! - Reversible global state (the umask) gets an RAII guard ([`UmaskGuard`])
//! so a panicking assertion cannot leak the altered state.
use Command;
/// RAII guard: sets the process umask and restores the previous one on drop.
///
/// Restoring in a `Drop` (rather than a trailing statement) means a panicking
/// assertion between set and restore cannot leak the altered umask into tests
/// running in parallel. Pair with `#[serial]` on the test so concurrent umask
/// users are excluded too.
pub
/// Environment variable set in the spawned subprocess so the `#[ignore]` test
/// body knows it is running in isolation (see [`is_subprocess`]).
const SUBPROCESS_ENV: &str = "__BLIVET_SUBPROCESS_TEST";
/// Returns `true` when running inside a subprocess spawned by
/// [`run_in_subprocess`].
pub
/// Re-invokes the test binary to run a single `#[ignore]` test in its own
/// process, then asserts it succeeded.
///
/// `--include-ignored` is required: without it the named `#[ignore]` test is
/// skipped, the subprocess exits 0, and this helper passes *vacuously* without
/// ever running the test body.
pub