diff --git a/fixtures/nextest-tests/tests/basic.rs b/fixtures/nextest-tests/tests/basic.rs index 0ab3ccfbb16..4938521114b 100644 --- a/fixtures/nextest-tests/tests/basic.rs +++ b/fixtures/nextest-tests/tests/basic.rs @@ -144,6 +144,10 @@ macro_rules! assert_env { }; } +fn check_env(env: &str) -> String { + std::env::var(env).expect(&format!("{env} must be set")) +} + /// Assert that test environment variables are correctly set. #[test] fn test_cargo_env_vars() { @@ -156,7 +160,7 @@ fn test_cargo_env_vars() { Ok("1"), "NEXTEST environment variable set to 1" ); - std::env::var("NEXTEST_RUN_ID") + let run_id = std::env::var("NEXTEST_RUN_ID") .expect("NEXTEST_RUN_ID must be set") .parse::() .expect("NEXTEST_RUN_ID must be a UUID"); @@ -172,6 +176,38 @@ fn test_cargo_env_vars() { "NEXTEST_EXECUTION_MODE set to process-per-test" ); + assert_eq!( + check_env("NEXTEST_ATTEMPT"), + nextest_attempt().to_string(), + "NEXTEST_ATTEMPT and __NEXTEST_ATTEMPT must be equal" + ); + + let test_name = "test_cargo_env_vars"; + assert_eq!(check_env("NEXTEST_TEST_NAME"), test_name); + let binary_id = "nextest-tests::basic"; + assert_eq!(check_env("NEXTEST_BINARY_ID"), binary_id); + + // The test might run with 1 or 3 total attempts + assert!(&["1", "3"].contains(&check_env("NEXTEST_TOTAL_ATTEMPTS").as_str())); + + assert_eq!(check_env("NEXTEST_STRESS_CURRENT"), "none"); + assert_eq!(check_env("NEXTEST_STRESS_TOTAL"), "none"); + + let attempt_id = check_env("NEXTEST_ATTEMPT_ID"); + + let (attempt_id_run_id, attempt_id) = attempt_id + .split_once(':') + .expect("NEXTEST_ATTEMPT_ID must contain ':'"); + let attempt_id_run_id = attempt_id_run_id + .parse::() + .expect("NEXTEST_ATTEMPT_ID Run ID must be a UUID"); + let (attempt_id_binary_id, attempt_id_test_name) = attempt_id + .split_once('$') + .expect("NEXTEST_ATTEMPT_ID must contain '$'"); + assert_eq!(attempt_id_run_id, run_id); + assert_eq!(attempt_id_binary_id, binary_id); + assert_eq!(attempt_id_test_name, test_name); + // https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates // Note: we do not test CARGO here because nextest does not set it -- it's set by Cargo when diff --git a/nextest-runner/src/runner/executor.rs b/nextest-runner/src/runner/executor.rs index 66e3bcf6aab..017ae7b958a 100644 --- a/nextest-runner/src/runner/executor.rs +++ b/nextest-runner/src/runner/executor.rs @@ -680,10 +680,41 @@ impl<'a> ExecutorContext<'a> { let command_mut = cmd.command_mut(); // Debug environment variable for testing. - command_mut.env("__NEXTEST_ATTEMPT", format!("{}", test.retry_data.attempt)); + let attempt = format!("{}", test.retry_data.attempt); + command_mut.env("__NEXTEST_ATTEMPT", &attempt); + command_mut.env("NEXTEST_ATTEMPT", attempt); command_mut.env("NEXTEST_RUN_ID", format!("{}", self.run_id)); + command_mut.env("NEXTEST_TEST_NAME", test.test_instance.name); + command_mut.env( + "NEXTEST_BINARY_ID", + test.test_instance.suite_info.binary_id.as_str(), + ); + + let attempt_id = test.test_instance.id().attempt_id( + self.run_id, + test.stress_index.map(|s| s.current), + test.retry_data.attempt, + ); + command_mut.env("NEXTEST_ATTEMPT_ID", &attempt_id); + command_mut.env( + "NEXTEST_TOTAL_ATTEMPTS", + test.retry_data.total_attempts.to_string(), + ); + + let stress_current = test + .stress_index + .map(|s| s.current.to_string()) + .unwrap_or_else(|| "none".into()); + let stress_total = test + .stress_index + .and_then(|s| s.total) + .map(|s| s.to_string()) + .unwrap_or_else(|| "none".into()); + command_mut.env("NEXTEST_STRESS_CURRENT", stress_current); + command_mut.env("NEXTEST_STRESS_TOTAL", stress_total); + // Set group and slot environment variables. command_mut.env( "NEXTEST_TEST_GLOBAL_SLOT", @@ -782,11 +813,7 @@ impl<'a> ExecutorContext<'a> { let child_pid_for_kill = ChildPid::Process(child_pid); crate::fire_usdt!(UsdtTestAttemptStart { - attempt_id: test.test_instance.id().attempt_id( - self.run_id, - test.stress_index.map(|s| s.current), - test.retry_data.attempt, - ), + attempt_id, run_id: self.run_id, binary_id: test.test_instance.suite_info.binary_id.clone(), test_name: test.test_instance.name.to_owned(),