public async Task TagsOnTransactionAsyncError() { var payloadSender = await AssertWith1TransactionAnd1ErrorAsync( async t => { await Assert.ThrowsAsync <InvalidOperationException>(async() => { await t.Tracer.CaptureTransaction(TransactionName, TransactionType, async transaction => { await WaitHelpers.DelayMinimum(); transaction.Tags["foo"] = "bar"; if (new Random().Next(1) == 0) //avoid unreachable code warning. { throw new InvalidOperationException(ExceptionMessage); } }); }); }); //According to the Intake API tags are stored on the Context (and not on Transaction.Tags directly). Assert.Equal("bar", payloadSender.FirstTransaction.Context.Tags["foo"]); //Also make sure the tag is visible directly on Transaction.Tags. Assert.Equal("bar", payloadSender.Payloads[0].Transactions[0].Tags["foo"]); }
public async Task AsyncTaskWithParameter_Invalid(string traceId, string parentId, string traceFlags) => await AssertInvalidDistributedTracingData(async agent => await agent.Tracer.CaptureTransaction(TestTransaction, UnitTest, async t => { t.Should().NotBeNull(); await WaitHelpers.DelayMinimum(); }, BuildDistributedTracingData(traceId, parentId, traceFlags)), traceId);
public async Task AsyncTaskWithReturnType_Invalid(string traceId, string parentId, string traceFlags) => await AssertInvalidDistributedTracingData(async agent => await agent.Tracer.CaptureTransaction(TestTransaction, UnitTest, async() => { await WaitHelpers.DelayMinimum(); return(42); }, BuildDistributedTracingData(traceId, parentId, traceFlags)), traceId);
/// <summary> /// Asserts on 1 transaction with 1 async Span /// </summary> private async Task <MockPayloadSender> AssertWith1TransactionAnd1SpanAsync(Func <ITransaction, Task> func) { var payloadSender = new MockPayloadSender(); var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)); await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async t => { await WaitHelpers.DelayMinimum(); await func(t); }); payloadSender.WaitForTransactions(); payloadSender.Transactions.Should().NotBeEmpty(); payloadSender.FirstTransaction.Name.Should().Be(TransactionName); payloadSender.FirstTransaction.Type.Should().Be(TransactionType); var duration = payloadSender.FirstTransaction.Duration; duration.Should().BeGreaterOrEqualToMinimumSleepLength(3); payloadSender.WaitForSpans(); payloadSender.SpansOnFirstTransaction.Should().NotBeEmpty(); payloadSender.SpansOnFirstTransaction[0].Name.Should().Be(SpanName); payloadSender.SpansOnFirstTransaction[0].Type.Should().Be(SpanType); return(payloadSender); }
/// <summary> /// Asserts on 1 transaction with 1 async Span /// </summary> private async Task <MockPayloadSender> AssertWith1TransactionAnd1SpanAsync(Func <ITransaction, Task> func) { var payloadSender = new MockPayloadSender(); var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)); await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async t => { await WaitHelpers.DelayMinimum(); await func(t); }); Assert.NotEmpty(payloadSender.Payloads); Assert.NotEmpty(payloadSender.Payloads[0].Transactions); Assert.Equal(TransactionName, payloadSender.Payloads[0].Transactions[0].Name); Assert.Equal(TransactionType, payloadSender.Payloads[0].Transactions[0].Type); var duration = payloadSender.Payloads[0].Transactions[0].Duration; WaitHelpers.Assert3XMinimumSleepLength(duration); Assert.NotEmpty(payloadSender.SpansOnFirstTransaction); Assert.Equal(SpanName, payloadSender.SpansOnFirstTransaction[0].Name); Assert.Equal(SpanType, payloadSender.SpansOnFirstTransaction[0].Type); return(payloadSender); }
public async Task LabelsOnTransactionAsyncError() { var payloadSender = await AssertWith1TransactionAnd1ErrorAsync( async t => { Func <Task> act = async() => { await t.Tracer.CaptureTransaction(TransactionName, TransactionType, async transaction => { await WaitHelpers.DelayMinimum(); transaction.Labels["foo"] = "bar"; if (new Random().Next(1) == 0) //avoid unreachable code warning. { throw new InvalidOperationException(ExceptionMessage); } }); }; await act.Should().ThrowAsync <InvalidOperationException>(); }); //According to the Intake API labels are stored on the Context (and not on Transaction.Labels directly). payloadSender.FirstTransaction.Context.Labels.Should().Contain("foo", "bar"); //Also make sure the label is visible directly on Transaction.Labels. payloadSender.FirstTransaction.Labels.Should().Contain("foo", "bar"); }
public async Task AsyncTaskWithReturnTypeAndParameter_Valid() => await AssertValidDistributedTracingData(async agent => await agent.Tracer.CaptureTransaction(TestTransaction, UnitTest, async t => { t.Should().NotBeNull(); await WaitHelpers.DelayMinimum(); return(42); }, BuildDistributedTracingData(ValidTraceId, ValidParentId, ValidTraceFlags)));
public async Task AsyncTaskWithReturnType() => await AssertWith1TransactionAsync(async agent => { var res = await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async() => { await WaitHelpers.DelayMinimum(); return(42); }); res.Should().Be(42); });
public async Task AsyncTaskWithParameter() => await AssertWith1TransactionAsync(async agent => { await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async t => { t.Should().NotBeNull(); await WaitHelpers.DelayMinimum(); }); });
public async Task AsyncTaskWithException() => await AssertWith1TransactionAnd1ErrorAsync(async agent => { await Assert.ThrowsAsync <InvalidOperationException>(async() => { await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async() => { await WaitHelpers.DelayMinimum(); throw new InvalidOperationException(ExceptionMessage); }); }); });
public async Task AsyncTaskWithReturnTypeAndParameter() => await AssertWith1TransactionAsync(async agent => { var res = await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async t => { Assert.NotNull(t); await WaitHelpers.DelayMinimum(); return(42); }); Assert.Equal(42, res); });
private async Task <MockPayloadSender> AssertWith1TransactionAnd1ErrorAnd1SpanAsyncOnSubSpan(Func <ISpan, Task> func) { var payloadSender = new MockPayloadSender(); using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)); await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async t => { await WaitHelpers.DelayMinimum(); await t.CaptureSpan("TestSpan", "TestSpanType", async s => { await WaitHelpers.DelayMinimum(); await func(s); }); }); payloadSender.WaitForTransactions(); payloadSender.Transactions.Should().NotBeEmpty(); payloadSender.FirstTransaction.Name.Should().Be(TransactionName); payloadSender.FirstTransaction.Type.Should().Be(TransactionType); var duration = payloadSender.FirstTransaction.Duration; duration.Should().BeGreaterOrEqualToMinimumSleepLength(3); payloadSender.WaitForSpans(); payloadSender.SpansOnFirstTransaction.Should().NotBeEmpty(); payloadSender.SpansOnFirstTransaction[0].Name.Should().Be(SpanName); payloadSender.SpansOnFirstTransaction[0].Type.Should().Be(SpanType); payloadSender.WaitForErrors(); payloadSender.Errors.Should().NotBeEmpty(); payloadSender.FirstError.Exception.Type.Should().Be(typeof(InvalidOperationException).FullName); payloadSender.FirstError.Exception.Message.Should().Be(ExceptionMessage); var orderedSpans = payloadSender.Spans.OrderBy(n => n.Timestamp).ToList(); var firstSpan = orderedSpans.First(); var innerSpan = orderedSpans.Last(); firstSpan.ParentId.Should().Be(payloadSender.FirstTransaction.Id); innerSpan.ParentId.Should().Be(firstSpan.Id); firstSpan.TransactionId.Should().Be(payloadSender.FirstTransaction.Id); innerSpan.TransactionId.Should().Be(payloadSender.FirstTransaction.Id); return(payloadSender); }
public async Task AsyncTaskWithExceptionAndParameter() => await AssertWith1TransactionAnd1ErrorAsync(async agent => { Func <Task> act = async() => { await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async t => { t.Should().NotBeNull(); await WaitHelpers.DelayMinimum(); throw new InvalidOperationException(ExceptionMessage); }); }; await act.Should().ThrowAsync <InvalidOperationException>(); });
public async Task LabelsOnTransactionAsync() { var payloadSender = await AssertWith1TransactionAsync( async t => { await t.Tracer.CaptureTransaction(TransactionName, TransactionType, async transaction => { await WaitHelpers.DelayMinimum(); transaction.Labels["foo"] = "bar"; }); }); //According to the Intake API labels are stored on the Context (and not on Transaction.Labels directly). payloadSender.FirstTransaction.Context.Labels.Should().Contain("foo", "bar"); //Also make sure the label is visible directly on Transaction.Labels. payloadSender.FirstTransaction.Labels.Should().Contain("foo", "bar"); }
public async Task AsyncTaskWithReturnTypeAndException() => await AssertWith1TransactionAnd1ErrorAsync(async agent => { Func <Task> act = async() => { await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async() => { await WaitHelpers.DelayMinimum(); if (new Random().Next(1) == 0) //avoid unreachable code warning. { throw new InvalidOperationException(ExceptionMessage); } return(42); }); }; await act.Should().ThrowAsync <InvalidOperationException>(); });
public async Task TagsOnTransactionAsync() { var payloadSender = await AssertWith1TransactionAsync( async t => { await t.Tracer.CaptureTransaction(TransactionName, TransactionType, async transaction => { await WaitHelpers.DelayMinimum(); transaction.Tags["foo"] = "bar"; }); }); //According to the Intake API tags are stored on the Context (and not on Transaction.Tags directly). Assert.Equal("bar", payloadSender.FirstTransaction.Context.Tags["foo"]); //Also make sure the tag is visible directly on Transaction.Tags. Assert.Equal("bar", payloadSender.Payloads[0].Transactions[0].Tags["foo"]); }
public async Task AsyncTaskWithReturnTypeAndException() => await AssertWith1TransactionAnd1ErrorAsync(async agent => { await Assert.ThrowsAsync <InvalidOperationException>(async() => { var result = await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async() => { await WaitHelpers.DelayMinimum(); if (new Random().Next(1) == 0) //avoid unreachable code warning. { throw new InvalidOperationException(ExceptionMessage); } return(42); }); Assert.True(false); //Should not be executed because the agent isn't allowed to catch an exception. Assert.Equal(42, result); //But if it'd not throw it'd be 42. }); });
public async Task CancelledAsyncTask() { var payloadSender = new MockPayloadSender(); var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)); var cancellationTokenSource = new CancellationTokenSource(); var token = cancellationTokenSource.Token; cancellationTokenSource.Cancel(); await Assert.ThrowsAsync <OperationCanceledException>(async() => { await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async() => { // ReSharper disable once MethodSupportsCancellation, we want to delay before we throw the exception await WaitHelpers.DelayMinimum(); token.ThrowIfCancellationRequested(); }); }); Assert.NotEmpty(payloadSender.Payloads); Assert.NotEmpty(payloadSender.Payloads[0].Transactions); Assert.Equal(TransactionName, payloadSender.Payloads[0].Transactions[0].Name); Assert.Equal(TransactionType, payloadSender.Payloads[0].Transactions[0].Type); var duration = payloadSender.Payloads[0].Transactions[0].Duration; Assert.True(duration >= WaitHelpers.SleepLength, $"Expected {duration} to be greater or equal to: {WaitHelpers.SleepLength}"); Assert.NotEmpty(payloadSender.Errors); Assert.NotEmpty(payloadSender.Errors[0].Errors); Assert.Equal("A task was canceled", payloadSender.Errors[0].Errors[0].Culprit); Assert.Equal("Task canceled", payloadSender.Errors[0].Errors[0].Exception.Message); }
public async Task CancelledAsyncTask() { var payloadSender = new MockPayloadSender(); var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)); var cancellationTokenSource = new CancellationTokenSource(); var token = cancellationTokenSource.Token; cancellationTokenSource.Cancel(); Func <Task> act = async() => { await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async() => { // ReSharper disable once MethodSupportsCancellation, we want to delay before we throw the exception await WaitHelpers.DelayMinimum(); token.ThrowIfCancellationRequested(); }); }; await act.Should().ThrowAsync <OperationCanceledException>(); payloadSender.Transactions.Should().NotBeEmpty(); payloadSender.FirstTransaction.Name.Should().Be(TransactionName); payloadSender.FirstTransaction.Type.Should().Be(TransactionType); var duration = payloadSender.FirstTransaction.Duration; duration.Should().BeGreaterOrEqualToMinimumSleepLength(); payloadSender.Errors.Should().NotBeEmpty(); payloadSender.FirstError.Culprit.Should().Be("A task was canceled"); payloadSender.FirstError.Exception.Message.Should().Be("Task canceled"); }
public async Task AsyncTask() => await AssertWith1TransactionAsync(async agent => { await agent.Tracer.CaptureTransaction(TransactionName, TransactionType, async() => { await WaitHelpers.DelayMinimum(); }); });
public async Task AsyncTask_Valid() => await AssertValidDistributedTracingData(async agent => await agent.Tracer.CaptureTransaction(TestTransaction, UnitTest, async() => { await WaitHelpers.DelayMinimum(); }, BuildDistributedTracingData(ValidTraceId, ValidParentId, ValidTraceFlags)));