-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Improve Copilot guidance for R2R tests and regression verification #125833
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,97 @@ | ||||||||||||||||||||||||||||||||||
| # ReadyToRun Tests | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| These tests validate ReadyToRun (R2R) behavior in the CoreCLR test suite, especially crossgen2 compilation correctness, cross-module compilation behavior, platform-specific code generation, and determinism. The directory contains both harness-driven tests and tests that invoke crossgen2 manually when they need more control over inputs or emitted artifacts. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ## Test Patterns | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ### Pattern 1: Built-in Harness (preferred for simple tests) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Use the built-in harness when a test only needs the standard ReadyToRun pipeline for a single assembly. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - Enable it with `<AlwaysUseCrossGen2>true</AlwaysUseCrossGen2>`. | ||||||||||||||||||||||||||||||||||
| - Add extra crossgen2 switches when needed with `<CrossGen2TestExtraArguments>`. | ||||||||||||||||||||||||||||||||||
| - Examples: | ||||||||||||||||||||||||||||||||||
| - `crossgen2/crossgen2smoke.csproj` for the basic harness-driven pattern | ||||||||||||||||||||||||||||||||||
| - `HardwareIntrinsics/` for harness-driven tests with extra instruction-set flags | ||||||||||||||||||||||||||||||||||
| - `GenericCycleDetection/` for harness-driven tests with extra cycle-detection flags | ||||||||||||||||||||||||||||||||||
| - When to use: single-assembly compilation, standard validation, or tests that only need a few extra crossgen2 switches. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| This pattern is the simplest to maintain because the normal test infrastructure handles the crossgen2 invocation and test execution. For example, `GenericCycleDetection/*.csproj` enables `AlwaysUseCrossGen2` and adds cycle-detection options through `CrossGen2TestExtraArguments`, while `HardwareIntrinsics/X86/*.csproj` appends instruction-set flags the same way. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ### Pattern 2: Manual crossgen2 Invocation | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Use manual crossgen2 invocation when the built-in harness is not expressive enough. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - Disable automatic crossgen with `<CrossGenTest>false</CrossGenTest>`. | ||||||||||||||||||||||||||||||||||
| - Run custom compilation steps with `CLRTestBashPreCommands` (and usually matching `CLRTestBatchPreCommands` for Windows). | ||||||||||||||||||||||||||||||||||
| - When to use: need `--map`, `--inputbubble`, `--opt-cross-module`, multi-step compilation, or platform-specific scripting. | ||||||||||||||||||||||||||||||||||
| - Examples: | ||||||||||||||||||||||||||||||||||
| - `tests/mainv1.csproj` | ||||||||||||||||||||||||||||||||||
| - `determinism/crossgen2determinism.csproj` | ||||||||||||||||||||||||||||||||||
| - `ObjCPInvokeR2R/ObjCPInvokeR2R.csproj` | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| This pattern is common when a test must stage input assemblies, compile multiple outputs in a specific order, compare multiple generated binaries, or run platform-specific shell logic before execution. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| ## Map File Validation | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| When using `--map` to validate R2R compilation: | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - **`MethodWithGCInfo`** entries represent actual compiled native code in the ReadyToRun image. This is the signal to use when asserting that a method was precompiled. | ||||||||||||||||||||||||||||||||||
| - **`MethodFixupSignature`** entries are metadata or signature references. They do not prove that the method body was compiled. | ||||||||||||||||||||||||||||||||||
| - **`DelayLoadHelperImport`** entries are call-site fixups. They are also metadata-related and are not proof of compilation. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Always check for `MethodWithGCInfo` when asserting that a method was precompiled into the R2R image. `ObjCPInvokeR2R/ObjCPInvokeR2R.cs` and `tests/test.cs` both use this rule when validating map output. | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
| Always check for `MethodWithGCInfo` when asserting that a method was precompiled into the R2R image. `ObjCPInvokeR2R/ObjCPInvokeR2R.cs` and `tests/test.cs` both use this rule when validating map output. | |
| Always check for `MethodWithGCInfo` when asserting that a method was precompiled into the R2R image. For example, `tests/test.cs` uses this rule when validating map output. |
Copilot
AI
Mar 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The platform-gating example refers to ObjCPInvokeR2R.csproj and a specific $(TargetsOSX) condition, but there is no such project under src/tests/readytorun/ in this branch. Please update the example to reference an existing ReadyToRun test project in this directory that uses CLRTestTargetUnsupported/DisableProjectBuild, or remove the file-specific example.
| In practice, this is why tests like `ObjCPInvokeR2R` use manual crossgen2 invocation with `--inputbubble`. | |
| ## Platform Gating | |
| Use MSBuild conditions to keep ReadyToRun tests targeted to the environments they actually validate. | |
| - Use `<CLRTestTargetUnsupported Condition="...">true</CLRTestTargetUnsupported>` for platform-specific tests. | |
| - Example: `ObjCPInvokeR2R.csproj` uses `Condition="'$(TargetsOSX)' != 'true'"` because `objc_msgSend` behavior is only relevant on Apple platforms. | |
| In practice, this is why some tests in this directory use manual crossgen2 invocation with `--inputbubble` instead of the built-in harness. | |
| ## Platform Gating | |
| Use MSBuild conditions to keep ReadyToRun tests targeted to the environments they actually validate. | |
| - Use `<CLRTestTargetUnsupported Condition="...">true</CLRTestTargetUnsupported>` for platform-specific tests. | |
| - Example condition: `Condition="'$(TargetsOSX)' != 'true'"` for tests that rely on macOS-specific behavior such as `objc_msgSend`. |
Copilot
AI
Mar 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The build/run snippet mixes configurations: it builds tests as checked, generates Core_Root as Release, and then cds into a Debug test output directory while running with the Release Core_Root. This is likely to produce incorrect instructions and hard-to-diagnose failures. Please make the example consistent (e.g., use a single <buildType> placeholder for both build output and CORE_ROOT, and cd into the matching <buildType> directory).
| src/tests/build.sh checked -tree:src/tests/readytorun | |
| # Generate Core_Root layout (required for manual runs) | |
| src/tests/build.sh -GenerateLayoutOnly x64 Release | |
| # Run a single test manually | |
| export CORE_ROOT=$(pwd)/artifacts/tests/coreclr/<os>.<arch>.Release/Tests/Core_Root | |
| cd artifacts/tests/coreclr/<os>.<arch>.Debug/readytorun/<TestName>/ | |
| src/tests/build.sh <buildType> -tree:src/tests/readytorun | |
| # Generate Core_Root layout (required for manual runs) | |
| src/tests/build.sh -GenerateLayoutOnly x64 <buildType> | |
| # Run a single test manually | |
| export CORE_ROOT=$(pwd)/artifacts/tests/coreclr/<os>.<arch>.<buildType>/Tests/Core_Root | |
| cd artifacts/tests/coreclr/<os>.<arch>.<buildType>/readytorun/<TestName>/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ObjCPInvokeR2R/ObjCPInvokeR2R.csprojis referenced as an example, but there is noObjCPInvokeR2Rdirectory/test undersrc/tests/readytorun/in this branch. This will confuse readers; either update the example to point to an existing test in this folder or add a note that this example comes from an out-of-tree/other PR.