Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a module initializer to install ThrowingTraceListener #47500

Merged
merged 1 commit into from
Sep 8, 2020

Conversation

sharwell
Copy link
Member

@sharwell sharwell commented Sep 6, 2020

Prevents Debug.Assert failures from calling FailFast on the test process in .NET Core runs.

@sharwell sharwell requested review from a team as code owners September 6, 2020 15:11
<trace>
<listeners>
<remove name="Default" />
<add name="ThrowingTraceListener" type="Microsoft.CodeAnalysis.ThrowingTraceListener, Roslyn.Test.Utilities" />
Copy link
Member

Choose a reason for hiding this comment

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

At one point this file was used to ensure all of the exe that we build in our infra use a throwing trace listener vs. the default ones. How does that work now for our exe files?

Copy link
Member Author

Choose a reason for hiding this comment

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

It never worked. .NET Core does not use this file.

Copy link
Member

Choose a reason for hiding this comment

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

Yes but this is important for .NET Desktop too for the same reasons.

Copy link
Member Author

Choose a reason for hiding this comment

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

The .NET Desktop version of this file has not been changed.
https://github.com/dotnet/roslyn/blob/master/eng/config/test/Desktop/app.config

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETFramework'">
<Compile Include="$(RepositoryEngineeringDir)config\test\Core\InstallTraceListener$(DefaultLanguageSourceExtension)"
Condition="Exists('$(RepositoryEngineeringDir)config\test\Core\InstallTraceListener$(DefaultLanguageSourceExtension)')"/>
</ItemGroup>
Copy link
Member

Choose a reason for hiding this comment

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

Module initializers work on .NET Framework too so why aren't we just universally doing this?

Copy link
Member Author

Choose a reason for hiding this comment

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

With this pull request, the following are covered:

  • .NET Framework test projects (via app.config)
  • .NET Core test projects written in C# (via module initializer)
  • .NET Core test projects written in Visual Basic that use <UseExportProvider>

Keeping app.config for .NET Framework prevents a test gap for some Visual Basic projects.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I think another way of stating is that there is a gap in VB for .NET Core projects with this change. Essentially paths that don't go through <UseExportProvider>. This gap does not exist on desktop because of the app.config work. Correct?

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct. Xunit doesn't offer an AssemblyInitialize extension point, and Visual Basic does not offer module initializers, so we do not have a way to guarantee that the trace listener is installed by the time the first test executes.

Copy link
Member

Choose a reason for hiding this comment

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

K. Think we should doc that so it's clearer what this still gives us.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will submit a follow-up PR to document the condition here.

// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#if !NET5_0
Copy link
Member

Choose a reason for hiding this comment

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

Referencing the .NET 5 TFM issue so we know to come back and change this if the design for what NET5_0 represents changes

dotnet/sdk#13377

// Make sure we run the module initializer for Roslyn.Test.Utilities. C# projects do this via a
// build-injected module initializer, but VB projects can ensure initialization occurs by applying the
// UseExportProviderAttribute to test classes that rely on it.
RuntimeHelpers.RunModuleConstructor(typeof(TestBase).Module.ModuleHandle);
Copy link
Member

Choose a reason for hiding this comment

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

In the case of c# this will cause the constructor to run twice correct?

I don't think this impacts correctness really but wanted to make sure I understood the implications.

Copy link
Member Author

Choose a reason for hiding this comment

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

I have no idea. I was expecting semantics similar to RunClassConstructor, where it's guaranteed to execute at most once, and exactly once by the time this call returns.

Copy link
Member

Choose a reason for hiding this comment

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

@sharwell sharwell merged commit 650d32d into dotnet:master Sep 8, 2020
@ghost ghost added this to the Next milestone Sep 8, 2020
@sharwell sharwell deleted the debug-assert branch September 8, 2020 17:12
@dibarbet dibarbet modified the milestones: Next, 16.8.P4 Sep 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants