# Test Scenario Env

> Generate a CoreRun-compatible .env file for a named CoreCLR test scenario defined by src/tests/Common/testenvironment.proj. Optionally merge the effective common and target-specific environment items from a specific src/tests project. USE FOR: "create an env file for jitstress1", "show the environment for this test under gcstress0xc", or scenario-aware standalone test repro generation. DO NOT USE FOR: library test scenarios, arbitrary user-defined environment files, or mobile, browser, WASI, Mono, and NativeAOT test hosting.

- Skill: `dotnet/test-scenario-env` (Agent Skill)
- Install (CLI): `npx skillmds@latest add dotnet/test-scenario-env`
- Raw SKILL.md: https://api.skillmd.com/api/skills/dotnet/test-scenario-env/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: .NET (Microsoft) (https://skillmd.com/u/dotnet)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/dotnet/test-scenario-env

---


# CoreCLR Test Scenario Environment

Generate a dotenv file consumable by:

```text
corerun[.exe] -e <path-to-env> <managed-test.dll>
```

Use `src/tests/Common/testenvironment.proj` as the source of truth. Do not
manually duplicate its scenario table or defaults in the skill.

## Inputs

Required:

- A scenario name from a `TestEnvironment` item in
  `src/tests/Common/testenvironment.proj`

Optional:

- A test `.csproj` under `src/tests/`; when supplied, merge its effective
  `CLRTestEnvironmentVariable` items and the applicable
  `CLRTestBatchEnvironmentVariable` or `CLRTestBashEnvironmentVariable` items
- Target OS, architecture, configuration, and runtime flavor
- Output path; default to
  `artifacts/tmp/test-scenario-env/<canonical-scenario>.env`

Default the target OS to the current host, architecture to `x64`,
configuration to `Release`, and runtime flavor to `coreclr`. Use the repro
directory's `.env` path when invoked by `standalone-test-repro`.

## Workflow

### 1. Resolve the Scenario

Read `src/tests/Common/testenvironment.proj` and match the requested name
against `TestEnvironment` item identities. Use the canonical identity from the
project in output and reporting.

If there is no exact scenario match, use `ask_user` with the closest concrete
scenario names. Do not silently emit an empty environment. If target-dependent
duplicates exist, select them by target OS using the project's conditions.

Reject scenarios outside managed desktop CoreCLR support for this skill.

### 2. Evaluate with MSBuild

Use the `build-and-test` skill before running the repository SDK. Invoke the
repository's bootstrapped `dotnet` to run the `CreateTestEnvFile` target rather
than interpreting scenario metadata manually.

Generate a temporary script under the same resolved output directory. Choose
the repository SDK entry point from the host OS, independently of the target OS.
Choose the temporary script extension and `TargetsWindows` value from the target
OS.

Windows host:

```text
.\dotnet.cmd msbuild src\tests\Common\testenvironment.proj /t:CreateTestEnvFile /p:Scenario=<scenario> "/p:TestEnvFileName=<resolved-output>\<temporary.cmd-or-sh>" /p:TargetsWindows=<true-or-false> /p:RuntimeVariant=<variant>
```

Non-Windows host:

```text
./dotnet.sh msbuild src/tests/Common/testenvironment.proj /t:CreateTestEnvFile /p:Scenario=<scenario> "/p:TestEnvFileName=<resolved-output>/<temporary.cmd-or-sh>" /p:TargetsWindows=<true-or-false> /p:RuntimeVariant=<variant>
```

Use a `.cmd` temporary file and `TargetsWindows=true` for a Windows target; use
a `.sh` file and `TargetsWindows=false` otherwise. This remains true for cross
builds. Omit `RuntimeVariant` when none was requested. Keep the generated value
for random scenarios such as `jitstress_random_1`; do not replace it with the
literal `random`.

### 3. Convert Scenario Output to Dotenv

Parse only assignments generated by `testenvironment.proj`:

- Windows: `set NAME=VALUE`
- Non-Windows: `export NAME=VALUE`

Ignore the shell shebang and other non-assignment lines. Encode an empty value
as `NAME=''`; a bare `NAME=` before another entry is not safe because CoreRun's
parser skips the following newline while looking for a value. Collapse
duplicate names using the last generated value.

Convert assignment values from the target shell's syntax to CoreRun dotenv
syntax; do not copy the shell text verbatim:

- Use the value written to the generated script. MSBuild decodes escaped item
  metadata before writing it, so `%2A` in `testenvironment.proj` is emitted as
  the literal wildcard `*`.
- For non-Windows scripts, convert shell variable references such as `$NAME` or
  `${NAME}` to CoreRun's supported `${NAME}` form. Do not expand them from the
  ambient environment while generating the file. For example, convert
  `$HELIX_DUMP_FOLDER/coredump.%d.dmp` to
  `${HELIX_DUMP_FOLDER}/coredump.%d.dmp`.
- Preserve non-expansion format tokens such as `%d`. To protect a literal `$`,
  single-quote the entire dotenv value so CoreRun does not interpret it as
  substitution; inside a single-quoted value, escape `\` as `\\` and `'` as
  `'`.

Write portable dotenv entries as `NAME=VALUE`, one per line. Quote or escape
whitespace, `#`, quotes, backslashes, newlines, and variable-expansion syntax
according to `src/coreclr/hosts/corerun/dotenv.cpp`. Never leave an unbraced
`$NAME` reference in the generated `.env`.

Delete only the specifically resolved temporary script after conversion.

### 4. Merge Test-Project Variables

When a test `.csproj` was supplied, evaluate its effective common
`CLRTestEnvironmentVariable` items and the selected target's
`CLRTestBatchEnvironmentVariable` or `CLRTestBashEnvironmentVariable` items for
the chosen OS, architecture, configuration, and runtime flavor, including
applicable imports and conditions.

Merge in runtime-wrapper order:

1. Scenario variables from `testenvironment.proj`
2. `CLRTestBatchEnvironmentVariable` items for a Windows target, or
   `CLRTestBashEnvironmentVariable` items for a non-Windows target
3. Common test-project `CLRTestEnvironmentVariable` items

Later values replace earlier values with the same name, including replacing
them with an empty value. This matches runtime wrapper behavior, which sources
`__TestEnv`, applies target-specific environment items, and then applies common
`CLRTestEnvironmentVariable` items.

Do not include the ambient process environment, CI credentials, or unrelated
MSBuild properties. Do not leave unevaluated expressions such as
`$(SomeProperty)` in the file.

### 5. Validate

Before completing:

1. Confirm the scenario exists for the selected target.
2. Compare scenario entries with the temporary script after applying the
   documented shell-to-dotenv normalization, before deleting it.
3. If a project was supplied, compare merged entries with its effective
   target-specific and common environment items and verify wrapper-order
   precedence.
4. Confirm `corerun -e <env-file>` can parse the generated file when a matching
   Core_Root is available.
5. Confirm the output is under `artifacts/tmp` unless the user explicitly chose
   another safe path.

## Final Response

Report the canonical scenario, output `.env` path, target OS and architecture,
and variable names. If a project was merged, report its path and any names whose
scenario values were overridden. Do not unnecessarily print sensitive values.

