Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer - #9941

Merged
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider
Jul 15, 2026
Merged

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer#9941
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Jul 14, 2026

Copy link
Copy Markdown
Member

Summary

[AssemblyFixtureProvider] cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies() + load-by-name via AssemblyLoadContext). That is fundamentally a reflection/runtime-loading mechanism and cannot be made reflection-free by the source generator. Under Native AOT it also surfaced an IL2026 — the last MSTest-owned trim/AOT warning a consumer hit when publishing a Native AOT test app with MSTestSourceGenMode=ReflectionFree and warnings-as-errors.

Rather than paper over it with a suppression, this PR makes the behavior explicit: skip the feature when dynamic code is unsupported, and surface it both at build time (analyzer) and at run time (trace warning).

Changes

1. Skip discovery when dynamic code is unsupported (TypeCache.ProviderDiscovery.cs)
Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported. Because ILC constant-folds that switch to false under AOT, the guarded reflection path is statically removed — so the IL2026 disappears with no suppression needed (same pattern already used in DataSerializationHelper).

2. Best-effort runtime warning
When discovery is skipped, emit a trace warning so consumers are not silently deprived of their fixtures. It scans the already-loaded assemblies (AppDomain.GetAssemblies, metadata-only via CustomAttributeData, with per-assembly failure isolation) — it deliberately does not walk the reference graph, so it stays AOT-safe. Consequently it can only see markers on assemblies that happen to be loaded (e.g. a self-applied marker on the test assembly); an unloaded referenced provider is not detectable at run time AOT-safely. Referenced providers are instead covered at build time by the analyzer. The warning is emitted through MTP's diagnostic logger (--diagnostic output).

3. New analyzer MSTEST0072AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzer
Warns at build time when the project opts into an AOT flavor detectable at build time — PublishAot (Native AOT) orRunAOTCompilation (Blazor WebAssembly AOT) — and [AssemblyFixtureProvider] is in play. It inspects both the compilation's own assembly attributes (reported at the attribute location) and referenced assemblies' attributes (reported as a no-location diagnostic), so the documented default usage — the attribute placed on a referenced fixture library consumed by an AOT test project — is covered. PublishAot and RunAOTCompilation are exposed to analyzers via new CompilerVisibleProperty entries in MSTest.TestAdapter.targets. Includes resources (+ regenerated xlf for all 13 locales), AnalyzerReleases.Unshipped.md entry, and unit tests (including the referenced-assembly and RunAOTCompilation scenarios).

4. Acceptance testAssemblyFixtureProviderNativeAotTests verifies that under PublishAot=true (which sets IsDynamicCodeSupported=false for a managed build) the referenced provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.

Notes

  • Analyzer coverage. MSTEST0072 detects [AssemblyFixtureProvider] whether it is declared in the compilation being built or on a referenced library, and it triggers on both build-time-detectable AOT flavors (PublishAot, RunAOTCompilation). The only case it cannot cover is a runtime that disables dynamic code without either build property being set (e.g. Mono iOS AOT), where there is no build-time signal to key off; the best-effort runtime trace warning is the fallback there, limited to already-loaded assemblies as described in change Porting latest changes. #2.
  • Supersedes the earlier suppression-based commit on this branch.

Validation

  • dotnet build of the adapter (net8.0) and MSTest.Analyzers → 0 errors (release-tracking analyzer satisfied).
  • New analyzer unit tests (7, incl. referenced-assembly and RunAOTCompilation cases) pass on net8.0.
  • Downstream: with discovery skipped under AOT, the reflection-free Native AOT publish reaches native codegen with no MSTest-owned IL20xx/IL30xx warnings.

CopilotAI review requested due to automatic review settings July 14, 2026 14:17

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Suppresses the IL2026 trim/AOT warning from assembly fixture provider discovery while extending acceptance-test coverage.

Changes:

  • Isolates and suppresses Assembly.GetReferencedAssemblies().
  • Adds the source file to trim/AOT warning assertions.
Show a summary per file
FileDescription
TypeCache.ProviderDiscovery.csAdds the scoped IL2026 suppression helper.
TrimAndAotAssertions.csGuards against future trim/AOT warnings from provider discovery.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actions

This comment has been minimized.

AssemblyFixtureProvider cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies + load-by-name), which requires capabilities not available when the runtime cannot generate dynamic code (Native AOT, Mono iOS AOT, Blazor WASM AOT). Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported so the feature is skipped there.
Because the ILC substitutes IsDynamicCodeSupported with a constant under AOT, the guarded reflection path is statically removed, so the previously-surfaced IL2026 (from Assembly.GetReferencedAssemblies) disappears without needing an inline suppression. This supersedes the earlier suppression approach.
…ative AOT
Since [AssemblyFixtureProvider] discovery is now skipped under Native AOT (it relies on walking the runtime assembly reference graph), add an analyzer that warns at build time when a project both opts into PublishAot and declares [assembly: AssemblyFixtureProvider], so the silently-ignored feature is surfaced to the user.
PublishAot is exposed to analyzers via a new CompilerVisibleProperty in MSTest.TestAdapter.targets. The diagnostic reports at each attribute application; includes resources (+ regenerated xlf), release tracking, and unit tests.
CopilotAI review requested due to automatic review settings July 14, 2026 15:37
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/aot-il2026-assembly-fixture-provider branch from 359ff8b to b54f046CompareJuly 14, 2026 15:37
@EvangelinkAmaury Levé (Evangelink) changed the title Suppress IL2026 in AssemblyFixtureProvider assembly discoverySkip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzerJul 14, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 15, 2026
…ime warning
- MSTEST0072 now also inspects referenced assemblies' attributes, so the documented default usage (attribute on a referenced fixture library) is flagged with a no-location diagnostic on the consuming Native AOT project, not just self-applied attributes.
- Add a runtime warning when discovery is skipped because dynamic code is unsupported, covering Mono iOS AOT and Blazor WebAssembly AOT which the PublishAot-keyed analyzer cannot reach. The check is metadata-only (HasAssemblyFixtureProviderMarker) so it stays AOT-safe.
- Use explicit LINQ filtering (.Where/.Any) in the analyzer loops per code-quality feedback.
- Add unit tests for the referenced-assembly scenario (PublishAot true and false).
CopilotAI review requested due to automatic review settings July 15, 2026 07:37

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 8
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs
@github-actions

This comment has been minimized.

…tance test, encoding, LINQ
- Runtime warning now scans already-loaded assemblies (AppDomain.GetAssemblies, metadata-only) instead of only the test assembly, so a referenced provider library is no longer silent on Mono iOS / Blazor WASM AOT. Stays AOT-safe (no reference-graph walk).
- Add acceptance test AssemblyFixtureProviderNativeAotTests verifying that under PublishAot=true (IsDynamicCodeSupported=false, managed) the provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.
- Restore UTF-8 BOM on all touched .cs files per .editorconfig.
- Use explicit .Where(...) in the referenced-assembly loop.
CopilotAI review requested due to automatic review settings July 15, 2026 08:00

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

- Isolate per-assembly failures in the runtime warning loop (try/catch around the metadata probe) so unresolvable custom-attribute metadata on one loaded assembly cannot abort discovery, matching the normal discovery path. Clarify in comments that the runtime probe is best-effort (already-loaded assemblies only) and that referenced-provider coverage is the analyzer's responsibility.
- Broaden MSTEST0072 to also trigger on RunAOTCompilation (Blazor WebAssembly AOT) in addition to PublishAot, giving build-time detection for another dynamic-code-disabled runtime. Added RunAOTCompilation as a CompilerVisibleProperty and a unit test.
- Replace the referenced-assembly foreach (whose loop variable was unused) with a single .Any(...) check that reports one no-location diagnostic, fixing the useless-assignment warning.
CopilotAI review requested due to automatic review settings July 15, 2026 08:35
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Resources.resx Outdated
MSTEST0072 now triggers on RunAOTCompilation (Blazor WebAssembly AOT) as well as PublishAot, so the diagnostic title/message/description no longer say only 'Native AOT'. Reword to 'ahead-of-time compilation (such as Native AOT or Blazor WebAssembly AOT)' and regenerate the XLF files for all locales.
CopilotAI review requested due to automatic review settings July 15, 2026 09:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9941

GradeTestNotes
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
AttributeOnReferencedAssembly_
NoDiagnostic
Strong negative assertion via RunAsync(); body is ~45 lines due to multi-project string literals — consider extracting shared setup into a helper to reduce per-test size.
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeOnReferencedAssembly_
Diagnostic
Good use of WithNoLocation() for cross-assembly diagnostic; body is ~45 lines — extracting the multi-project scaffolding into a shared helper would improve readability.
A (90–100)new AssemblyFixtureProviderNativeAotTests.
AssemblyFixtureProvider_
WhenDynamicCodeUnsupported_
IsSkipped
Clear AAA; rich assertions: exit code, summary, and positive and negative output checks all verified.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
NoDiagnostic
Concise, focused negative test; canonical Roslyn markup assertion pattern. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeIsUsed_
Diagnostic
Clean single-scenario test with precise location-aware diagnostic assertion. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeNotUsed_
NoDiagnostic
Well-scoped negative test; verifies silence when the attribute is absent under AOT. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeUsedMultipleTimes_
DiagnosticOnEach
Verifies per-usage diagnostic with two independent markers; correctly tests the each-occurrence contract. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenRunAOTCompilationAndAttributeIsUsed_
Diagnostic
Correctly tests the RunAOTCompilation property path (distinct from PublishAot); canonical markup assertion. No issues found.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
allowed:
- defaults
- "awmgmcpg"

See Network Configuration for more information.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 44.2 AIC · ⌖ 5.65 AIC · ⊞ 8.9K · [◷]( · )

@Evangelink
Amaury Levé (Evangelink) merged commit 179aae0 into mainJul 15, 2026
60 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/aot-il2026-assembly-fixture-provider branch July 15, 2026 10:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer - #9941

Merged
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider
Jul 15, 2026
Merged

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer#9941
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Jul 14, 2026

