예제 #1
0
        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"]);
        }
예제 #2
0
 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);
예제 #3
0
 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);
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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");
        }
예제 #7
0
 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();
     });
 });
예제 #10
0
 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);
         });
     });
 });
예제 #11
0
        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);
        });
예제 #12
0
        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>();
        });
예제 #16
0
        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"]);
        }
예제 #17
0
        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.
            });
        });
예제 #18
0
        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(); });
 });
예제 #21
0
 public async Task AsyncTask_Valid() =>
 await AssertValidDistributedTracingData(async agent => await agent.Tracer.CaptureTransaction(TestTransaction, UnitTest,
                                                                                              async() => { await WaitHelpers.DelayMinimum(); }, BuildDistributedTracingData(ValidTraceId, ValidParentId, ValidTraceFlags)));