From aea0ada51b55d2f2068d543b569b4fe6a422e4ac Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Tue, 3 Dec 2024 11:13:22 +0000 Subject: [PATCH] Fixes for ASP.NET (Framework) tests --- Directory.Packages.props | 17 +- .../Serialization/MetricSetConverter.cs | 11 +- .../ElasticApmModule.cs | 8 +- .../Areas/MyArea/Web.config | 4 +- .../AspNetFullFrameworkSampleApp.csproj | 10 +- .../Views/Web.config | 4 +- .../AspNetFullFrameworkSampleApp/Web.config | 270 ++++-------------- .../BodyCapturingTests.cs | 84 ++++-- .../TestsBase.cs | 4 +- 9 files changed, 137 insertions(+), 275 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 2029d4bf1..922c7cddc 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -22,7 +22,7 @@ - + @@ -38,6 +38,9 @@ + + + @@ -63,6 +66,7 @@ + @@ -73,18 +77,19 @@ + - + - - + + - + @@ -119,7 +124,7 @@ - + diff --git a/src/Elastic.Apm/Report/Serialization/MetricSetConverter.cs b/src/Elastic.Apm/Report/Serialization/MetricSetConverter.cs index e5c5e3e0e..a922815a8 100644 --- a/src/Elastic.Apm/Report/Serialization/MetricSetConverter.cs +++ b/src/Elastic.Apm/Report/Serialization/MetricSetConverter.cs @@ -19,7 +19,6 @@ public override void Write(Utf8JsonWriter writer, MetricSet value, JsonSerialize writer.WriteStartObject(); if (value.Transaction != null) { - writer.WritePropertyName("transaction"); writer.WriteStartObject(); @@ -35,7 +34,6 @@ public override void Write(Utf8JsonWriter writer, MetricSet value, JsonSerialize if (value.Span != null) { - writer.WritePropertyName("span"); writer.WriteStartObject(); @@ -43,13 +41,15 @@ public override void Write(Utf8JsonWriter writer, MetricSet value, JsonSerialize writer.WritePropertyName("type"); writer.WriteStringValue(value.Span.Type); - writer.WritePropertyName("subtype"); - writer.WriteStringValue(value.Span.SubType); + if (value.Span.SubType is not null) + { + writer.WritePropertyName("subtype"); + writer.WriteStringValue(value.Span.SubType); + } writer.WriteEndObject(); } - writer.WritePropertyName("samples"); writer.WriteStartObject(); @@ -128,6 +128,5 @@ public override MetricSet Read(ref Utf8JsonReader reader, Type typeToConvert, Js return new MetricSet(timestamp, samples); } - } } diff --git a/src/integrations/Elastic.Apm.AspNetFullFramework/ElasticApmModule.cs b/src/integrations/Elastic.Apm.AspNetFullFramework/ElasticApmModule.cs index b00e9cf44..50c8732a3 100644 --- a/src/integrations/Elastic.Apm.AspNetFullFramework/ElasticApmModule.cs +++ b/src/integrations/Elastic.Apm.AspNetFullFramework/ElasticApmModule.cs @@ -212,14 +212,14 @@ private void RestoreContextIfNeeded(HttpContextBase context) if (Agent.Instance == null) { _logger.Trace()? - .Log("Agent.Instance is null during {RequestNotification}. url: {{UrlPath}}", + .Log("Agent.Instance is null during {RequestNotification}. url: {UrlPath}", $"{nameof(OnExecuteRequestStep)}:{EventName()}", urlPath); return; } if (Agent.Instance.Tracer == null) { _logger.Trace()? - .Log("Agent.Instance.Tracer is null during {RequestNotification}. url: {{UrlPath}}", + .Log("Agent.Instance.Tracer is null during {RequestNotification}. url: {UrlPath}", $"{nameof(OnExecuteRequestStep)}:{EventName()}", urlPath); return; } @@ -235,10 +235,10 @@ private void RestoreContextIfNeeded(HttpContextBase context) var spanInApplicationInstance = context.Items[HttpContextCurrentExecutionSegmentsContainer.CurrentSpanKey] is not null; _logger.Trace()? - .Log($"{nameof(ITracer.CurrentTransaction)} is null during {{RequestNotification}}. url: {{UrlPath}}" + .Log("{nameof(ITracer.CurrentTransaction)} is null during {RequestNotification}. url: {UrlPath}" + "(HttpContext.Current Span: {HttpContextCurrentHasSpan}, Transaction: {HttpContextCurrenHasTransaction})" + "(ApplicationContext Span: {ApplicationContextHasSpan}, Transaction: {ApplicationContextHasTransaction})", - $"{nameof(OnExecuteRequestStep)}:{EventName()}", urlPath, spanInCurrent, transactionInCurrent, spanInApplicationInstance, transactionInApplicationInstance + nameof(ITracer.CurrentTransaction), $"{nameof(OnExecuteRequestStep)}:{EventName()}", urlPath, spanInCurrent, transactionInCurrent, spanInApplicationInstance, transactionInApplicationInstance ); if (HttpContext.Current == null) diff --git a/test/iis/AspNetFullFrameworkSampleApp/Areas/MyArea/Web.config b/test/iis/AspNetFullFrameworkSampleApp/Areas/MyArea/Web.config index be8136e17..3554f67c2 100644 --- a/test/iis/AspNetFullFrameworkSampleApp/Areas/MyArea/Web.config +++ b/test/iis/AspNetFullFrameworkSampleApp/Areas/MyArea/Web.config @@ -9,7 +9,7 @@ - + @@ -36,7 +36,7 @@ - + diff --git a/test/iis/AspNetFullFrameworkSampleApp/AspNetFullFrameworkSampleApp.csproj b/test/iis/AspNetFullFrameworkSampleApp/AspNetFullFrameworkSampleApp.csproj index fa30e279b..0117753f2 100644 --- a/test/iis/AspNetFullFrameworkSampleApp/AspNetFullFrameworkSampleApp.csproj +++ b/test/iis/AspNetFullFrameworkSampleApp/AspNetFullFrameworkSampleApp.csproj @@ -15,6 +15,7 @@ MSB4011 false false + true @@ -40,8 +41,8 @@ Library AspNetFullFrameworkSampleApp AspNetFullFrameworkSampleApp - v4.6.2 - net462 + v4.8.1 + net481 win @@ -92,11 +93,16 @@ + + + + + diff --git a/test/iis/AspNetFullFrameworkSampleApp/Views/Web.config b/test/iis/AspNetFullFrameworkSampleApp/Views/Web.config index 60d297323..c7005c55f 100644 --- a/test/iis/AspNetFullFrameworkSampleApp/Views/Web.config +++ b/test/iis/AspNetFullFrameworkSampleApp/Views/Web.config @@ -9,7 +9,7 @@ - + @@ -39,7 +39,7 @@ - + diff --git a/test/iis/AspNetFullFrameworkSampleApp/Web.config b/test/iis/AspNetFullFrameworkSampleApp/Web.config index e44d37826..f6af07b5a 100644 --- a/test/iis/AspNetFullFrameworkSampleApp/Web.config +++ b/test/iis/AspNetFullFrameworkSampleApp/Web.config @@ -1,16 +1,26 @@ - -
+ @@ -23,8 +33,8 @@ - - + + @@ -61,252 +71,68 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + - - + + - - + + diff --git a/test/iis/Elastic.Apm.AspNetFullFramework.Tests/BodyCapturingTests.cs b/test/iis/Elastic.Apm.AspNetFullFramework.Tests/BodyCapturingTests.cs index 3cf80b85f..7d5ef41f4 100644 --- a/test/iis/Elastic.Apm.AspNetFullFramework.Tests/BodyCapturingTests.cs +++ b/test/iis/Elastic.Apm.AspNetFullFramework.Tests/BodyCapturingTests.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Net.Http; using System.Text; +using System.Text.Json; using System.Threading.Tasks; using Elastic.Apm.Helpers; using Elastic.Apm.Tests.Utilities; @@ -44,9 +45,13 @@ private async Task Assert_TextData_RequestBody_IsCaptured(string httpMethod, Sam await SendRequestToSampleAppAndVerifyResponse(new HttpMethod(httpMethod), pathData.Uri, pathData.StatusCode, httpContent: content); await WaitAndCustomVerifyReceivedData(receivedData => { - receivedData.Transactions.Count.Should().Be(1); + receivedData.Transactions.Should().ContainSingle(); var transaction = receivedData.Transactions.Single(); - transaction.Context.Request.Body.Should().Be(textBody); + transaction.Context.Request.Body.Should().BeOfType().Subject.ValueKind.Should().Be(JsonValueKind.String); + if (transaction.Context.Request.Body is JsonElement element) + { + element.GetString().Should().Be(textBody); + } }); } @@ -63,11 +68,15 @@ public async Task TextData_RequestBody_IsCaptured_And_Truncated() await SendGetRequestToSampleAppAndVerifyResponse(pathData.Uri, pathData.StatusCode, httpContent: content); await WaitAndCustomVerifyReceivedData(receivedData => { - receivedData.Transactions.Count.Should().Be(1); + receivedData.Transactions.Should().ContainSingle(); var transaction = receivedData.Transactions.Single(); - var body = transaction.Context.Request.Body.ToString(); - body.Should().Contain(textFragment); - body.Length.Should().Be(RequestBodyStreamHelper.RequestBodyMaxLength); + transaction.Context.Request.Body.Should().BeOfType().Subject.ValueKind.Should().Be(JsonValueKind.String); + if (transaction.Context.Request.Body is JsonElement element) + { + var body = element.GetString(); + body.Should().Contain(textFragment); + body.Should().HaveLength(RequestBodyStreamHelper.RequestBodyMaxLength); + } }); } @@ -91,9 +100,13 @@ private async Task Assert_JsonData_RequestBody_IsCaptured(string httpMethod, Sam await SendRequestToSampleAppAndVerifyResponse(new HttpMethod(httpMethod), pathData.Uri, pathData.StatusCode, httpContent: content); await WaitAndCustomVerifyReceivedData(receivedData => { - receivedData.Transactions.Count.Should().Be(1); + receivedData.Transactions.Should().ContainSingle(); var transaction = receivedData.Transactions.Single(); - transaction.Context.Request.Body.Should().Be(jsonBody); + transaction.Context.Request.Body.Should().BeOfType().Subject.ValueKind.Should().Be(JsonValueKind.String); + if (transaction.Context.Request.Body is JsonElement element) + { + element.GetString().Should().Be(jsonBody); + } }); } @@ -120,9 +133,13 @@ private async Task Assert_FormData_RequestBody_IsCaptured(string httpMethod, Sam await SendRequestToSampleAppAndVerifyResponse(new HttpMethod(httpMethod), pathData.Uri, pathData.StatusCode, httpContent: content); await WaitAndCustomVerifyReceivedData(receivedData => { - receivedData.Transactions.Count.Should().Be(1); + receivedData.Transactions.Should().ContainSingle(); var transaction = receivedData.Transactions.Single(); - transaction.Context.Request.Body.Should().Be("foo=bar&number=23"); + transaction.Context.Request.Body.Should().BeOfType().Subject.ValueKind.Should().Be(JsonValueKind.String); + if (transaction.Context.Request.Body is JsonElement element) + { + element.GetString().Should().Be("foo=bar&number=23"); + } }); } @@ -140,9 +157,13 @@ public async Task FormData_RequestBody_IsCaptured_And_Sanitized() await SendGetRequestToSampleAppAndVerifyResponse(pathData.Uri, pathData.StatusCode, httpContent: content); await WaitAndCustomVerifyReceivedData(receivedData => { - receivedData.Transactions.Count.Should().Be(1); + receivedData.Transactions.Should().ContainSingle(); var transaction = receivedData.Transactions.Single(); - transaction.Context.Request.Body.Should().Be("foo=bar&password=[REDACTED]&number=23"); + transaction.Context.Request.Body.Should().BeOfType().Subject.ValueKind.Should().Be(JsonValueKind.String); + if (transaction.Context.Request.Body is JsonElement element) + { + element.GetString().Should().Be("foo=bar&password=[REDACTED]&number=23"); + } }); } @@ -151,26 +172,31 @@ await WaitAndCustomVerifyReceivedData(receivedData => [InlineData("POST")] public async Task MultipartFormData_RequestBody_IsCaptured(string httpMethod) { - using (var tempFile = new TempFile()) + using var tempFile = new TempFile(); + var pathData = SampleAppUrlPaths.HomePage; + + var data = "just some test data in the file"; + var bytes = Encoding.UTF8.GetBytes(data); + + using (var stream = new FileStream(tempFile.Path, FileMode.OpenOrCreate, FileAccess.Write)) + stream.Write(bytes); + + using var content = new MultipartFormDataContent { - var pathData = SampleAppUrlPaths.HomePage; + { new StreamContent(new FileStream(tempFile.Path, FileMode.Open, FileAccess.Read)), "file", "file" } + }; - var data = $"just some test data in the file"; - var bytes = Encoding.UTF8.GetBytes(data); - using (var stream = new FileStream(tempFile.Path, FileMode.OpenOrCreate, FileAccess.Write)) - stream.Write(bytes); - var content = new MultipartFormDataContent - { - { new StreamContent(new FileStream(tempFile.Path, FileMode.Open, FileAccess.Read)), "file", "file" } - }; - await SendRequestToSampleAppAndVerifyResponse(new HttpMethod(httpMethod), pathData.Uri, pathData.StatusCode, httpContent: content); - await WaitAndCustomVerifyReceivedData(receivedData => + await SendRequestToSampleAppAndVerifyResponse(new HttpMethod(httpMethod), pathData.Uri, pathData.StatusCode, httpContent: content); + await WaitAndCustomVerifyReceivedData(receivedData => + { + receivedData.Transactions.Should().ContainSingle(); + var transaction = receivedData.Transactions.Single(); + transaction.Context.Request.Body.Should().BeOfType().Subject.ValueKind.Should().Be(JsonValueKind.String); + if (transaction.Context.Request.Body is JsonElement element) { - receivedData.Transactions.Count.Should().Be(1); - var transaction = receivedData.Transactions.Single(); - transaction.Context.Request.Body.ToString().Should().Contain(data); - }); - } + element.GetString().Should().Contain(data); + } + }); } } } diff --git a/test/iis/Elastic.Apm.AspNetFullFramework.Tests/TestsBase.cs b/test/iis/Elastic.Apm.AspNetFullFramework.Tests/TestsBase.cs index 636b01c3f..92a0b45c3 100644 --- a/test/iis/Elastic.Apm.AspNetFullFramework.Tests/TestsBase.cs +++ b/test/iis/Elastic.Apm.AspNetFullFramework.Tests/TestsBase.cs @@ -91,9 +91,9 @@ protected TestsBase( private static class DataSentByAgentVerificationConsts { - internal const int LogMessageAfterNInitialAttempts = 30; // i.e., log the first message after 3 seconds (if it's still failing) + internal const int LogMessageAfterNInitialAttempts = 50; // i.e., log the first message after 3 seconds (if it's still failing) internal const int LogMessageEveryNAttempts = 10; // i.e., log message every second (if it's still failing) - internal const int MaxNumberOfAttemptsToVerify = 100; + internal const int MaxNumberOfAttemptsToVerify = 150; internal const int WaitBetweenVerifyAttemptsMs = 100; }