Copy link
Copy Markdown
Member

Summary

[AssemblyFixtureProvider] cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies() + load-by-name via AssemblyLoadContext). That is fundamentally a reflection/runtime-loading mechanism and cannot be made reflection-free by the source generator. Under Native AOT it also surfaced an IL2026 — the last MSTest-owned trim/AOT warning a consumer hit when publishing a Native AOT test app with MSTestSourceGenMode=ReflectionFree and warnings-as-errors.

Rather than paper over it with a suppression, this PR makes the behavior explicit: skip the feature when dynamic code is unsupported, and surface it both at build time (analyzer) and at run time (trace warning).

Changes

1. Skip discovery when dynamic code is unsupported (TypeCache.ProviderDiscovery.cs)
Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported. Because ILC constant-folds that switch to false under AOT, the guarded reflection path is statically removed — so the IL2026 disappears with no suppression needed (same pattern already used in DataSerializationHelper).

2. Best-effort runtime warning
When discovery is skipped, emit a trace warning so consumers are not silently deprived of their fixtures. It scans the already-loaded assemblies (AppDomain.GetAssemblies, metadata-only via CustomAttributeData, with per-assembly failure isolation) — it deliberately does not walk the reference graph, so it stays AOT-safe. Consequently it can only see markers on assemblies that happen to be loaded (e.g. a self-applied marker on the test assembly); an unloaded referenced provider is not detectable at run time AOT-safely. Referenced providers are instead covered at build time by the analyzer. The warning is emitted through MTP's diagnostic logger (--diagnostic output).

3. New analyzer MSTEST0072AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzer
Warns at build time when the project opts into an AOT flavor detectable at build time — PublishAot (Native AOT) orRunAOTCompilation (Blazor WebAssembly AOT) — and [AssemblyFixtureProvider] is in play. It inspects both the compilation's own assembly attributes (reported at the attribute location) and referenced assemblies' attributes (reported as a no-location diagnostic), so the documented default usage — the attribute placed on a referenced fixture library consumed by an AOT test project — is covered. PublishAot and RunAOTCompilation are exposed to analyzers via new CompilerVisibleProperty entries in MSTest.TestAdapter.targets. Includes resources (+ regenerated xlf for all 13 locales), AnalyzerReleases.Unshipped.md entry, and unit tests (including the referenced-assembly and RunAOTCompilation scenarios).

4. Acceptance testAssemblyFixtureProviderNativeAotTests verifies that under PublishAot=true (which sets IsDynamicCodeSupported=false for a managed build) the referenced provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.

Notes

  • Analyzer coverage. MSTEST0072 detects [AssemblyFixtureProvider] whether it is declared in the compilation being built or on a referenced library, and it triggers on both build-time-detectable AOT flavors (PublishAot, RunAOTCompilation). The only case it cannot cover is a runtime that disables dynamic code without either build property being set (e.g. Mono iOS AOT), where there is no build-time signal to key off; the best-effort runtime trace warning is the fallback there, limited to already-loaded assemblies as described in change Porting latest changes. #2.
  • Supersedes the earlier suppression-based commit on this branch.

Validation

  • dotnet build of the adapter (net8.0) and MSTest.Analyzers → 0 errors (release-tracking analyzer satisfied).
  • New analyzer unit tests (7, incl. referenced-assembly and RunAOTCompilation cases) pass on net8.0.
  • Downstream: with discovery skipped under AOT, the reflection-free Native AOT publish reaches native codegen with no MSTest-owned IL20xx/IL30xx warnings.

CopilotAI review requested due to automatic review settings July 14, 2026 14:17

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Suppresses the IL2026 trim/AOT warning from assembly fixture provider discovery while extending acceptance-test coverage.

Changes:

  • Isolates and suppresses Assembly.GetReferencedAssemblies().
  • Adds the source file to trim/AOT warning assertions.
Show a summary per file
FileDescription
TypeCache.ProviderDiscovery.csAdds the scoped IL2026 suppression helper.
TrimAndAotAssertions.csGuards against future trim/AOT warnings from provider discovery.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actions

This comment has been minimized.

AssemblyFixtureProvider cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies + load-by-name), which requires capabilities not available when the runtime cannot generate dynamic code (Native AOT, Mono iOS AOT, Blazor WASM AOT). Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported so the feature is skipped there.
Because the ILC substitutes IsDynamicCodeSupported with a constant under AOT, the guarded reflection path is statically removed, so the previously-surfaced IL2026 (from Assembly.GetReferencedAssemblies) disappears without needing an inline suppression. This supersedes the earlier suppression approach.
…ative AOT
Since [AssemblyFixtureProvider] discovery is now skipped under Native AOT (it relies on walking the runtime assembly reference graph), add an analyzer that warns at build time when a project both opts into PublishAot and declares [assembly: AssemblyFixtureProvider], so the silently-ignored feature is surfaced to the user.
PublishAot is exposed to analyzers via a new CompilerVisibleProperty in MSTest.TestAdapter.targets. The diagnostic reports at each attribute application; includes resources (+ regenerated xlf), release tracking, and unit tests.
CopilotAI review requested due to automatic review settings July 14, 2026 15:37
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/aot-il2026-assembly-fixture-provider branch from 359ff8b to b54f046CompareJuly 14, 2026 15:37
@EvangelinkAmaury Levé (Evangelink) changed the title Suppress IL2026 in AssemblyFixtureProvider assembly discoverySkip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzerJul 14, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 15, 2026
…ime warning
- MSTEST0072 now also inspects referenced assemblies' attributes, so the documented default usage (attribute on a referenced fixture library) is flagged with a no-location diagnostic on the consuming Native AOT project, not just self-applied attributes.
- Add a runtime warning when discovery is skipped because dynamic code is unsupported, covering Mono iOS AOT and Blazor WebAssembly AOT which the PublishAot-keyed analyzer cannot reach. The check is metadata-only (HasAssemblyFixtureProviderMarker) so it stays AOT-safe.
- Use explicit LINQ filtering (.Where/.Any) in the analyzer loops per code-quality feedback.
- Add unit tests for the referenced-assembly scenario (PublishAot true and false).
CopilotAI review requested due to automatic review settings July 15, 2026 07:37

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 8
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs
@github-actions

This comment has been minimized.

…tance test, encoding, LINQ
- Runtime warning now scans already-loaded assemblies (AppDomain.GetAssemblies, metadata-only) instead of only the test assembly, so a referenced provider library is no longer silent on Mono iOS / Blazor WASM AOT. Stays AOT-safe (no reference-graph walk).
- Add acceptance test AssemblyFixtureProviderNativeAotTests verifying that under PublishAot=true (IsDynamicCodeSupported=false, managed) the provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.
- Restore UTF-8 BOM on all touched .cs files per .editorconfig.
- Use explicit .Where(...) in the referenced-assembly loop.
CopilotAI review requested due to automatic review settings July 15, 2026 08:00

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

- Isolate per-assembly failures in the runtime warning loop (try/catch around the metadata probe) so unresolvable custom-attribute metadata on one loaded assembly cannot abort discovery, matching the normal discovery path. Clarify in comments that the runtime probe is best-effort (already-loaded assemblies only) and that referenced-provider coverage is the analyzer's responsibility.
- Broaden MSTEST0072 to also trigger on RunAOTCompilation (Blazor WebAssembly AOT) in addition to PublishAot, giving build-time detection for another dynamic-code-disabled runtime. Added RunAOTCompilation as a CompilerVisibleProperty and a unit test.
- Replace the referenced-assembly foreach (whose loop variable was unused) with a single .Any(...) check that reports one no-location diagnostic, fixing the useless-assignment warning.
CopilotAI review requested due to automatic review settings July 15, 2026 08:35
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Resources.resx Outdated
MSTEST0072 now triggers on RunAOTCompilation (Blazor WebAssembly AOT) as well as PublishAot, so the diagnostic title/message/description no longer say only 'Native AOT'. Reword to 'ahead-of-time compilation (such as Native AOT or Blazor WebAssembly AOT)' and regenerate the XLF files for all locales.
CopilotAI review requested due to automatic review settings July 15, 2026 09:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9941

GradeTestNotes
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
AttributeOnReferencedAssembly_
NoDiagnostic
Strong negative assertion via RunAsync(); body is ~45 lines due to multi-project string literals — consider extracting shared setup into a helper to reduce per-test size.
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeOnReferencedAssembly_
Diagnostic
Good use of WithNoLocation() for cross-assembly diagnostic; body is ~45 lines — extracting the multi-project scaffolding into a shared helper would improve readability.
A (90–100)new AssemblyFixtureProviderNativeAotTests.
AssemblyFixtureProvider_
WhenDynamicCodeUnsupported_
IsSkipped
Clear AAA; rich assertions: exit code, summary, and positive and negative output checks all verified.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
NoDiagnostic
Concise, focused negative test; canonical Roslyn markup assertion pattern. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeIsUsed_
Diagnostic
Clean single-scenario test with precise location-aware diagnostic assertion. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeNotUsed_
NoDiagnostic
Well-scoped negative test; verifies silence when the attribute is absent under AOT. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeUsedMultipleTimes_
DiagnosticOnEach
Verifies per-usage diagnostic with two independent markers; correctly tests the each-occurrence contract. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenRunAOTCompilationAndAttributeIsUsed_
Diagnostic
Correctly tests the RunAOTCompilation property path (distinct from PublishAot); canonical markup assertion. No issues found.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
allowed:
- defaults
- "awmgmcpg"

See Network Configuration for more information.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 44.2 AIC · ⌖ 5.65 AIC · ⊞ 8.9K · [◷]( · )

@Evangelink
Amaury Levé (Evangelink) merged commit 179aae0 into mainJul 15, 2026
60 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/aot-il2026-assembly-fixture-provider branch July 15, 2026 10:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer - #9941

Merged
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider
Jul 15, 2026
Merged

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer#9941
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Jul 14, 2026

Copy link
Copy Markdown
Member

Summary

[AssemblyFixtureProvider] cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies() + load-by-name via AssemblyLoadContext). That is fundamentally a reflection/runtime-loading mechanism and cannot be made reflection-free by the source generator. Under Native AOT it also surfaced an IL2026 — the last MSTest-owned trim/AOT warning a consumer hit when publishing a Native AOT test app with MSTestSourceGenMode=ReflectionFree and warnings-as-errors.

Rather than paper over it with a suppression, this PR makes the behavior explicit: skip the feature when dynamic code is unsupported, and surface it both at build time (analyzer) and at run time (trace warning).

Changes

1. Skip discovery when dynamic code is unsupported (TypeCache.ProviderDiscovery.cs)
Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported. Because ILC constant-folds that switch to false under AOT, the guarded reflection path is statically removed — so the IL2026 disappears with no suppression needed (same pattern already used in DataSerializationHelper).

2. Best-effort runtime warning
When discovery is skipped, emit a trace warning so consumers are not silently deprived of their fixtures. It scans the already-loaded assemblies (AppDomain.GetAssemblies, metadata-only via CustomAttributeData, with per-assembly failure isolation) — it deliberately does not walk the reference graph, so it stays AOT-safe. Consequently it can only see markers on assemblies that happen to be loaded (e.g. a self-applied marker on the test assembly); an unloaded referenced provider is not detectable at run time AOT-safely. Referenced providers are instead covered at build time by the analyzer. The warning is emitted through MTP's diagnostic logger (--diagnostic output).

3. New analyzer MSTEST0072AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzer
Warns at build time when the project opts into an AOT flavor detectable at build time — PublishAot (Native AOT) orRunAOTCompilation (Blazor WebAssembly AOT) — and [AssemblyFixtureProvider] is in play. It inspects both the compilation's own assembly attributes (reported at the attribute location) and referenced assemblies' attributes (reported as a no-location diagnostic), so the documented default usage — the attribute placed on a referenced fixture library consumed by an AOT test project — is covered. PublishAot and RunAOTCompilation are exposed to analyzers via new CompilerVisibleProperty entries in MSTest.TestAdapter.targets. Includes resources (+ regenerated xlf for all 13 locales), AnalyzerReleases.Unshipped.md entry, and unit tests (including the referenced-assembly and RunAOTCompilation scenarios).

4. Acceptance testAssemblyFixtureProviderNativeAotTests verifies that under PublishAot=true (which sets IsDynamicCodeSupported=false for a managed build) the referenced provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.

Notes

  • Analyzer coverage. MSTEST0072 detects [AssemblyFixtureProvider] whether it is declared in the compilation being built or on a referenced library, and it triggers on both build-time-detectable AOT flavors (PublishAot, RunAOTCompilation). The only case it cannot cover is a runtime that disables dynamic code without either build property being set (e.g. Mono iOS AOT), where there is no build-time signal to key off; the best-effort runtime trace warning is the fallback there, limited to already-loaded assemblies as described in change Porting latest changes. #2.
  • Supersedes the earlier suppression-based commit on this branch.

Validation

  • dotnet build of the adapter (net8.0) and MSTest.Analyzers → 0 errors (release-tracking analyzer satisfied).
  • New analyzer unit tests (7, incl. referenced-assembly and RunAOTCompilation cases) pass on net8.0.
  • Downstream: with discovery skipped under AOT, the reflection-free Native AOT publish reaches native codegen with no MSTest-owned IL20xx/IL30xx warnings.

CopilotAI review requested due to automatic review settings July 14, 2026 14:17

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Suppresses the IL2026 trim/AOT warning from assembly fixture provider discovery while extending acceptance-test coverage.

Changes:

  • Isolates and suppresses Assembly.GetReferencedAssemblies().
  • Adds the source file to trim/AOT warning assertions.
Show a summary per file
FileDescription
TypeCache.ProviderDiscovery.csAdds the scoped IL2026 suppression helper.
TrimAndAotAssertions.csGuards against future trim/AOT warnings from provider discovery.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actions

This comment has been minimized.

AssemblyFixtureProvider cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies + load-by-name), which requires capabilities not available when the runtime cannot generate dynamic code (Native AOT, Mono iOS AOT, Blazor WASM AOT). Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported so the feature is skipped there.
Because the ILC substitutes IsDynamicCodeSupported with a constant under AOT, the guarded reflection path is statically removed, so the previously-surfaced IL2026 (from Assembly.GetReferencedAssemblies) disappears without needing an inline suppression. This supersedes the earlier suppression approach.
…ative AOT
Since [AssemblyFixtureProvider] discovery is now skipped under Native AOT (it relies on walking the runtime assembly reference graph), add an analyzer that warns at build time when a project both opts into PublishAot and declares [assembly: AssemblyFixtureProvider], so the silently-ignored feature is surfaced to the user.
PublishAot is exposed to analyzers via a new CompilerVisibleProperty in MSTest.TestAdapter.targets. The diagnostic reports at each attribute application; includes resources (+ regenerated xlf), release tracking, and unit tests.
CopilotAI review requested due to automatic review settings July 14, 2026 15:37
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/aot-il2026-assembly-fixture-provider branch from 359ff8b to b54f046CompareJuly 14, 2026 15:37
@EvangelinkAmaury Levé (Evangelink) changed the title Suppress IL2026 in AssemblyFixtureProvider assembly discoverySkip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzerJul 14, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 15, 2026
…ime warning
- MSTEST0072 now also inspects referenced assemblies' attributes, so the documented default usage (attribute on a referenced fixture library) is flagged with a no-location diagnostic on the consuming Native AOT project, not just self-applied attributes.
- Add a runtime warning when discovery is skipped because dynamic code is unsupported, covering Mono iOS AOT and Blazor WebAssembly AOT which the PublishAot-keyed analyzer cannot reach. The check is metadata-only (HasAssemblyFixtureProviderMarker) so it stays AOT-safe.
- Use explicit LINQ filtering (.Where/.Any) in the analyzer loops per code-quality feedback.
- Add unit tests for the referenced-assembly scenario (PublishAot true and false).
CopilotAI review requested due to automatic review settings July 15, 2026 07:37

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 8
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs
@github-actions

This comment has been minimized.

…tance test, encoding, LINQ
- Runtime warning now scans already-loaded assemblies (AppDomain.GetAssemblies, metadata-only) instead of only the test assembly, so a referenced provider library is no longer silent on Mono iOS / Blazor WASM AOT. Stays AOT-safe (no reference-graph walk).
- Add acceptance test AssemblyFixtureProviderNativeAotTests verifying that under PublishAot=true (IsDynamicCodeSupported=false, managed) the provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.
- Restore UTF-8 BOM on all touched .cs files per .editorconfig.
- Use explicit .Where(...) in the referenced-assembly loop.
CopilotAI review requested due to automatic review settings July 15, 2026 08:00

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

- Isolate per-assembly failures in the runtime warning loop (try/catch around the metadata probe) so unresolvable custom-attribute metadata on one loaded assembly cannot abort discovery, matching the normal discovery path. Clarify in comments that the runtime probe is best-effort (already-loaded assemblies only) and that referenced-provider coverage is the analyzer's responsibility.
- Broaden MSTEST0072 to also trigger on RunAOTCompilation (Blazor WebAssembly AOT) in addition to PublishAot, giving build-time detection for another dynamic-code-disabled runtime. Added RunAOTCompilation as a CompilerVisibleProperty and a unit test.
- Replace the referenced-assembly foreach (whose loop variable was unused) with a single .Any(...) check that reports one no-location diagnostic, fixing the useless-assignment warning.
CopilotAI review requested due to automatic review settings July 15, 2026 08:35
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Resources.resx Outdated
MSTEST0072 now triggers on RunAOTCompilation (Blazor WebAssembly AOT) as well as PublishAot, so the diagnostic title/message/description no longer say only 'Native AOT'. Reword to 'ahead-of-time compilation (such as Native AOT or Blazor WebAssembly AOT)' and regenerate the XLF files for all locales.
CopilotAI review requested due to automatic review settings July 15, 2026 09:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9941

GradeTestNotes
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
AttributeOnReferencedAssembly_
NoDiagnostic
Strong negative assertion via RunAsync(); body is ~45 lines due to multi-project string literals — consider extracting shared setup into a helper to reduce per-test size.
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeOnReferencedAssembly_
Diagnostic
Good use of WithNoLocation() for cross-assembly diagnostic; body is ~45 lines — extracting the multi-project scaffolding into a shared helper would improve readability.
A (90–100)new AssemblyFixtureProviderNativeAotTests.
AssemblyFixtureProvider_
WhenDynamicCodeUnsupported_
IsSkipped
Clear AAA; rich assertions: exit code, summary, and positive and negative output checks all verified.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
NoDiagnostic
Concise, focused negative test; canonical Roslyn markup assertion pattern. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeIsUsed_
Diagnostic
Clean single-scenario test with precise location-aware diagnostic assertion. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeNotUsed_
NoDiagnostic
Well-scoped negative test; verifies silence when the attribute is absent under AOT. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeUsedMultipleTimes_
DiagnosticOnEach
Verifies per-usage diagnostic with two independent markers; correctly tests the each-occurrence contract. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenRunAOTCompilationAndAttributeIsUsed_
Diagnostic
Correctly tests the RunAOTCompilation property path (distinct from PublishAot); canonical markup assertion. No issues found.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
allowed:
- defaults
- "awmgmcpg"

See Network Configuration for more information.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 44.2 AIC · ⌖ 5.65 AIC · ⊞ 8.9K · [◷]( · )

@Evangelink
Amaury Levé (Evangelink) merged commit 179aae0 into mainJul 15, 2026
60 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/aot-il2026-assembly-fixture-provider branch July 15, 2026 10:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer - #9941

Merged
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider
Jul 15, 2026
Merged

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer#9941
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Jul 14, 2026

Copy link
Copy Markdown
Member

Summary

