Skip to content

Run AppDomain.GetAssemblies Reflection.Emit test out of process - #136902

Open
jakobbotsch wants to merge 2 commits into
dotnet:mainfrom
jakobbotsch:fix-collectible-ca-test-flake
Open

jakobbotsch wants to merge 2 commits into
dotnet:mainfrom
jakobbotsch:fix-collectible-ca-test-flake

Conversation

@jakobbotsch

@jakobbotsch jakobbotsch commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

TypeBuilderSetCustomAttribute.SetCustomAttribute_ConstructorInfo_ByteArray_TypeArgument_ResolvesAgainstDecoratedModule(RunAndCollect) asserts that a collectible dynamic assembly is collected within 10 GCs. It fails rarely in CI, for example on Windows x86 checked in #135048.

The cause is another test running in parallel in the same process. AssemblyTests.DefineDynamicAssembly_AssemblyBuilderLocationIsEmpty_InternalAssemblyBuilderLocationIsEmpty calls AppDomain.CurrentDomain.GetAssemblies(), which returns strong references to every loaded assembly, including live collectible assemblies created by other tests, and keeps the array alive while it enumerates it. If that snapshot lands between assembly creation and collection in the collectibility test, the assembly stays alive and the assertion fails.

Fix the flakiness by isolating the test that calls AppDomain.GetAssemblies.

The RunAndCollect case of the TypeArgument_ResolvesAgainstDecoratedModule
test asserts that the dynamic assembly is collected within 10 GCs. Tests
running in parallel in the same process can transiently keep it alive, for
example AssemblyTests.DefineDynamicAssembly_AssemblyBuilderLocationIsEmpty_...
calls AppDomain.GetAssemblies() and holds the returned array while it
enumerates it. When that snapshot lands between assembly creation and
collection the assertion fails.

Run the test body under RemoteExecutor so no other tests share the process.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fea5a15e-c5cb-4be1-90bf-822f91431c3c
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @dotnet/area-system-reflection
See info in area-owners.md if you want to be subscribed.

Revert the out of process change to the TypeArgument_ResolvesAgainstDecoratedModule
theory, since other tests in this assembly use the same pattern to verify
collectability. Instead run the test that calls AppDomain.GetAssemblies, and
therefore holds strong references to every loaded assembly, under RemoteExecutor
so it no longer interferes with collectible assemblies from parallel tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fea5a15e-c5cb-4be1-90bf-822f91431c3c
@jakobbotsch jakobbotsch changed the title Run collectible assembly custom attribute test out of process Run AppDomain.GetAssemblies Reflection.Emit test out of process Nov 3, 2026
@jakobbotsch
jakobbotsch requested a review from jkotas November 3, 2026 16:29
[Fact]
// Runs out of process: AppDomain.GetAssemblies() holds strong references to every loaded assembly,
// which can keep collectible assemblies created by tests running in parallel alive.
[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looking around - we use a separate test type with [Collection(nameof(DisableParallelization))] in number of places to deal with this problem. It may be preferable to RemoteExecutor since it won't disable the test on platforms where RemoteExecutor is not supported.

Either way, it looks fine to me.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants