diff --git a/src/Shared/test/Shared.Tests/StackTraceHelperTest.cs b/src/Shared/test/Shared.Tests/StackTraceHelperTest.cs index 4f3b6ed178de..449396d8c064 100644 --- a/src/Shared/test/Shared.Tests/StackTraceHelperTest.cs +++ b/src/Shared/test/Shared.Tests/StackTraceHelperTest.cs @@ -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() { @@ -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.GenericMethod", 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 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] @@ -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)]