[AssemblyFixtureProvider] cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies() + load-by-name via AssemblyLoadContext). That is fundamentally a reflection/runtime-loading mechanism and cannot be made reflection-free by the source generator. Under Native AOT it also surfaced an IL2026 — the last MSTest-owned trim/AOT warning a consumer hit when publishing a Native AOT test app with MSTestSourceGenMode=ReflectionFree and warnings-as-errors.

Rather than paper over it with a suppression, this PR makes the behavior explicit: skip the feature when dynamic code is unsupported, and surface it both at build time (analyzer) and at run time (trace warning).

Changes

1. Skip discovery when dynamic code is unsupported (TypeCache.ProviderDiscovery.cs)
Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported. Because ILC constant-folds that switch to false under AOT, the guarded reflection path is statically removed — so the IL2026 disappears with no suppression needed (same pattern already used in DataSerializationHelper).

2. Best-effort runtime warning
When discovery is skipped, emit a trace warning so consumers are not silently deprived of their fixtures. It scans the already-loaded assemblies (AppDomain.GetAssemblies, metadata-only via CustomAttributeData, with per-assembly failure isolation) — it deliberately does not walk the reference graph, so it stays AOT-safe. Consequently it can only see markers on assemblies that happen to be loaded (e.g. a self-applied marker on the test assembly); an unloaded referenced provider is not detectable at run time AOT-safely. Referenced providers are instead covered at build time by the analyzer. The warning is emitted through MTP's diagnostic logger (--diagnostic output).

3. New analyzer MSTEST0072AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzer
Warns at build time when the project opts into an AOT flavor detectable at build time — PublishAot (Native AOT) orRunAOTCompilation (Blazor WebAssembly AOT) — and [AssemblyFixtureProvider] is in play. It inspects both the compilation's own assembly attributes (reported at the attribute location) and referenced assemblies' attributes (reported as a no-location diagnostic), so the documented default usage — the attribute placed on a referenced fixture library consumed by an AOT test project — is covered. PublishAot and RunAOTCompilation are exposed to analyzers via new CompilerVisibleProperty entries in MSTest.TestAdapter.targets. Includes resources (+ regenerated xlf for all 13 locales), AnalyzerReleases.Unshipped.md entry, and unit tests (including the referenced-assembly and RunAOTCompilation scenarios).

4. Acceptance testAssemblyFixtureProviderNativeAotTests verifies that under PublishAot=true (which sets IsDynamicCodeSupported=false for a managed build) the referenced provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.

Notes

  • Analyzer coverage. MSTEST0072 detects [AssemblyFixtureProvider] whether it is declared in the compilation being built or on a referenced library, and it triggers on both build-time-detectable AOT flavors (PublishAot, RunAOTCompilation). The only case it cannot cover is a runtime that disables dynamic code without either build property being set (e.g. Mono iOS AOT), where there is no build-time signal to key off; the best-effort runtime trace warning is the fallback there, limited to already-loaded assemblies as described in change Porting latest changes. #2.
  • Supersedes the earlier suppression-based commit on this branch.

Validation

  • dotnet build of the adapter (net8.0) and MSTest.Analyzers → 0 errors (release-tracking analyzer satisfied).
  • New analyzer unit tests (7, incl. referenced-assembly and RunAOTCompilation cases) pass on net8.0.
  • Downstream: with discovery skipped under AOT, the reflection-free Native AOT publish reaches native codegen with no MSTest-owned IL20xx/IL30xx warnings.

CopilotAI review requested due to automatic review settings July 14, 2026 14:17

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Suppresses the IL2026 trim/AOT warning from assembly fixture provider discovery while extending acceptance-test coverage.

Changes:

  • Isolates and suppresses Assembly.GetReferencedAssemblies().
  • Adds the source file to trim/AOT warning assertions.
Show a summary per file
FileDescription
TypeCache.ProviderDiscovery.csAdds the scoped IL2026 suppression helper.
TrimAndAotAssertions.csGuards against future trim/AOT warnings from provider discovery.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actions

This comment has been minimized.

AssemblyFixtureProvider cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies + load-by-name), which requires capabilities not available when the runtime cannot generate dynamic code (Native AOT, Mono iOS AOT, Blazor WASM AOT). Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported so the feature is skipped there.
Because the ILC substitutes IsDynamicCodeSupported with a constant under AOT, the guarded reflection path is statically removed, so the previously-surfaced IL2026 (from Assembly.GetReferencedAssemblies) disappears without needing an inline suppression. This supersedes the earlier suppression approach.
…ative AOT
Since [AssemblyFixtureProvider] discovery is now skipped under Native AOT (it relies on walking the runtime assembly reference graph), add an analyzer that warns at build time when a project both opts into PublishAot and declares [assembly: AssemblyFixtureProvider], so the silently-ignored feature is surfaced to the user.
PublishAot is exposed to analyzers via a new CompilerVisibleProperty in MSTest.TestAdapter.targets. The diagnostic reports at each attribute application; includes resources (+ regenerated xlf), release tracking, and unit tests.
CopilotAI review requested due to automatic review settings July 14, 2026 15:37
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/aot-il2026-assembly-fixture-provider branch from 359ff8b to b54f046CompareJuly 14, 2026 15:37
@EvangelinkAmaury Levé (Evangelink) changed the title Suppress IL2026 in AssemblyFixtureProvider assembly discoverySkip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzerJul 14, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 15, 2026
…ime warning
- MSTEST0072 now also inspects referenced assemblies' attributes, so the documented default usage (attribute on a referenced fixture library) is flagged with a no-location diagnostic on the consuming Native AOT project, not just self-applied attributes.
- Add a runtime warning when discovery is skipped because dynamic code is unsupported, covering Mono iOS AOT and Blazor WebAssembly AOT which the PublishAot-keyed analyzer cannot reach. The check is metadata-only (HasAssemblyFixtureProviderMarker) so it stays AOT-safe.
- Use explicit LINQ filtering (.Where/.Any) in the analyzer loops per code-quality feedback.
- Add unit tests for the referenced-assembly scenario (PublishAot true and false).
CopilotAI review requested due to automatic review settings July 15, 2026 07:37

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 8
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs
@github-actions

This comment has been minimized.

…tance test, encoding, LINQ
- Runtime warning now scans already-loaded assemblies (AppDomain.GetAssemblies, metadata-only) instead of only the test assembly, so a referenced provider library is no longer silent on Mono iOS / Blazor WASM AOT. Stays AOT-safe (no reference-graph walk).
- Add acceptance test AssemblyFixtureProviderNativeAotTests verifying that under PublishAot=true (IsDynamicCodeSupported=false, managed) the provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.
- Restore UTF-8 BOM on all touched .cs files per .editorconfig.
- Use explicit .Where(...) in the referenced-assembly loop.
CopilotAI review requested due to automatic review settings July 15, 2026 08:00

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

- Isolate per-assembly failures in the runtime warning loop (try/catch around the metadata probe) so unresolvable custom-attribute metadata on one loaded assembly cannot abort discovery, matching the normal discovery path. Clarify in comments that the runtime probe is best-effort (already-loaded assemblies only) and that referenced-provider coverage is the analyzer's responsibility.
- Broaden MSTEST0072 to also trigger on RunAOTCompilation (Blazor WebAssembly AOT) in addition to PublishAot, giving build-time detection for another dynamic-code-disabled runtime. Added RunAOTCompilation as a CompilerVisibleProperty and a unit test.
- Replace the referenced-assembly foreach (whose loop variable was unused) with a single .Any(...) check that reports one no-location diagnostic, fixing the useless-assignment warning.
CopilotAI review requested due to automatic review settings July 15, 2026 08:35
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Resources.resx Outdated
MSTEST0072 now triggers on RunAOTCompilation (Blazor WebAssembly AOT) as well as PublishAot, so the diagnostic title/message/description no longer say only 'Native AOT'. Reword to 'ahead-of-time compilation (such as Native AOT or Blazor WebAssembly AOT)' and regenerate the XLF files for all locales.
CopilotAI review requested due to automatic review settings July 15, 2026 09:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9941

GradeTestNotes
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
AttributeOnReferencedAssembly_
NoDiagnostic
Strong negative assertion via RunAsync(); body is ~45 lines due to multi-project string literals — consider extracting shared setup into a helper to reduce per-test size.
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeOnReferencedAssembly_
Diagnostic
Good use of WithNoLocation() for cross-assembly diagnostic; body is ~45 lines — extracting the multi-project scaffolding into a shared helper would improve readability.
A (90–100)new AssemblyFixtureProviderNativeAotTests.
AssemblyFixtureProvider_
WhenDynamicCodeUnsupported_
IsSkipped
Clear AAA; rich assertions: exit code, summary, and positive and negative output checks all verified.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
NoDiagnostic
Concise, focused negative test; canonical Roslyn markup assertion pattern. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeIsUsed_
Diagnostic
Clean single-scenario test with precise location-aware diagnostic assertion. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeNotUsed_
NoDiagnostic
Well-scoped negative test; verifies silence when the attribute is absent under AOT. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeUsedMultipleTimes_
DiagnosticOnEach
Verifies per-usage diagnostic with two independent markers; correctly tests the each-occurrence contract. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenRunAOTCompilationAndAttributeIsUsed_
Diagnostic
Correctly tests the RunAOTCompilation property path (distinct from PublishAot); canonical markup assertion. No issues found.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
allowed:
- defaults
- "awmgmcpg"

See Network Configuration for more information.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 44.2 AIC · ⌖ 5.65 AIC · ⊞ 8.9K · [◷]( · )

@Evangelink
Amaury Levé (Evangelink) merged commit 179aae0 into mainJul 15, 2026
60 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/aot-il2026-assembly-fixture-provider branch July 15, 2026 10:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer - #9941

Merged
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider
Jul 15, 2026
Merged

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer#9941
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Jul 14, 2026

Copy link
Copy Markdown
Member

Summary

[AssemblyFixtureProvider] cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies() + load-by-name via AssemblyLoadContext). That is fundamentally a reflection/runtime-loading mechanism and cannot be made reflection-free by the source generator. Under Native AOT it also surfaced an IL2026 — the last MSTest-owned trim/AOT warning a consumer hit when publishing a Native AOT test app with MSTestSourceGenMode=ReflectionFree and warnings-as-errors.

