Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.LanguageServer;
Expand Down Expand Up @@ -90,6 +91,8 @@ protected TestBase(ITestOutputHelper testOutput)

// Give this thread a name, so it's easier to find in the VS Threads window.
Thread.CurrentThread.Name ??= "Main Thread";

ThrowingTraceListener.ReplaceDefaultListener();
}

Task IAsyncLifetime.InitializeAsync() => InitializeAsync();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root for license information.

using System;
using System.Diagnostics;

namespace Microsoft.AspNetCore.Razor.Test.Common;

public sealed class ThrowingTraceListener : TraceListener
{
public static void ReplaceDefaultListener()
{
// Remove the default trace listener so that Debug.Assert and Debug.Fail don't diplay
// assert dialog during test runs.

var sawThrowingTraceListener = false;
var listeners = Trace.Listeners;
for (var i = listeners.Count - 1; i >= 0; i--)
{
switch (listeners[i])
{
case DefaultTraceListener:
listeners.RemoveAt(i);
break;
case ThrowingTraceListener:
sawThrowingTraceListener = true;
break;
}
}

if (!sawThrowingTraceListener)
{
// Add an instance of the ThrowingTraceListener so that Debug.Assert and Debug.Fail
// throw exceptions during test runs.
listeners.Add(new ThrowingTraceListener());
}
}

public override void Fail(string? message, string? detailMessage)
Copy link
Contributor

Choose a reason for hiding this comment

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

From my understanding, a single test will fail with this exception now instead of hanging the machine right?

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 DefaultTraceListener is responsible for displaying the assert dialog UI when a Debug.Assert or Debug.Fail triggers a failure. This would change such failures to throw an exception. That might fail the test, but only if the exception isn't caught before xUnit sees it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, I'll do this a bit differently. The DefaultTraceListener has some useful behavior too, since it controls Debug.Write(...) as well. I'm thinking that I'll leave it in place but disable the assertion UI.

{
throw new InvalidOperationException(
(string.IsNullOrEmpty(message) ? "Assertion failed" : message) +
(string.IsNullOrEmpty(detailMessage) ? "" : Environment.NewLine + detailMessage));
}

public override void Write(object? o)
{
}

public override void Write(object? o, string? category)
{
}

public override void Write(string? message)
{
}

public override void Write(string? message, string? category)
{
}

public override void WriteLine(object? o)
{
}

public override void WriteLine(object? o, string? category)
{
}

public override void WriteLine(string? message)
{
}

public override void WriteLine(string? message, string? category)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Threading;
using Microsoft.AspNetCore.Razor.Test.Common;
using Microsoft.VisualStudio.Extensibility.Testing;
using Xunit;
using Xunit.Sdk;
Expand Down Expand Up @@ -38,6 +39,8 @@ public abstract class AbstractIntegrationTest : AbstractIdeIntegrationTest

public override async Task InitializeAsync()
{
ThrowingTraceListener.ReplaceDefaultListener();

await base.InitializeAsync();
}
}