public async Task CustomSanitizeFieldNameSettingWithHeaders(string sanitizeFieldNames, string[] headerNames, bool useOnlyDiagnosticSource)
        {
            CreateAgent(useOnlyDiagnosticSource, sanitizeFieldNames);

            foreach (var header in headerNames)
            {
                _client.DefaultRequestHeaders.Add(header, "123");
            }

            await _client.GetAsync("/Home/SimplePage");

            _capturedPayload.WaitForTransactions();
            _capturedPayload.Transactions.Should().ContainSingle();
            _capturedPayload.FirstTransaction.Context.Should().NotBeNull();
            _capturedPayload.FirstTransaction.Context.Request.Should().NotBeNull();
            _capturedPayload.FirstTransaction.Context.Request.Headers.Should().NotBeNull();

            foreach (var header in headerNames)
            {
                _capturedPayload.FirstTransaction.Context.Request.Headers[header].Should().Be(Apm.Consts.Redacted);
            }
        }
Example #2
0
        public void LabelsOnTransactionAndSpan()
        {
            const string transactionName  = TestTransaction;
            const string transactionType  = UnitTest;
            const string spanName         = "TestSpan";
            const string exceptionMessage = "Foo!";
            var          payloadSender    = new MockPayloadSender();

            using (var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)))
            {
                var transaction = agent.Tracer.StartTransaction(transactionName, transactionType);
                transaction.SetLabel("fooTransaction1", "barTransaction1");
                transaction.SetLabel("fooTransaction2", "barTransaction2");

                var span = transaction.StartSpan(spanName, ApiConstants.TypeExternal);
                span.SetLabel("fooSpan1", "barSpan1");
                span.SetLabel("fooSpan2", "barSpan2");

                Thread.Sleep(5);                 //Make sure we have duration > 0

                try
                {
                    throw new InvalidOperationException(exceptionMessage);
                }
                catch (Exception e)
                {
                    span.CaptureException(e);
                }

                span.End();
                transaction.End();
            }

            payloadSender.WaitForTransactions();
            payloadSender.Transactions.Should().ContainSingle();
            payloadSender.WaitForErrors();
            payloadSender.Errors.Should().ContainSingle();
            payloadSender.FirstError.Exception.Message.Should().Be(exceptionMessage);

            payloadSender.FirstTransaction.Context.InternalLabels.Value.MergedDictionary["fooTransaction1"].Value.Should().Be("barTransaction1");
            payloadSender.FirstTransaction.Context.InternalLabels.Value.MergedDictionary["fooTransaction2"].Value.Should().Be("barTransaction2");

            payloadSender.WaitForSpans();
            payloadSender.SpansOnFirstTransaction[0].Context.InternalLabels.Value.MergedDictionary["fooSpan1"].Value.Should().Be("barSpan1");
            payloadSender.SpansOnFirstTransaction[0].Context.InternalLabels.Value.MergedDictionary["fooSpan2"].Value.Should().Be("barSpan2");
        }
Example #3
0
        public void CaptureCustom()
        {
            var payloadSender = new MockPayloadSender();
            var customValue   = "b".Repeat(10_000);
            var customKey     = "a";

            using (var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)))
            {
                var transaction = agent.Tracer.StartTransaction(TestTransaction, CustomTransactionTypeForTests);
                transaction.Custom.Add(customKey, customValue);
                transaction.End();
            }

            payloadSender.WaitForTransactions();
            payloadSender.FirstTransaction.Should().NotBeNull();
            payloadSender.FirstTransaction.Custom[customKey].Should().Be(customValue);
        }
Example #4
0
        private async Task <MockPayloadSender> AssertWith1TransactionAnd1SpanAsyncOnSubSpan(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("SubSpan", "SubSpanType", 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);

            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);
        }
Example #5
0
        public void CustomServiceSetTwice()
        {
            var payloadSender = new MockPayloadSender();

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender));

            var transaction1 = agent.Tracer.StartTransaction("Transaction1", "test");

            transaction1.SetService("Service1", "1.0-beta1");

            transaction1.SetService("Service2", "1.0-beta2");
            transaction1.End();

            payloadSender.WaitForTransactions();
            payloadSender.FirstTransaction.Should().NotBeNull();
            payloadSender.FirstTransaction?.Context.Service.Name.Should().Be("Service2");
            payloadSender.FirstTransaction?.Context.Service.Version.Should().Be("1.0-beta2");
        }