Rather than paper over it with a suppression, this PR makes the behavior explicit: skip the feature when dynamic code is unsupported, and surface it both at build time (analyzer) and at run time (trace warning).

Changes

1. Skip discovery when dynamic code is unsupported (TypeCache.ProviderDiscovery.cs)
Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported. Because ILC constant-folds that switch to false under AOT, the guarded reflection path is statically removed — so the IL2026 disappears with no suppression needed (same pattern already used in DataSerializationHelper).

2. Best-effort runtime warning
When discovery is skipped, emit a trace warning so consumers are not silently deprived of their fixtures. It scans the already-loaded assemblies (AppDomain.GetAssemblies, metadata-only via CustomAttributeData, with per-assembly failure isolation) — it deliberately does not walk the reference graph, so it stays AOT-safe. Consequently it can only see markers on assemblies that happen to be loaded (e.g. a self-applied marker on the test assembly); an unloaded referenced provider is not detectable at run time AOT-safely. Referenced providers are instead covered at build time by the analyzer. The warning is emitted through MTP's diagnostic logger (--diagnostic output).

3. New analyzer MSTEST0072AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzer
Warns at build time when the project opts into an AOT flavor detectable at build time — PublishAot (Native AOT) orRunAOTCompilation (Blazor WebAssembly AOT) — and [AssemblyFixtureProvider] is in play. It inspects both the compilation's own assembly attributes (reported at the attribute location) and referenced assemblies' attributes (reported as a no-location diagnostic), so the documented default usage — the attribute placed on a referenced fixture library consumed by an AOT test project — is covered. PublishAot and RunAOTCompilation are exposed to analyzers via new CompilerVisibleProperty entries in MSTest.TestAdapter.targets. Includes resources (+ regenerated xlf for all 13 locales), AnalyzerReleases.Unshipped.md entry, and unit tests (including the referenced-assembly and RunAOTCompilation scenarios).

4. Acceptance testAssemblyFixtureProviderNativeAotTests verifies that under PublishAot=true (which sets IsDynamicCodeSupported=false for a managed build) the referenced provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.

Notes

  • Analyzer coverage. MSTEST0072 detects [AssemblyFixtureProvider] whether it is declared in the compilation being built or on a referenced library, and it triggers on both build-time-detectable AOT flavors (PublishAot, RunAOTCompilation). The only case it cannot cover is a runtime that disables dynamic code without either build property being set (e.g. Mono iOS AOT), where there is no build-time signal to key off; the best-effort runtime trace warning is the fallback there, limited to already-loaded assemblies as described in change Porting latest changes. #2.
  • Supersedes the earlier suppression-based commit on this branch.

Validation

  • dotnet build of the adapter (net8.0) and MSTest.Analyzers → 0 errors (release-tracking analyzer satisfied).
  • New analyzer unit tests (7, incl. referenced-assembly and RunAOTCompilation cases) pass on net8.0.
  • Downstream: with discovery skipped under AOT, the reflection-free Native AOT publish reaches native codegen with no MSTest-owned IL20xx/IL30xx warnings.

CopilotAI review requested due to automatic review settings July 14, 2026 14:17

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Suppresses the IL2026 trim/AOT warning from assembly fixture provider discovery while extending acceptance-test coverage.

Changes:

  • Isolates and suppresses Assembly.GetReferencedAssemblies().
  • Adds the source file to trim/AOT warning assertions.
Show a summary per file
FileDescription
TypeCache.ProviderDiscovery.csAdds the scoped IL2026 suppression helper.
TrimAndAotAssertions.csGuards against future trim/AOT warnings from provider discovery.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actions

This comment has been minimized.

AssemblyFixtureProvider cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies + load-by-name), which requires capabilities not available when the runtime cannot generate dynamic code (Native AOT, Mono iOS AOT, Blazor WASM AOT). Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported so the feature is skipped there.
Because the ILC substitutes IsDynamicCodeSupported with a constant under AOT, the guarded reflection path is statically removed, so the previously-surfaced IL2026 (from Assembly.GetReferencedAssemblies) disappears without needing an inline suppression. This supersedes the earlier suppression approach.
…ative AOT
Since [AssemblyFixtureProvider] discovery is now skipped under Native AOT (it relies on walking the runtime assembly reference graph), add an analyzer that warns at build time when a project both opts into PublishAot and declares [assembly: AssemblyFixtureProvider], so the silently-ignored feature is surfaced to the user.
PublishAot is exposed to analyzers via a new CompilerVisibleProperty in MSTest.TestAdapter.targets. The diagnostic reports at each attribute application; includes resources (+ regenerated xlf), release tracking, and unit tests.
CopilotAI review requested due to automatic review settings July 14, 2026 15:37
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/aot-il2026-assembly-fixture-provider branch from 359ff8b to b54f046CompareJuly 14, 2026 15:37
@EvangelinkAmaury Levé (Evangelink) changed the title Suppress IL2026 in AssemblyFixtureProvider assembly discoverySkip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzerJul 14, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 15, 2026
…ime warning
- MSTEST0072 now also inspects referenced assemblies' attributes, so the documented default usage (attribute on a referenced fixture library) is flagged with a no-location diagnostic on the consuming Native AOT project, not just self-applied attributes.
- Add a runtime warning when discovery is skipped because dynamic code is unsupported, covering Mono iOS AOT and Blazor WebAssembly AOT which the PublishAot-keyed analyzer cannot reach. The check is metadata-only (HasAssemblyFixtureProviderMarker) so it stays AOT-safe.
- Use explicit LINQ filtering (.Where/.Any) in the analyzer loops per code-quality feedback.
- Add unit tests for the referenced-assembly scenario (PublishAot true and false).
CopilotAI review requested due to automatic review settings July 15, 2026 07:37

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 8
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs
@github-actions

This comment has been minimized.

…tance test, encoding, LINQ
- Runtime warning now scans already-loaded assemblies (AppDomain.GetAssemblies, metadata-only) instead of only the test assembly, so a referenced provider library is no longer silent on Mono iOS / Blazor WASM AOT. Stays AOT-safe (no reference-graph walk).
- Add acceptance test AssemblyFixtureProviderNativeAotTests verifying that under PublishAot=true (IsDynamicCodeSupported=false, managed) the provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.
- Restore UTF-8 BOM on all touched .cs files per .editorconfig.
- Use explicit .Where(...) in the referenced-assembly loop.
CopilotAI review requested due to automatic review settings July 15, 2026 08:00

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

- Isolate per-assembly failures in the runtime warning loop (try/catch around the metadata probe) so unresolvable custom-attribute metadata on one loaded assembly cannot abort discovery, matching the normal discovery path. Clarify in comments that the runtime probe is best-effort (already-loaded assemblies only) and that referenced-provider coverage is the analyzer's responsibility.
- Broaden MSTEST0072 to also trigger on RunAOTCompilation (Blazor WebAssembly AOT) in addition to PublishAot, giving build-time detection for another dynamic-code-disabled runtime. Added RunAOTCompilation as a CompilerVisibleProperty and a unit test.
- Replace the referenced-assembly foreach (whose loop variable was unused) with a single .Any(...) check that reports one no-location diagnostic, fixing the useless-assignment warning.
CopilotAI review requested due to automatic review settings July 15, 2026 08:35
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Resources.resx Outdated
MSTEST0072 now triggers on RunAOTCompilation (Blazor WebAssembly AOT) as well as PublishAot, so the diagnostic title/message/description no longer say only 'Native AOT'. Reword to 'ahead-of-time compilation (such as Native AOT or Blazor WebAssembly AOT)' and regenerate the XLF files for all locales.
CopilotAI review requested due to automatic review settings July 15, 2026 09:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9941

GradeTestNotes
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
AttributeOnReferencedAssembly_
NoDiagnostic
Strong negative assertion via RunAsync(); body is ~45 lines due to multi-project string literals — consider extracting shared setup into a helper to reduce per-test size.
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeOnReferencedAssembly_
Diagnostic
Good use of WithNoLocation() for cross-assembly diagnostic; body is ~45 lines — extracting the multi-project scaffolding into a shared helper would improve readability.
A (90–100)new AssemblyFixtureProviderNativeAotTests.
AssemblyFixtureProvider_
WhenDynamicCodeUnsupported_
IsSkipped
Clear AAA; rich assertions: exit code, summary, and positive and negative output checks all verified.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
NoDiagnostic
Concise, focused negative test; canonical Roslyn markup assertion pattern. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeIsUsed_
Diagnostic
Clean single-scenario test with precise location-aware diagnostic assertion. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeNotUsed_
NoDiagnostic
Well-scoped negative test; verifies silence when the attribute is absent under AOT. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeUsedMultipleTimes_
DiagnosticOnEach
Verifies per-usage diagnostic with two independent markers; correctly tests the each-occurrence contract. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenRunAOTCompilationAndAttributeIsUsed_
Diagnostic
Correctly tests the RunAOTCompilation property path (distinct from PublishAot); canonical markup assertion. No issues found.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
allowed:
- defaults
- "awmgmcpg"

See Network Configuration for more information.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 44.2 AIC · ⌖ 5.65 AIC · ⊞ 8.9K · [◷]( · )

@Evangelink
Amaury Levé (Evangelink) merged commit 179aae0 into mainJul 15, 2026
60 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/aot-il2026-assembly-fixture-provider branch July 15, 2026 10:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer - #9941

Merged
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider
Jul 15, 2026
Merged

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer#9941
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Jul 14, 2026

Copy link
Copy Markdown
Member

Summary

[AssemblyFixtureProvider] cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies() + load-by-name via AssemblyLoadContext). That is fundamentally a reflection/runtime-loading mechanism and cannot be made reflection-free by the source generator. Under Native AOT it also surfaced an IL2026 — the last MSTest-owned trim/AOT warning a consumer hit when publishing a Native AOT test app with MSTestSourceGenMode=ReflectionFree and warnings-as-errors.

