diff --git a/test/integrations/Elastic.Apm.AspNetCore.Tests/BaggageAspNetCoreTests.cs b/test/integrations/Elastic.Apm.AspNetCore.Tests/BaggageAspNetCoreTests.cs index f668e462b..1f431fa77 100644 --- a/test/integrations/Elastic.Apm.AspNetCore.Tests/BaggageAspNetCoreTests.cs +++ b/test/integrations/Elastic.Apm.AspNetCore.Tests/BaggageAspNetCoreTests.cs @@ -9,6 +9,7 @@ using Elastic.Apm.Model; using FluentAssertions; using Xunit; +using Xunit.Abstractions; namespace Elastic.Apm.AspNetCore.Tests; @@ -16,6 +17,8 @@ namespace Elastic.Apm.AspNetCore.Tests; public class BaggageAspNetCoreTests : MultiApplicationTestBase { + public BaggageAspNetCoreTests(ITestOutputHelper output) : base(output) { } + private void ValidateOtelAttribute(Transaction transaction, string key, string value) => transaction.Otel.Attributes.Should().Contain(new KeyValuePair($"baggage.{key}", value)); diff --git a/test/integrations/Elastic.Apm.AspNetCore.Tests/DistributedTracingAspNetCoreTests.cs b/test/integrations/Elastic.Apm.AspNetCore.Tests/DistributedTracingAspNetCoreTests.cs index 494c94c99..ab3400335 100644 --- a/test/integrations/Elastic.Apm.AspNetCore.Tests/DistributedTracingAspNetCoreTests.cs +++ b/test/integrations/Elastic.Apm.AspNetCore.Tests/DistributedTracingAspNetCoreTests.cs @@ -3,6 +3,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information +using System; using System.Diagnostics; using System.Linq; using System.Net.Http; @@ -18,6 +19,8 @@ namespace Elastic.Apm.AspNetCore.Tests [Collection("DiagnosticListenerTest")] public class DistributedTracingAspNetCoreTests : MultiApplicationTestBase { + public DistributedTracingAspNetCoreTests(ITestOutputHelper output) : base(output) { } + /// /// Distributed tracing integration test. /// It starts with 1 agent and with another agent. @@ -112,6 +115,8 @@ public async Task DistributedTraceAcross2ServicesWithTraceState() var res = await client.GetAsync("http://localhost:5901/Home/DistributedTracingMiniSample"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.FirstTransaction.IsSampled.Should().BeTrue(); _payloadSender2.FirstTransaction.IsSampled.Should().BeTrue(); @@ -136,6 +141,8 @@ public async Task PreferW3CTraceHeaderOverElasticTraceHeader() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.FirstTransaction.TraceId.Should().Be(expectedTraceId); _payloadSender1.FirstTransaction.ParentId.Should().Be(expectedParentId); } @@ -158,6 +165,8 @@ public async Task TraceContextIgnoreSampledFalse_WithNoTraceState() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + // Assert that the transaction is sampled and the traceparent header was ignored _payloadSender1.FirstTransaction.IsSampled.Should().BeTrue(); @@ -185,6 +194,8 @@ public async Task TraceContextIgnoreSampledFalse_WithEsTraceState_NotSampled() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + // Assert that the transaction is not sampled, so the traceparent header was not ignored _payloadSender1.FirstTransaction.IsSampled.Should().BeFalse(); @@ -212,6 +223,8 @@ public async Task TraceContextIgnoreSampledFalse_WithNonEsTraceState_NotSampled( var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + // Assert that the transaction is sampled and the traceparent header was ignored _payloadSender1.FirstTransaction.IsSampled.Should().BeTrue(); @@ -240,6 +253,8 @@ public async Task TraceContextIgnoreSampledFalse_NotSet_WithNonEsTraceState_NotS var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + // Assert that the transaction is not sampled and the traceparent header was not ignored _payloadSender1.FirstTransaction.IsSampled.Should().BeFalse(); @@ -262,6 +277,8 @@ public async Task TraceContinuationStrategyContinue() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.FirstTransaction.IsSampled.Should().BeTrue(); _payloadSender1.FirstTransaction.ParentId.Should().Be("b7ad6b7169203331"); _payloadSender1.FirstTransaction.TraceId.Should().Be("0af7651916cd43dd8448eb211c80319c"); @@ -284,6 +301,8 @@ public async Task TraceContinuationStrategyDefault() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.FirstTransaction.IsSampled.Should().BeTrue(); _payloadSender1.FirstTransaction.ParentId.Should().Be("b7ad6b7169203331"); _payloadSender1.FirstTransaction.TraceId.Should().Be("0af7651916cd43dd8448eb211c80319c"); @@ -306,6 +325,8 @@ public async Task TraceContinuationStrategyRestartExternalWithNoEsTag() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.FirstTransaction.IsSampled.Should().BeTrue(); _payloadSender1.FirstTransaction.ParentId.Should().NotBe("b7ad6b7169203331"); _payloadSender1.FirstTransaction.TraceId.Should().NotBe("0af7651916cd43dd8448eb211c80319c"); @@ -330,6 +351,8 @@ public async Task TraceContinuationStrategyRestartExternalWithEsTag() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.FirstTransaction.IsSampled.Should().BeTrue(); _payloadSender1.FirstTransaction.ParentId.Should().Be("b7ad6b7169203331"); _payloadSender1.FirstTransaction.TraceId.Should().Be("0af7651916cd43dd8448eb211c80319c"); @@ -352,6 +375,8 @@ public async Task TraceContinuationStrategyRestartWithEsTag() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.FirstTransaction.IsSampled.Should().BeTrue(); _payloadSender1.FirstTransaction.ParentId.Should().NotBe("b7ad6b7169203331"); _payloadSender1.FirstTransaction.TraceId.Should().NotBe("0af7651916cd43dd8448eb211c80319c"); @@ -376,6 +401,8 @@ public async Task TraceContinuationStrategyRestartWithoutEsTag() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.FirstTransaction.IsSampled.Should().BeTrue(); _payloadSender1.FirstTransaction.ParentId.Should().NotBe("b7ad6b7169203331"); _payloadSender1.FirstTransaction.TraceId.Should().NotBe("0af7651916cd43dd8448eb211c80319c"); @@ -401,6 +428,8 @@ public async Task TraceContinuationStrategyRestartExternalAndNoTraceParent() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.Transactions.Should().NotBeNullOrEmpty(); } @@ -423,6 +452,8 @@ public async Task TraceContinuationStrategyRestartExternalAndNoTraceState() var res = await client.GetAsync("http://localhost:5901/Home/Index"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.Transactions.Should().NotBeNullOrEmpty(); // The trace is restarted (due to `traceContinuationStrategy=restart_external`), so assert that the traceId and @@ -454,6 +485,9 @@ private async Task ExecuteAndCheckDistributedCall(bool startActivityBeforeHttpCa var res = await client.GetAsync("http://localhost:5901/Home/DistributedTracingMiniSample"); res.IsSuccessStatusCode.Should().BeTrue(); + _payloadSender1.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender2.WaitForTransactions(TimeSpan.FromSeconds(10)); + _payloadSender1.Transactions.Count.Should().Be(1); _payloadSender2.Transactions.Count.Should().Be(1); diff --git a/test/integrations/Elastic.Apm.AspNetCore.Tests/FailedRequestTests.cs b/test/integrations/Elastic.Apm.AspNetCore.Tests/FailedRequestTests.cs index 159e7b3d4..22430179f 100644 --- a/test/integrations/Elastic.Apm.AspNetCore.Tests/FailedRequestTests.cs +++ b/test/integrations/Elastic.Apm.AspNetCore.Tests/FailedRequestTests.cs @@ -9,7 +9,9 @@ using Elastic.Apm.Api; using Elastic.Apm.DiagnosticSource; using Elastic.Apm.EntityFrameworkCore; +using Elastic.Apm.Logging; using Elastic.Apm.Tests.Utilities; +using Elastic.Apm.Tests.Utilities.XUnit; using FluentAssertions; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; @@ -24,7 +26,7 @@ public class FailedRequestTests : IAsyncLifetime { private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - private readonly MockPayloadSender _payloadSender1 = new MockPayloadSender(); + private MockPayloadSender _payloadSender1; private ApmAgent _agent1; private Task _taskForApp1; @@ -34,7 +36,13 @@ public class FailedRequestTests : IAsyncLifetime public Task InitializeAsync() { - _agent1 = new ApmAgent(new TestAgentComponents(payloadSender: _payloadSender1, configuration: new MockConfiguration(exitSpanMinDuration: "0"))); + var logger = new XUnitLogger(LogLevel.Trace, _output); + _payloadSender1 = new MockPayloadSender(logger); + _agent1 = new ApmAgent(new TestAgentComponents( + payloadSender: _payloadSender1, + configuration: new MockConfiguration(exitSpanMinDuration: "0", flushInterval: "0"), + logger: logger + )); _taskForApp1 = Program.CreateWebHostBuilder(null) .ConfigureLogging(logging => logging.AddXunit(_output)) @@ -71,6 +79,7 @@ public async Task DistributedTraceAcross2Service() var client = new HttpClient(); var res = await client.GetAsync("http://localhost:5901/Home/TriggerError"); res.IsSuccessStatusCode.Should().BeFalse(); + _payloadSender1.WaitForAny(); _payloadSender1.Transactions.Count.Should().Be(1); _payloadSender1.FirstTransaction.Should().NotBeNull(); diff --git a/test/integrations/Elastic.Apm.AspNetCore.Tests/MultiApplicationTestBase.cs b/test/integrations/Elastic.Apm.AspNetCore.Tests/MultiApplicationTestBase.cs index 105b6036e..6bcca0f95 100644 --- a/test/integrations/Elastic.Apm.AspNetCore.Tests/MultiApplicationTestBase.cs +++ b/test/integrations/Elastic.Apm.AspNetCore.Tests/MultiApplicationTestBase.cs @@ -8,11 +8,14 @@ using System.Threading.Tasks; using Elastic.Apm.DiagnosticSource; using Elastic.Apm.EntityFrameworkCore; +using Elastic.Apm.Logging; using Elastic.Apm.Tests.Utilities; +using Elastic.Apm.Tests.Utilities.XUnit; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using SampleAspNetCoreApp; using Xunit; +using Xunit.Abstractions; namespace Elastic.Apm.AspNetCore.Tests; @@ -21,8 +24,9 @@ namespace Elastic.Apm.AspNetCore.Tests; /// public abstract class MultiApplicationTestBase : IAsyncLifetime { - internal readonly MockPayloadSender _payloadSender1 = new(); - internal readonly MockPayloadSender _payloadSender2 = new(); + private readonly ITestOutputHelper _output; + internal MockPayloadSender _payloadSender1; + internal MockPayloadSender _payloadSender2; private readonly CancellationTokenSource _cancellationTokenSource = new(); internal ApmAgent _agent1; internal ApmAgent _agent2; @@ -30,12 +34,18 @@ public abstract class MultiApplicationTestBase : IAsyncLifetime private Task _taskForApp1; private Task _taskForApp2; + public MultiApplicationTestBase(ITestOutputHelper output) => _output = output; + public Task InitializeAsync() { - _agent1 = new ApmAgent(new TestAgentComponents(payloadSender: _payloadSender1, - configuration: new MockConfiguration(exitSpanMinDuration: "0"))); - _agent2 = new ApmAgent(new TestAgentComponents(payloadSender: _payloadSender2, - configuration: new MockConfiguration(exitSpanMinDuration: "0"))); + var logger1 = new XUnitLogger(LogLevel.Trace, _output, "Sender 1"); + _payloadSender1 = new MockPayloadSender(logger1); + var logger2 = new XUnitLogger(LogLevel.Trace, _output, "Sender 2"); + _payloadSender2 = new MockPayloadSender(logger2); + + var configuration = new MockConfiguration(exitSpanMinDuration: "0", flushInterval: "3s"); + _agent1 = new ApmAgent(new TestAgentComponents(payloadSender: _payloadSender1, configuration: configuration, logger: logger1)); + _agent2 = new ApmAgent(new TestAgentComponents(payloadSender: _payloadSender2, configuration: configuration, logger: logger2)); _taskForApp1 = Program.CreateWebHostBuilder(null) .ConfigureServices(services =>