Example #6
0
        public void TransactionResultTest()
        {
            const string transactionName = TestTransaction;
            const string transactionType = UnitTest;
            var          payloadSender   = new MockPayloadSender();

            using (var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)))
            {
                var transaction = agent.Tracer.StartTransaction(transactionName, transactionType);

                const string result = "success";
                transaction.Result = result;
                transaction.End();

                payloadSender.WaitForTransactions();
                payloadSender.Transactions[0].Result.Should().Be(result);
            }
        }
Example #7
0
    public void UnsampledTransactionWithSpansOnV8OrNewer()
    {
        var payloadSender = new MockPayloadSender();

        using (var agent = new ApmAgent(new TestAgentComponents(apmServerInfo: MockApmServerInfo.Version80, payloadSender: payloadSender,
                                                                configuration: new MockConfiguration(transactionSampleRate: "0"))))
        {
            agent.Tracer.CaptureTransaction("foo", "bar", (t) =>
            {
                t.CaptureSpan("span1", "testSpan", (s1) => s1.CaptureSpan("span2", "testSpan", () => { }));
                t.CaptureSpan("span3", "testSpan", () => { });
            });
        }

        payloadSender.WaitForTransactions(TimeSpan.FromMilliseconds(100));
        payloadSender.Transactions.Should().BeNullOrEmpty();
        payloadSender.Spans.Should().BeNullOrEmpty();
    }
Example #8
0
        private void AssertWith1TransactionAnd1SpanOnSubSpan(Action <ISpan> action)
        {
            var payloadSender = new MockPayloadSender();

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender));

            WaitHelpers.SleepMinimum();
            agent.Tracer.CaptureTransaction(TransactionName, TransactionType, t =>
            {
                WaitHelpers.SleepMinimum();
                t.CaptureSpan("aa", "bb", s =>                 //TODO Name
                {
                    WaitHelpers.SleepMinimum();
                    action(s);
                });
            });

            payloadSender.WaitForTransactions();
            payloadSender.Transactions.Should().NotBeEmpty();

            payloadSender.FirstTransaction.Name.Should().Be(TransactionName);
            payloadSender.FirstTransaction.Type.Should().Be(TransactionType);

            payloadSender.WaitForSpans();
            payloadSender.SpansOnFirstTransaction.Should().NotBeEmpty();

            payloadSender.SpansOnFirstTransaction[0].Name.Should().Be(SpanName);
            payloadSender.SpansOnFirstTransaction[0].Type.Should().Be(SpanType);

            var duration = payloadSender.FirstTransaction.Duration;

            duration.Should().BeGreaterOrEqualToMinimumSleepLength(3);

            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);
        }
Example #9
0
        public void AgentDisabledBasicTransaction()
        {
            var payloadSender = new MockPayloadSender();
            var configReader  = new MockConfiguration(enabled: "false");

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, configuration: configReader));
            agent.Tracer.CurrentTransaction.Should().BeNull();
            var transaction = agent.Tracer.StartTransaction("TestTransaction", "Test");

            transaction.Should().NotBeOfType <Transaction>();
            transaction.Should().BeOfType <NoopTransaction>();

            agent.Tracer.CurrentTransaction.Should().Be(transaction);

            transaction.End();

            payloadSender.SignalEndTransactions();
            agent.Tracer.CurrentTransaction.Should().BeNull();
            payloadSender.WaitForTransactions();
            payloadSender.Transactions.Should().BeNullOrEmpty();
        }
Example #10
0
        public void CustomServiceTest()
        {
            var payloadSender = new MockPayloadSender();

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender));

            var transaction1 = agent.Tracer.StartTransaction("Transaction1", "test");

            transaction1.SetService("Service1", "1.0-beta1");
            transaction1.End();

            var transaction2 = agent.Tracer.StartTransaction("Transaction2", "test");

            transaction2.SetService("Service2", "1.0-beta2");
            transaction2.End();

            var transaction3 = agent.Tracer.StartTransaction("Transaction3", "test");

            transaction3.End();

            payloadSender.WaitForTransactions();
            payloadSender.Transactions.Count.Should().Be(3);

            var recordedTransaction1 = payloadSender.Transactions.FirstOrDefault(t => t.Name == "Transaction1");

            recordedTransaction1.Should().NotBeNull();
            recordedTransaction1?.Context.Service.Name.Should().Be("Service1");
            recordedTransaction1?.Context.Service.Version.Should().Be("1.0-beta1");

            var recordedTransaction2 = payloadSender.Transactions.FirstOrDefault(t => t.Name == "Transaction2");

            recordedTransaction2.Should().NotBeNull();
            recordedTransaction2?.Context.Service.Name.Should().Be("Service2");
            recordedTransaction2?.Context.Service.Version.Should().Be("1.0-beta2");

            var recordedTransaction3 = payloadSender.Transactions.FirstOrDefault(t => t.Name == "Transaction3");

            recordedTransaction3.Should().NotBeNull();
            recordedTransaction3?.Context.Service.Should().BeNull();
        }