Rather than paper over it with a suppression, this PR makes the behavior explicit: skip the feature when dynamic code is unsupported, and surface it both at build time (analyzer) and at run time (trace warning).

Changes

1. Skip discovery when dynamic code is unsupported (TypeCache.ProviderDiscovery.cs)
Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported. Because ILC constant-folds that switch to false under AOT, the guarded reflection path is statically removed — so the IL2026 disappears with no suppression needed (same pattern already used in DataSerializationHelper).

2. Best-effort runtime warning
When discovery is skipped, emit a trace warning so consumers are not silently deprived of their fixtures. It scans the already-loaded assemblies (AppDomain.GetAssemblies, metadata-only via CustomAttributeData, with per-assembly failure isolation) — it deliberately does not walk the reference graph, so it stays AOT-safe. Consequently it can only see markers on assemblies that happen to be loaded (e.g. a self-applied marker on the test assembly); an unloaded referenced provider is not detectable at run time AOT-safely. Referenced providers are instead covered at build time by the analyzer. The warning is emitted through MTP's diagnostic logger (--diagnostic output).

3. New analyzer MSTEST0072AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzer
Warns at build time when the project opts into an AOT flavor detectable at build time — PublishAot (Native AOT) orRunAOTCompilation (Blazor WebAssembly AOT) — and [AssemblyFixtureProvider] is in play. It inspects both the compilation's own assembly attributes (reported at the attribute location) and referenced assemblies' attributes (reported as a no-location diagnostic), so the documented default usage — the attribute placed on a referenced fixture library consumed by an AOT test project — is covered. PublishAot and RunAOTCompilation are exposed to analyzers via new CompilerVisibleProperty entries in MSTest.TestAdapter.targets. Includes resources (+ regenerated xlf for all 13 locales), AnalyzerReleases.Unshipped.md entry, and unit tests (including the referenced-assembly and RunAOTCompilation scenarios).

4. Acceptance testAssemblyFixtureProviderNativeAotTests verifies that under PublishAot=true (which sets IsDynamicCodeSupported=false for a managed build) the referenced provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.

Notes

  • Analyzer coverage. MSTEST0072 detects [AssemblyFixtureProvider] whether it is declared in the compilation being built or on a referenced library, and it triggers on both build-time-detectable AOT flavors (PublishAot, RunAOTCompilation). The only case it cannot cover is a runtime that disables dynamic code without either build property being set (e.g. Mono iOS AOT), where there is no build-time signal to key off; the best-effort runtime trace warning is the fallback there, limited to already-loaded assemblies as described in change Porting latest changes. #2.
  • Supersedes the earlier suppression-based commit on this branch.

Validation

  • dotnet build of the adapter (net8.0) and MSTest.Analyzers → 0 errors (release-tracking analyzer satisfied).
  • New analyzer unit tests (7, incl. referenced-assembly and RunAOTCompilation cases) pass on net8.0.
  • Downstream: with discovery skipped under AOT, the reflection-free Native AOT publish reaches native codegen with no MSTest-owned IL20xx/IL30xx warnings.

CopilotAI review requested due to automatic review settings July 14, 2026 14:17

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Suppresses the IL2026 trim/AOT warning from assembly fixture provider discovery while extending acceptance-test coverage.

Changes:

  • Isolates and suppresses Assembly.GetReferencedAssemblies().
  • Adds the source file to trim/AOT warning assertions.
Show a summary per file
FileDescription
TypeCache.ProviderDiscovery.csAdds the scoped IL2026 suppression helper.
TrimAndAotAssertions.csGuards against future trim/AOT warnings from provider discovery.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actions

This comment has been minimized.

AssemblyFixtureProvider cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies + load-by-name), which requires capabilities not available when the runtime cannot generate dynamic code (Native AOT, Mono iOS AOT, Blazor WASM AOT). Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported so the feature is skipped there.
Because the ILC substitutes IsDynamicCodeSupported with a constant under AOT, the guarded reflection path is statically removed, so the previously-surfaced IL2026 (from Assembly.GetReferencedAssemblies) disappears without needing an inline suppression. This supersedes the earlier suppression approach.
…ative AOT
Since [AssemblyFixtureProvider] discovery is now skipped under Native AOT (it relies on walking the runtime assembly reference graph), add an analyzer that warns at build time when a project both opts into PublishAot and declares [assembly: AssemblyFixtureProvider], so the silently-ignored feature is surfaced to the user.
PublishAot is exposed to analyzers via a new CompilerVisibleProperty in MSTest.TestAdapter.targets. The diagnostic reports at each attribute application; includes resources (+ regenerated xlf), release tracking, and unit tests.
CopilotAI review requested due to automatic review settings July 14, 2026 15:37
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/aot-il2026-assembly-fixture-provider branch from 359ff8b to b54f046CompareJuly 14, 2026 15:37
@EvangelinkAmaury Levé (Evangelink) changed the title Suppress IL2026 in AssemblyFixtureProvider assembly discoverySkip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzerJul 14, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 15, 2026
…ime warning
- MSTEST0072 now also inspects referenced assemblies' attributes, so the documented default usage (attribute on a referenced fixture library) is flagged with a no-location diagnostic on the consuming Native AOT project, not just self-applied attributes.
- Add a runtime warning when discovery is skipped because dynamic code is unsupported, covering Mono iOS AOT and Blazor WebAssembly AOT which the PublishAot-keyed analyzer cannot reach. The check is metadata-only (HasAssemblyFixtureProviderMarker) so it stays AOT-safe.
- Use explicit LINQ filtering (.Where/.Any) in the analyzer loops per code-quality feedback.
- Add unit tests for the referenced-assembly scenario (PublishAot true and false).
CopilotAI review requested due to automatic review settings July 15, 2026 07:37

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 8
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs
@github-actions

This comment has been minimized.

…tance test, encoding, LINQ
- Runtime warning now scans already-loaded assemblies (AppDomain.GetAssemblies, metadata-only) instead of only the test assembly, so a referenced provider library is no longer silent on Mono iOS / Blazor WASM AOT. Stays AOT-safe (no reference-graph walk).
- Add acceptance test AssemblyFixtureProviderNativeAotTests verifying that under PublishAot=true (IsDynamicCodeSupported=false, managed) the provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.
- Restore UTF-8 BOM on all touched .cs files per .editorconfig.
- Use explicit .Where(...) in the referenced-assembly loop.
CopilotAI review requested due to automatic review settings July 15, 2026 08:00

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

- Isolate per-assembly failures in the runtime warning loop (try/catch around the metadata probe) so unresolvable custom-attribute metadata on one loaded assembly cannot abort discovery, matching the normal discovery path. Clarify in comments that the runtime probe is best-effort (already-loaded assemblies only) and that referenced-provider coverage is the analyzer's responsibility.
- Broaden MSTEST0072 to also trigger on RunAOTCompilation (Blazor WebAssembly AOT) in addition to PublishAot, giving build-time detection for another dynamic-code-disabled runtime. Added RunAOTCompilation as a CompilerVisibleProperty and a unit test.
- Replace the referenced-assembly foreach (whose loop variable was unused) with a single .Any(...) check that reports one no-location diagnostic, fixing the useless-assignment warning.
CopilotAI review requested due to automatic review settings July 15, 2026 08:35
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Resources.resx Outdated
MSTEST0072 now triggers on RunAOTCompilation (Blazor WebAssembly AOT) as well as PublishAot, so the diagnostic title/message/description no longer say only 'Native AOT'. Reword to 'ahead-of-time compilation (such as Native AOT or Blazor WebAssembly AOT)' and regenerate the XLF files for all locales.
CopilotAI review requested due to automatic review settings July 15, 2026 09:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9941

GradeTestNotes
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
AttributeOnReferencedAssembly_
NoDiagnostic
Strong negative assertion via RunAsync(); body is ~45 lines due to multi-project string literals — consider extracting shared setup into a helper to reduce per-test size.
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeOnReferencedAssembly_
Diagnostic
Good use of WithNoLocation() for cross-assembly diagnostic; body is ~45 lines — extracting the multi-project scaffolding into a shared helper would improve readability.
A (90–100)new AssemblyFixtureProviderNativeAotTests.
AssemblyFixtureProvider_
WhenDynamicCodeUnsupported_
IsSkipped
Clear AAA; rich assertions: exit code, summary, and positive and negative output checks all verified.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
NoDiagnostic
Concise, focused negative test; canonical Roslyn markup assertion pattern. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeIsUsed_
Diagnostic
Clean single-scenario test with precise location-aware diagnostic assertion. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeNotUsed_
NoDiagnostic
Well-scoped negative test; verifies silence when the attribute is absent under AOT. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeUsedMultipleTimes_
DiagnosticOnEach
Verifies per-usage diagnostic with two independent markers; correctly tests the each-occurrence contract. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenRunAOTCompilationAndAttributeIsUsed_
Diagnostic
Correctly tests the RunAOTCompilation property path (distinct from PublishAot); canonical markup assertion. No issues found.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
allowed:
- defaults
- "awmgmcpg"

See Network Configuration for more information.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 44.2 AIC · ⌖ 5.65 AIC · ⊞ 8.9K · [◷]( · )

@Evangelink
Amaury Levé (Evangelink) merged commit 179aae0 into mainJul 15, 2026
60 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/aot-il2026-assembly-fixture-provider branch July 15, 2026 10:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer - #9941

Merged
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider
Jul 15, 2026
Merged

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer#9941
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Jul 14, 2026

Copy link
Copy Markdown
Member

Summary

[AssemblyFixtureProvider] cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies() + load-by-name via AssemblyLoadContext). That is fundamentally a reflection/runtime-loading mechanism and cannot be made reflection-free by the source generator. Under Native AOT it also surfaced an IL2026 — the last MSTest-owned trim/AOT warning a consumer hit when publishing a Native AOT test app with MSTestSourceGenMode=ReflectionFree and warnings-as-errors.

Rather than paper over it with a suppression, this PR makes the behavior explicit: skip the feature when dynamic code is unsupported, and surface it both at build time (analyzer) and at run time (trace warning).

