Skip to content
Open
Changes from all commits
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
43 changes: 39 additions & 4 deletions src/Shared/test/Shared.Tests/StackTraceHelperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Microsoft.Extensions.Internal;

public class StackTraceHelperTest
{
private static bool IsMono => Type.GetType("Mono.RuntimeStructs") != null;
[Fact]
public void StackTraceHelper_IncludesLineNumbersForFiles()
{
Expand Down Expand Up @@ -179,7 +180,30 @@ public void StackTraceHelper_ProducesReadableOutput()
var methodNames = stackFrames.Select(stackFrame => stackFrame.MethodDisplayInfo.ToString()).ToArray();

// Assert
Assert.Equal(expectedCallStack, methodNames);
Assert.Equal(expectedCallStack.Count, methodNames.Length);

if (IsMono)
{
// On Mono, verify key components are present but allow for runtime-specific formatting
Assert.Contains("Iterator()+MoveNext()", methodNames[0]);
Assert.Contains("string.Join", methodNames[1]);
Assert.Contains("GenericClass<T>.GenericMethod<V>", methodNames[2]);
Assert.Contains("MethodAsync(int value)", methodNames[3]);

// For async generic method on Mono, check for either resolved form or state machine form
var asyncGenericFrame = methodNames[4];
Assert.True(
asyncGenericFrame.Contains("MethodAsync<TValue>(TValue value)") || // Resolved form
asyncGenericFrame.Contains("MethodAsync") && asyncGenericFrame.Contains("TValue"), // State machine form
$"Expected async generic method info in: {asyncGenericFrame}");

Assert.Contains("Method(string value)", methodNames[5]);
Assert.Contains("StackTraceHelper_ProducesReadableOutput()", methodNames[6]);
}
else
{
Assert.Equal(expectedCallStack, methodNames);
}
}

[Fact]
Expand Down Expand Up @@ -242,9 +266,20 @@ public void GetFrames_DoesNotFailForDynamicallyGeneratedAssemblies()
// Assert
var frame = frames[0];
Assert.Null(frame.FilePath);
// lambda_method{RandomNumber}(Closure )
Assert.StartsWith("lambda_method", frame.MethodDisplayInfo.ToString());
Assert.EndsWith("(Closure )", frame.MethodDisplayInfo.ToString());
var methodDisplay = frame.MethodDisplayInfo.ToString();

if (IsMono)
{
// On Mono, lambda methods may include declaring type prefix (e.g., "object.lambda_method34")
Assert.Contains("lambda_method", methodDisplay);
Assert.EndsWith("(Closure )", methodDisplay);
}
else
{
// On CoreCLR, maintain strict check to prevent regressions
Assert.StartsWith("lambda_method", methodDisplay);
Assert.EndsWith("(Closure )", methodDisplay);
}
}

[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
Expand Down
Loading