Example #11
0
        /// <summary>
        /// Shared between ErrorOnTransaction and ErrorOnTransactionWithCulprit
        /// </summary>
        /// <param name="culprit">Culprit.</param>
        private static void ErrorOnTransactionCommon(string culprit = null)
        {
            const string transactionName  = TestTransaction;
            const string transactionType  = UnitTest;
            const string exceptionMessage = "Foo!";
            var          payloadSender    = new MockPayloadSender();

            using (var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)))
            {
                var transaction = agent.Tracer.StartTransaction(transactionName, transactionType);

                Thread.Sleep(5);                 //Make sure we have duration > 0
                try
                {
                    throw new InvalidOperationException(exceptionMessage);
                }
                catch (Exception e)
                {
                    if (string.IsNullOrEmpty(culprit))
                    {
                        transaction.CaptureException(e);
                    }
                    else
                    {
                        transaction.CaptureException(e, culprit);
                    }
                }

                transaction.End();
            }

            payloadSender.WaitForTransactions();
            payloadSender.Transactions.Should().ContainSingle();
            payloadSender.WaitForErrors();
            payloadSender.Errors.Should().ContainSingle();
            payloadSender.FirstError.Exception.Message.Should().Be(exceptionMessage);
            payloadSender.FirstError.Exception.Message.Should().Be(exceptionMessage);

            payloadSender.FirstError.Culprit.Should().Be(!string.IsNullOrEmpty(culprit) ? culprit : "Elastic.Apm.Tests.ApiTests.ApiTests");
        }
Example #12
0
        public void SpansShouldNotBeSent_WhenTransactionMaxSpansIsEqualToZero()
        {
            // Arrange
            var mockPayloadSender = new MockPayloadSender();
            var mockConfig        = new MockConfigSnapshot(transactionMaxSpans: "0");

            // Act
            using (var agent = new ApmAgent(new TestAgentComponents(config: mockConfig, payloadSender: mockPayloadSender)))
            {
                agent.Tracer.CaptureTransaction("test transaction name", "test transaction type",
                                                transaction =>
                                                transaction.CaptureSpan("test span name", "test span type", span => { })
                                                );
            }

            // Assert
            mockPayloadSender.WaitForTransactions();
            mockPayloadSender.Transactions.Count.Should().Be(1);
            mockPayloadSender.Spans.Count.Should().Be(0);
            mockPayloadSender.FirstTransaction.SpanCount.Dropped.Should().Be(1);
            mockPayloadSender.FirstTransaction.SampleRate.Should().Be(1);
        }
Example #13
0
        public void AgentDisabledTransactionWithLambda()
        {
            var payloadSender = new MockPayloadSender();
            var configReader  = new MockConfiguration(enabled: "false");

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, configuration: configReader));
            var codeExecuted = false;

            agent.Tracer.CaptureTransaction("TestTransaction", "Test", transaction =>
            {
                codeExecuted = true;
                transaction.Should().NotBeOfType <Transaction>();
                transaction.Should().BeOfType <NoopTransaction>();

                // ReSharper disable AccessToDisposedClosure
                agent.Tracer.CurrentTransaction.Should().NotBeNull();
                agent.Tracer.CurrentTransaction.Should().Be(transaction);
            });

            codeExecuted.Should().BeTrue();
            payloadSender.SignalEndTransactions();
            payloadSender.WaitForTransactions();
            payloadSender.Transactions.Should().BeNullOrEmpty();
        }
Example #14
0
        /// <summary>
        /// Asserts on 1 transaction with 1 async span and 1 error
        /// </summary>
        private async Task <MockPayloadSender> AssertWith1TransactionAnd1ErrorAnd1SpanAsync(Func <ITransaction, 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 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);

            payloadSender.WaitForErrors();
            payloadSender.Errors.Should().NotBeEmpty();

            payloadSender.FirstError.Exception.Type.Should().Be(typeof(InvalidOperationException).FullName);
            payloadSender.FirstError.Exception.Message.Should().Be(ExceptionMessage);

            return(payloadSender);
        }