Changes

1. Skip discovery when dynamic code is unsupported (TypeCache.ProviderDiscovery.cs)
Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported. Because ILC constant-folds that switch to false under AOT, the guarded reflection path is statically removed — so the IL2026 disappears with no suppression needed (same pattern already used in DataSerializationHelper).

2. Best-effort runtime warning
When discovery is skipped, emit a trace warning so consumers are not silently deprived of their fixtures. It scans the already-loaded assemblies (AppDomain.GetAssemblies, metadata-only via CustomAttributeData, with per-assembly failure isolation) — it deliberately does not walk the reference graph, so it stays AOT-safe. Consequently it can only see markers on assemblies that happen to be loaded (e.g. a self-applied marker on the test assembly); an unloaded referenced provider is not detectable at run time AOT-safely. Referenced providers are instead covered at build time by the analyzer. The warning is emitted through MTP's diagnostic logger (--diagnostic output).

3. New analyzer MSTEST0072AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzer
Warns at build time when the project opts into an AOT flavor detectable at build time — PublishAot (Native AOT) orRunAOTCompilation (Blazor WebAssembly AOT) — and [AssemblyFixtureProvider] is in play. It inspects both the compilation's own assembly attributes (reported at the attribute location) and referenced assemblies' attributes (reported as a no-location diagnostic), so the documented default usage — the attribute placed on a referenced fixture library consumed by an AOT test project — is covered. PublishAot and RunAOTCompilation are exposed to analyzers via new CompilerVisibleProperty entries in MSTest.TestAdapter.targets. Includes resources (+ regenerated xlf for all 13 locales), AnalyzerReleases.Unshipped.md entry, and unit tests (including the referenced-assembly and RunAOTCompilation scenarios).

4. Acceptance testAssemblyFixtureProviderNativeAotTests verifies that under PublishAot=true (which sets IsDynamicCodeSupported=false for a managed build) the referenced provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.

Notes

  • Analyzer coverage. MSTEST0072 detects [AssemblyFixtureProvider] whether it is declared in the compilation being built or on a referenced library, and it triggers on both build-time-detectable AOT flavors (PublishAot, RunAOTCompilation). The only case it cannot cover is a runtime that disables dynamic code without either build property being set (e.g. Mono iOS AOT), where there is no build-time signal to key off; the best-effort runtime trace warning is the fallback there, limited to already-loaded assemblies as described in change Porting latest changes. #2.
  • Supersedes the earlier suppression-based commit on this branch.

Validation

  • dotnet build of the adapter (net8.0) and MSTest.Analyzers → 0 errors (release-tracking analyzer satisfied).
  • New analyzer unit tests (7, incl. referenced-assembly and RunAOTCompilation cases) pass on net8.0.
  • Downstream: with discovery skipped under AOT, the reflection-free Native AOT publish reaches native codegen with no MSTest-owned IL20xx/IL30xx warnings.

CopilotAI review requested due to automatic review settings July 14, 2026 14:17

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Suppresses the IL2026 trim/AOT warning from assembly fixture provider discovery while extending acceptance-test coverage.

Changes:

  • Isolates and suppresses Assembly.GetReferencedAssemblies().
  • Adds the source file to trim/AOT warning assertions.
Show a summary per file
FileDescription
TypeCache.ProviderDiscovery.csAdds the scoped IL2026 suppression helper.
TrimAndAotAssertions.csGuards against future trim/AOT warnings from provider discovery.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actions

This comment has been minimized.

AssemblyFixtureProvider cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies + load-by-name), which requires capabilities not available when the runtime cannot generate dynamic code (Native AOT, Mono iOS AOT, Blazor WASM AOT). Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported so the feature is skipped there.
Because the ILC substitutes IsDynamicCodeSupported with a constant under AOT, the guarded reflection path is statically removed, so the previously-surfaced IL2026 (from Assembly.GetReferencedAssemblies) disappears without needing an inline suppression. This supersedes the earlier suppression approach.
…ative AOT
Since [AssemblyFixtureProvider] discovery is now skipped under Native AOT (it relies on walking the runtime assembly reference graph), add an analyzer that warns at build time when a project both opts into PublishAot and declares [assembly: AssemblyFixtureProvider], so the silently-ignored feature is surfaced to the user.
PublishAot is exposed to analyzers via a new CompilerVisibleProperty in MSTest.TestAdapter.targets. The diagnostic reports at each attribute application; includes resources (+ regenerated xlf), release tracking, and unit tests.
CopilotAI review requested due to automatic review settings July 14, 2026 15:37
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/aot-il2026-assembly-fixture-provider branch from 359ff8b to b54f046CompareJuly 14, 2026 15:37
@EvangelinkAmaury Levé (Evangelink) changed the title Suppress IL2026 in AssemblyFixtureProvider assembly discoverySkip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzerJul 14, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 15, 2026
…ime warning
- MSTEST0072 now also inspects referenced assemblies' attributes, so the documented default usage (attribute on a referenced fixture library) is flagged with a no-location diagnostic on the consuming Native AOT project, not just self-applied attributes.
- Add a runtime warning when discovery is skipped because dynamic code is unsupported, covering Mono iOS AOT and Blazor WebAssembly AOT which the PublishAot-keyed analyzer cannot reach. The check is metadata-only (HasAssemblyFixtureProviderMarker) so it stays AOT-safe.
- Use explicit LINQ filtering (.Where/.Any) in the analyzer loops per code-quality feedback.
- Add unit tests for the referenced-assembly scenario (PublishAot true and false).
CopilotAI review requested due to automatic review settings July 15, 2026 07:37

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 8
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs
@github-actions

This comment has been minimized.

…tance test, encoding, LINQ
- Runtime warning now scans already-loaded assemblies (AppDomain.GetAssemblies, metadata-only) instead of only the test assembly, so a referenced provider library is no longer silent on Mono iOS / Blazor WASM AOT. Stays AOT-safe (no reference-graph walk).
- Add acceptance test AssemblyFixtureProviderNativeAotTests verifying that under PublishAot=true (IsDynamicCodeSupported=false, managed) the provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.
- Restore UTF-8 BOM on all touched .cs files per .editorconfig.
- Use explicit .Where(...) in the referenced-assembly loop.
CopilotAI review requested due to automatic review settings July 15, 2026 08:00

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

- Isolate per-assembly failures in the runtime warning loop (try/catch around the metadata probe) so unresolvable custom-attribute metadata on one loaded assembly cannot abort discovery, matching the normal discovery path. Clarify in comments that the runtime probe is best-effort (already-loaded assemblies only) and that referenced-provider coverage is the analyzer's responsibility.
- Broaden MSTEST0072 to also trigger on RunAOTCompilation (Blazor WebAssembly AOT) in addition to PublishAot, giving build-time detection for another dynamic-code-disabled runtime. Added RunAOTCompilation as a CompilerVisibleProperty and a unit test.
- Replace the referenced-assembly foreach (whose loop variable was unused) with a single .Any(...) check that reports one no-location diagnostic, fixing the useless-assignment warning.
CopilotAI review requested due to automatic review settings July 15, 2026 08:35
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Resources.resx Outdated
MSTEST0072 now triggers on RunAOTCompilation (Blazor WebAssembly AOT) as well as PublishAot, so the diagnostic title/message/description no longer say only 'Native AOT'. Reword to 'ahead-of-time compilation (such as Native AOT or Blazor WebAssembly AOT)' and regenerate the XLF files for all locales.
CopilotAI review requested due to automatic review settings July 15, 2026 09:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9941

GradeTestNotes
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
AttributeOnReferencedAssembly_
NoDiagnostic
Strong negative assertion via RunAsync(); body is ~45 lines due to multi-project string literals — consider extracting shared setup into a helper to reduce per-test size.
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeOnReferencedAssembly_
Diagnostic
Good use of WithNoLocation() for cross-assembly diagnostic; body is ~45 lines — extracting the multi-project scaffolding into a shared helper would improve readability.
A (90–100)new AssemblyFixtureProviderNativeAotTests.
AssemblyFixtureProvider_
WhenDynamicCodeUnsupported_
IsSkipped
Clear AAA; rich assertions: exit code, summary, and positive and negative output checks all verified.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
NoDiagnostic
Concise, focused negative test; canonical Roslyn markup assertion pattern. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeIsUsed_
Diagnostic
Clean single-scenario test with precise location-aware diagnostic assertion. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeNotUsed_
NoDiagnostic
Well-scoped negative test; verifies silence when the attribute is absent under AOT. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeUsedMultipleTimes_
DiagnosticOnEach
Verifies per-usage diagnostic with two independent markers; correctly tests the each-occurrence contract. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenRunAOTCompilationAndAttributeIsUsed_
Diagnostic
Correctly tests the RunAOTCompilation property path (distinct from PublishAot); canonical markup assertion. No issues found.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
allowed:
- defaults
- "awmgmcpg"

See Network Configuration for more information.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 44.2 AIC · ⌖ 5.65 AIC · ⊞ 8.9K · [◷]( · )

@Evangelink
Amaury Levé (Evangelink) merged commit 179aae0 into mainJul 15, 2026
60 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/aot-il2026-assembly-fixture-provider branch July 15, 2026 10:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer - #9941

Merged
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider
Jul 15, 2026
Merged

Skip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzer#9941
Amaury Levé (Evangelink) merged 6 commits into
mainfrom
dev/amauryleve/aot-il2026-assembly-fixture-provider

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented Jul 14, 2026

Copy link
Copy Markdown
Member

Summary

[AssemblyFixtureProvider] cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies() + load-by-name via AssemblyLoadContext). That is fundamentally a reflection/runtime-loading mechanism and cannot be made reflection-free by the source generator. Under Native AOT it also surfaced an IL2026 — the last MSTest-owned trim/AOT warning a consumer hit when publishing a Native AOT test app with MSTestSourceGenMode=ReflectionFree and warnings-as-errors.

Rather than paper over it with a suppression, this PR makes the behavior explicit: skip the feature when dynamic code is unsupported, and surface it both at build time (analyzer) and at run time (trace warning).

Changes

1. Skip discovery when dynamic code is unsupported (TypeCache.ProviderDiscovery.cs)
Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported. Because ILC constant-folds that switch to false under AOT, the guarded reflection path is statically removed — so the IL2026 disappears with no suppression needed (same pattern already used in DataSerializationHelper).

2. Best-effort runtime warning
When discovery is skipped, emit a trace warning so consumers are not silently deprived of their fixtures. It scans the already-loaded assemblies (AppDomain.GetAssemblies, metadata-only via CustomAttributeData, with per-assembly failure isolation) — it deliberately does not walk the reference graph, so it stays AOT-safe. Consequently it can only see markers on assemblies that happen to be loaded (e.g. a self-applied marker on the test assembly); an unloaded referenced provider is not detectable at run time AOT-safely. Referenced providers are instead covered at build time by the analyzer. The warning is emitted through MTP's diagnostic logger (--diagnostic output).

3. New analyzer MSTEST0072AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzer
Warns at build time when the project opts into an AOT flavor detectable at build time — PublishAot (Native AOT) orRunAOTCompilation (Blazor WebAssembly AOT) — and [AssemblyFixtureProvider] is in play. It inspects both the compilation's own assembly attributes (reported at the attribute location) and referenced assemblies' attributes (reported as a no-location diagnostic), so the documented default usage — the attribute placed on a referenced fixture library consumed by an AOT test project — is covered. PublishAot and RunAOTCompilation are exposed to analyzers via new CompilerVisibleProperty entries in MSTest.TestAdapter.targets. Includes resources (+ regenerated xlf for all 13 locales), AnalyzerReleases.Unshipped.md entry, and unit tests (including the referenced-assembly and RunAOTCompilation scenarios).

4. Acceptance testAssemblyFixtureProviderNativeAotTests verifies that under PublishAot=true (which sets IsDynamicCodeSupported=false for a managed build) the referenced provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.

Notes

  • Analyzer coverage. MSTEST0072 detects [AssemblyFixtureProvider] whether it is declared in the compilation being built or on a referenced library, and it triggers on both build-time-detectable AOT flavors (PublishAot, RunAOTCompilation). The only case it cannot cover is a runtime that disables dynamic code without either build property being set (e.g. Mono iOS AOT), where there is no build-time signal to key off; the best-effort runtime trace warning is the fallback there, limited to already-loaded assemblies as described in change Porting latest changes. #2.
  • Supersedes the earlier suppression-based commit on this branch.

Validation

  • dotnet build of the adapter (net8.0) and MSTest.Analyzers → 0 errors (release-tracking analyzer satisfied).
  • New analyzer unit tests (7, incl. referenced-assembly and RunAOTCompilation cases) pass on net8.0.
  • Downstream: with discovery skipped under AOT, the reflection-free Native AOT publish reaches native codegen with no MSTest-owned IL20xx/IL30xx warnings.

CopilotAI review requested due to automatic review settings July 14, 2026 14:17

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Suppresses the IL2026 trim/AOT warning from assembly fixture provider discovery while extending acceptance-test coverage.

Changes:

  • Isolates and suppresses Assembly.GetReferencedAssemblies().
  • Adds the source file to trim/AOT warning assertions.
Show a summary per file
FileDescription
TypeCache.ProviderDiscovery.csAdds the scoped IL2026 suppression helper.
TrimAndAotAssertions.csGuards against future trim/AOT warnings from provider discovery.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actions

This comment has been minimized.

AssemblyFixtureProvider cross-assembly discovery walks the runtime assembly reference graph (Assembly.GetReferencedAssemblies + load-by-name), which requires capabilities not available when the runtime cannot generate dynamic code (Native AOT, Mono iOS AOT, Blazor WASM AOT). Guard DiscoverFixturesFromProviders on RuntimeFeature.IsDynamicCodeSupported so the feature is skipped there.
Because the ILC substitutes IsDynamicCodeSupported with a constant under AOT, the guarded reflection path is statically removed, so the previously-surfaced IL2026 (from Assembly.GetReferencedAssemblies) disappears without needing an inline suppression. This supersedes the earlier suppression approach.
…ative AOT
Since [AssemblyFixtureProvider] discovery is now skipped under Native AOT (it relies on walking the runtime assembly reference graph), add an analyzer that warns at build time when a project both opts into PublishAot and declares [assembly: AssemblyFixtureProvider], so the silently-ignored feature is surfaced to the user.
PublishAot is exposed to analyzers via a new CompilerVisibleProperty in MSTest.TestAdapter.targets. The diagnostic reports at each attribute application; includes resources (+ regenerated xlf), release tracking, and unit tests.
CopilotAI review requested due to automatic review settings July 14, 2026 15:37
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/aot-il2026-assembly-fixture-provider branch from 359ff8b to b54f046CompareJuly 14, 2026 15:37
@EvangelinkAmaury Levé (Evangelink) changed the title Suppress IL2026 in AssemblyFixtureProvider assembly discoverySkip [AssemblyFixtureProvider] under Native AOT + add MSTEST0072 analyzerJul 14, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 15, 2026
…ime warning
- MSTEST0072 now also inspects referenced assemblies' attributes, so the documented default usage (attribute on a referenced fixture library) is flagged with a no-location diagnostic on the consuming Native AOT project, not just self-applied attributes.
- Add a runtime warning when discovery is skipped because dynamic code is unsupported, covering Mono iOS AOT and Blazor WebAssembly AOT which the PublishAot-keyed analyzer cannot reach. The check is metadata-only (HasAssemblyFixtureProviderMarker) so it stays AOT-safe.
- Use explicit LINQ filtering (.Where/.Any) in the analyzer loops per code-quality feedback.
- Add unit tests for the referenced-assembly scenario (PublishAot true and false).
CopilotAI review requested due to automatic review settings July 15, 2026 07:37

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 21/21 changed files
  • Comments generated: 8
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
Comment threadsrc/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs
@github-actions

This comment has been minimized.

…tance test, encoding, LINQ
- Runtime warning now scans already-loaded assemblies (AppDomain.GetAssemblies, metadata-only) instead of only the test assembly, so a referenced provider library is no longer silent on Mono iOS / Blazor WASM AOT. Stays AOT-safe (no reference-graph walk).
- Add acceptance test AssemblyFixtureProviderNativeAotTests verifying that under PublishAot=true (IsDynamicCodeSupported=false, managed) the provider's AssemblyInitialize/AssemblyCleanup are skipped while the test still passes.
- Restore UTF-8 BOM on all touched .cs files per .editorconfig.
- Use explicit .Where(...) in the referenced-assembly loop.
CopilotAI review requested due to automatic review settings July 15, 2026 08:00

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

This comment has been minimized.

- Isolate per-assembly failures in the runtime warning loop (try/catch around the metadata probe) so unresolvable custom-attribute metadata on one loaded assembly cannot abort discovery, matching the normal discovery path. Clarify in comments that the runtime probe is best-effort (already-loaded assemblies only) and that referenced-provider coverage is the analyzer's responsibility.
- Broaden MSTEST0072 to also trigger on RunAOTCompilation (Blazor WebAssembly AOT) in addition to PublishAot, giving build-time detection for another dynamic-code-disabled runtime. Added RunAOTCompilation as a CompilerVisibleProperty and a unit test.
- Replace the referenced-assembly foreach (whose loop variable was unused) with a single .Any(...) check that reports one no-location diagnostic, fixing the useless-assignment warning.
CopilotAI review requested due to automatic review settings July 15, 2026 08:35
@github-actions

This comment has been minimized.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment threadsrc/Analyzers/MSTest.Analyzers/Resources.resx Outdated
MSTEST0072 now triggers on RunAOTCompilation (Blazor WebAssembly AOT) as well as PublishAot, so the diagnostic title/message/description no longer say only 'Native AOT'. Reword to 'ahead-of-time compilation (such as Native AOT or Blazor WebAssembly AOT)' and regenerate the XLF files for all locales.
CopilotAI review requested due to automatic review settings July 15, 2026 09:34

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 2
  • Review effort level: Medium

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9941

GradeTestNotes
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
AttributeOnReferencedAssembly_
NoDiagnostic
Strong negative assertion via RunAsync(); body is ~45 lines due to multi-project string literals — consider extracting shared setup into a helper to reduce per-test size.
B (80–89)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeOnReferencedAssembly_
Diagnostic
Good use of WithNoLocation() for cross-assembly diagnostic; body is ~45 lines — extracting the multi-project scaffolding into a shared helper would improve readability.
A (90–100)new AssemblyFixtureProviderNativeAotTests.
AssemblyFixtureProvider_
WhenDynamicCodeUnsupported_
IsSkipped
Clear AAA; rich assertions: exit code, summary, and positive and negative output checks all verified.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenNotPublishAot_
NoDiagnostic
Concise, focused negative test; canonical Roslyn markup assertion pattern. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeIsUsed_
Diagnostic
Clean single-scenario test with precise location-aware diagnostic assertion. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeNotUsed_
NoDiagnostic
Well-scoped negative test; verifies silence when the attribute is absent under AOT. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenPublishAotAndAttributeUsedMultipleTimes_
DiagnosticOnEach
Verifies per-usage diagnostic with two independent markers; correctly tests the each-occurrence contract. No issues found.
A (90–100)new AssemblyFixtureProviderNotSupportedWithNativeAotAnalyzerTests.
WhenRunAOTCompilationAndAttributeIsUsed_
Diagnostic
Correctly tests the RunAOTCompilation property path (distinct from PublishAot); canonical markup assertion. No issues found.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
allowed:
- defaults
- "awmgmcpg"

See Network Configuration for more information.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 44.2 AIC · ⌖ 5.65 AIC · ⊞ 8.9K · [◷]( · )

@Evangelink
Amaury Levé (Evangelink) merged commit 179aae0 into mainJul 15, 2026
60 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/aot-il2026-assembly-fixture-provider branch July 15, 2026 10:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@0101