Example #15
0
        public async Task Capture_Transaction_When_Receive_From_Queue()
        {
            await using var scope = await QueueScope.CreateWithQueue(_adminClient);

            var sender   = _client.CreateSender(scope.QueueName);
            var receiver = _client.CreateReceiver(scope.QueueName);

            await sender.SendMessageAsync(
                new ServiceBusMessage("test message")).ConfigureAwait(false);

            await receiver.ReceiveMessageAsync(TimeSpan.FromSeconds(30)).ConfigureAwait(false);

            if (!_sender.WaitForTransactions(TimeSpan.FromMinutes(2)))
            {
                throw new Exception("No transaction received in timeout");
            }

            _sender.Transactions.Should().HaveCount(1);
            var transaction = _sender.FirstTransaction;

            transaction.Name.Should().Be($"{ServiceBus.SegmentName} RECEIVE from {scope.QueueName}");
            transaction.Type.Should().Be(ApiConstants.TypeMessaging);
        }
Example #16
0
        public void ChangeTransactionContextAfterError()
        {
            var mockPayloadSender = new MockPayloadSender();

            using var agent = new ApmAgent(new TestAgentComponents(payloadSender: mockPayloadSender));

            agent.Tracer.CaptureTransaction("Test", "Test", t =>
            {
                t.Context.Request = new Request("GET", new Url {
                    Full = "http://localhost", Protocol = "http", Search = "abc"
                })
                {
                    Body = "abc", Headers = new Dictionary <string, string> {
                        { "header1", "headerValue" }
                    }
                };
                t.Context.Response = new Response {
                    StatusCode = 404, Finished = false
                };

                t.SetLabel("foo", "bar");
                // Let's capture an error
                t.CaptureError("Test Error", "Test", new StackTrace().GetFrames());

                // Let's change CurrentTransaction.Context after the error is captured
                t.Context.Request.Method             = "PUT";
                t.Context.Request.Body               = "cde";
                t.Context.Request.Headers["header2"] = "headerValue";
                t.Context.Request.Url.Full           = "http://elastic.co";
                t.Context.Request.Url.Protocol       = "tcp";
                t.Context.Request.Url.Search         = "cde";
                t.Context.Response.StatusCode        = 500;
                t.Context.Response.Finished          = true;
                t.Context.InternalLabels.Value.InnerDictionary["foo"].Value.Should().Be("bar");

                // Asserts on the captured error
                mockPayloadSender.WaitForErrors();
                mockPayloadSender.FirstError.Should().NotBeNull("first error should not be null");
                mockPayloadSender.FirstError.Context.Should().NotBeNull("context should not be null");
                mockPayloadSender.FirstError.Context.Request.Method.Should().Be("GET");
                mockPayloadSender.FirstError.Context.Request.Body.Should().Be("abc");
                mockPayloadSender.FirstError.Context.Request.Headers.Count.Should().Be(1);
                mockPayloadSender.FirstError.Context.Request.Headers["header1"].Should().Be("headerValue");
                mockPayloadSender.FirstError.Context.Request.Url.Full.Should().Be("http://localhost");
                mockPayloadSender.FirstError.Context.Request.Url.Protocol.Should().Be("http");
                mockPayloadSender.FirstError.Context.Request.Url.Search.Should().Be("abc");
                mockPayloadSender.FirstError.Context.Response.StatusCode.Should().Be(404);
                mockPayloadSender.FirstError.Context.Response.Finished.Should().BeFalse();
                mockPayloadSender.FirstError.Context.InternalLabels.Value.InnerDictionary["foo"].Value.Should().Be("bar");
                mockPayloadSender.FirstError.Context.Response.Headers.Should().BeNull();
            });

            // Asserts on the captured transaction
            mockPayloadSender.WaitForTransactions();
            mockPayloadSender.FirstTransaction.Context.Request.Method.Should().Be("PUT");
            mockPayloadSender.FirstTransaction.Context.Request.Body.Should().Be("cde");
            mockPayloadSender.FirstTransaction.Context.Request.Headers.Count.Should().Be(2);
            mockPayloadSender.FirstTransaction.Context.Request.Headers["header1"].Should().Be("headerValue");
            mockPayloadSender.FirstTransaction.Context.Request.Headers["header2"].Should().Be("headerValue");
            mockPayloadSender.FirstTransaction.Context.Request.Url.Full.Should().Be("http://elastic.co");
            mockPayloadSender.FirstTransaction.Context.Request.Url.Protocol.Should().Be("tcp");
            mockPayloadSender.FirstTransaction.Context.Request.Url.Search.Should().Be("cde");
            mockPayloadSender.FirstTransaction.Context.Response.StatusCode.Should().Be(500);
            mockPayloadSender.FirstTransaction.Context.Response.Finished.Should().BeTrue();
            mockPayloadSender.FirstTransaction.Context.InternalLabels.Value.InnerDictionary["foo"].Value.Should().Be("bar");
            mockPayloadSender.FirstTransaction.Context.Response.Headers.Should().BeNull();
        }
        public async Task HomeSimplePageTransactionTest(bool withDiagnosticSourceOnly)
        {
            _client = Helper.ConfigureHttpClient(true, withDiagnosticSourceOnly, _agent, _factory);

            var headerKey   = "X-Additional-Header";
            var headerValue = "For-Elastic-Apm-Agent";

            _client.DefaultRequestHeaders.Add(headerKey, headerValue);
            var response = await _client.GetAsync("/Home/SimplePage");

            //test service
            _capturedPayload.WaitForTransactions();
            _capturedPayload.Transactions.Should().ContainSingle();

            _agent.Service.Name.Should()
            .NotBeNullOrWhiteSpace()
            .And.NotBe(ConfigConsts.DefaultValues.UnknownServiceName);

            _agent.Service.Agent.Name.Should().Be(Apm.Consts.AgentName);
            var apmVersion = typeof(Agent).Assembly.GetCustomAttribute <AssemblyInformationalVersionAttribute>().InformationalVersion;

            _agent.Service.Agent.Version.Should().Be(apmVersion);

            _agent.Service.Framework.Name.Should().Be("ASP.NET Core");

            var aspNetCoreVersion = Assembly.Load("Microsoft.AspNetCore").GetName().Version.ToString();

            _agent.Service.Framework.Version.Should().Be(aspNetCoreVersion);

            _agent.Service.Runtime.Name.Should().Be(Runtime.DotNetCoreName);
            _agent.Service.Runtime.Version.Should().Be(Directory.GetParent(typeof(object).Assembly.Location).Name);

            var transaction     = _capturedPayload.FirstTransaction;
            var transactionName = $"{response.RequestMessage.Method} Home/SimplePage";

            transaction.Name.Should().Be(transactionName);
            transaction.Result.Should().Be("HTTP 2xx");
            transaction.Duration.Should().BeGreaterThan(0);
            transaction.Outcome.Should().Be(Outcome.Success);

            transaction.Type.Should().Be("request");
            transaction.Id.Should().NotBeEmpty();

            //test transaction.context.response
            transaction.Context.Response.StatusCode.Should().Be(200);
            if (_agent.ConfigurationReader.CaptureHeaders)
            {
                transaction.Context.Response.Headers.Should().NotBeNull();
                transaction.Context.Response.Headers.Should().NotBeEmpty();

                transaction.Context.Response.Headers.Should().ContainKeys(headerKey);
                transaction.Context.Response.Headers[headerKey].Should().Be(headerValue);
            }

            //test transaction.context.request
#if NETCOREAPP3_0 || NETCOREAPP3_1
            transaction.Context.Request.HttpVersion.Should().Be("2");
#else
            transaction.Context.Request.HttpVersion.Should().Be("2.0");
#endif
            transaction.Context.Request.Method.Should().Be("GET");

            //test transaction.context.request.url
            transaction.Context.Request.Url.Full.Should().Be(response.RequestMessage.RequestUri.AbsoluteUri);
            transaction.Context.Request.Url.HostName.Should().Be("localhost");
            transaction.Context.Request.Url.Protocol.Should().Be("HTTP");

            if (_agent.ConfigurationReader.CaptureHeaders)
            {
                transaction.Context.Request.Headers.Should().NotBeNull();
                transaction.Context.Request.Headers.Should().NotBeEmpty();

                transaction.Context.Request.Headers.Should().ContainKeys(headerKey);
                transaction.Context.Request.Headers[headerKey].Should().Be(headerValue);
            }

            //test transaction.context.request.encrypted
            transaction.Context.Request.Socket.Encrypted.Should().BeFalse();
        }