示例#1
0
        public async Task When_InvokingMiddlewareWithStatusCode_Expect_SetTag(int statusCode, bool expectedError)
        {
            // Arrange
            MockTracer mockTracer = new MockTracer();

            OpenTracingSpanTaggingMiddleware middleware = new OpenTracingSpanTaggingMiddleware(
                (httpContext) => Task.CompletedTask,
                mockTracer);

            HttpContext context = new DefaultHttpContext();

            context.Response.StatusCode = statusCode;

            // Act
            using (mockTracer.BuildSpan("Unit Test").StartActive())
            {
                await middleware.Invoke(context);
            }

            // Assert
            MockSpan mockSpan = Assert.Single(mockTracer.FinishedSpans());

            if (mockSpan.Tags.ContainsKey("error"))
            {
                Assert.Equal(expectedError, mockSpan.Tags["error"]);
            }

            Assert.Equal(expectedError, mockSpan.Tags.ContainsKey("error"));
        }
示例#2
0
        public async Task When_InvokingMiddlewareWithException_Expect_SetTagError()
        {
            // Arrange
            Exception exception = new Exception("Unit Test");

            MockTracer mockTracer = new MockTracer();

            OpenTracingSpanTaggingMiddleware middleware = new OpenTracingSpanTaggingMiddleware(
                (httpContext) => throw exception,
                mockTracer);

            Exception result;

            // Act
            using (mockTracer.BuildSpan("Unit Test").StartActive())
            {
                result = await Record.ExceptionAsync(() => middleware.Invoke(new DefaultHttpContext()));
            }

            // Assert
            MockSpan mockSpan = Assert.Single(mockTracer.FinishedSpans());

            Assert.True(mockSpan.Tags.ContainsKey("error"));
            Assert.True(Assert.IsType <bool>(mockSpan.Tags["error"]));

            Assert.NotNull(result);
            Assert.Equal(exception, result);
        }
        public async Task ParentNotPickedUp()
        {
            var testClient = new Client(new RequestHandler(_tracer, ignoreActiveSpan: true));

            using (IScope scope = _tracer.BuildSpan("parent").StartActive(finishSpanOnDispose: true))
            {
                string response = await testClient.Send("no_parent");

                Assert.Equal("no_parent:response", response);
            }

            var finished = _tracer.FinishedSpans();

            Assert.Equal(2, finished.Count);

            MockSpan child = GetOneByOperationName(finished, RequestHandler.OperationName);

            Assert.NotNull(child);

            MockSpan parent = GetOneByOperationName(finished, "parent");

            Assert.NotNull(parent);

            // Here check that there is no parent-child relation although it should be because child is
            // created when parent is active
            Assert.NotEqual(parent.Context.SpanId, child.ParentId);
        }
        private static void AssertTargetSpanAnyOf(MockSpan targetSpan, string key, params string[] values)
        {
            string actualValue = targetSpan.Tags[key];

            Assert.Contains(actualValue, values);
            targetSpan.Tags.Remove(key);
        }
示例#5
0
            public void When_CreatingValidationProblemDetailsWithActiveSpan_Expect_ValidationProblemDetailsWithTraceId()
            {
                // Arrange
                ServiceCollection services = new ServiceCollection();

                services.AddScoped <ITracer, MockTracer>();

                IServiceProvider serviceProvider = services.BuildServiceProvider();
                ITracer          tracer          = serviceProvider.GetRequiredService <ITracer>();

                IOptions <ApiBehaviorOptions> options = Options.Create(new ApiBehaviorOptions());
                ProblemDetailsFactory         factory = new CustomProblemDetailsFactory(options);

                ValidationProblemDetails result;

                // Act
                using (tracer.BuildSpan("Unit Test").StartActive())
                {
                    result = factory.CreateValidationProblemDetails(
                        new DefaultHttpContext {
                        RequestServices = serviceProvider
                    },
                        new ModelStateDictionary());
                }

                // Assert
                MockTracer mockTracer = Assert.IsType <MockTracer>(tracer);
                MockSpan   mockSpan   = Assert.Single(mockTracer.FinishedSpans());

                Assert.Equal(mockSpan.Context.TraceId, result.Extensions["traceId"]);
            }
        public void TestRootSpan()
        {
            // Create and finish a root span.
            var tracer = new MockTracer();

            var span = tracer.BuildSpan("tester")
                       .WithStartTimestamp(FixedStartTimestamp)
                       .Start();

            span.SetTag("string", "foo");
            span.SetTag("int", 7);
            span.Log("foo");
            var fields = new Dictionary <string, object> {
                { "f1", 4 }, { "f2", "two" }
            };

            span.Log(GetTestTimestamp(2), fields);
            span.Log(GetTestTimestamp(3), "event name");
            span.Finish(FixedFinishTimestamp);

            List <MockSpan> finishedSpans = tracer.FinishedSpans();

            // Check that the span looks right.

            Assert.Single(finishedSpans);
            MockSpan finishedSpan = finishedSpans[0];

            Assert.Equal("tester", finishedSpan.OperationName);
            Assert.Null(finishedSpan.ParentId);
            Assert.NotNull(finishedSpan.Context.TraceId);
            Assert.NotNull(finishedSpan.Context.SpanId);
            Assert.Equal(FixedStartTimestamp, finishedSpan.StartTimestamp);
            Assert.Equal(FixedFinishTimestamp, finishedSpan.FinishTimestamp);

            var tags = finishedSpan.Tags;

            Assert.Equal(2, tags.Count);
            Assert.Equal(7, tags["int"]);
            Assert.Equal("foo", tags["string"]);

            var logs = finishedSpan.LogEntries;

            Assert.Equal(3, logs.Count);
            {
                MockSpan.LogEntry log = logs[0];
                Assert.Single(log.Fields);
                Assert.Equal("foo", log.Fields["event"]);
            }
            {
                MockSpan.LogEntry log = logs[1];
                Assert.Equal(GetTestTimestamp(2), log.Timestamp);
                Assert.Equal(4, log.Fields["f1"]);
                Assert.Equal("two", log.Fields["f2"]);
            }
            {
                MockSpan.LogEntry log = logs[2];
                Assert.Equal(GetTestTimestamp(3), log.Timestamp);
                Assert.Equal("event name", log.Fields["event"]);
            }
        }
示例#7
0
        private IEnumerable <string> ExpectBasicSpanDataExists(MockSpan span)
        {
            if (string.IsNullOrWhiteSpace(span.Resource))
            {
                yield return("Resource must be set.");
            }

            if (string.IsNullOrWhiteSpace(span.Type))
            {
                yield return("Type must be set.");
            }

            if (string.IsNullOrWhiteSpace(span.Name))
            {
                yield return("Name must be set.");
            }

            if (string.IsNullOrWhiteSpace(span.Service))
            {
                yield return("Service must be set.");
            }

            if (span.TraceId == default)
            {
                yield return("TraceId must be set.");
            }

            if (span.SpanId == default)
            {
                yield return("SpanId must be set.");
            }
        }
        public async Task ParentPickedUp()
        {
            var testClient = new Client(new RequestHandler(_tracer));

            using (IScope scope = _tracer.BuildSpan("parent").StartActive(finishSpanOnDispose: true))
            {
                string response = await testClient.Send("correct_parent");

                Assert.Equal("correct_parent:response", response);
            }

            // Send second request, now there is no active parent.
            string response2 = await testClient.Send("no_parent");

            Assert.Equal("no_parent:response", response2);

            var finished = _tracer.FinishedSpans();

            Assert.Equal(3, finished.Count);

            SortByStartTimestamp(finished);

            MockSpan parent = GetOneByOperationName(finished, "parent");

            Assert.NotNull(parent);

            // now there is parent/child relation between first and second span:
            Assert.Equal(parent.Context.SpanId, finished[1].ParentId);

            // third span should not have parent.
            Assert.Null(finished[2].ParentId);
        }
        private static void CheckSimpleSkipFromAttributeTest(MockSpan targetSpan)
        {
            // Check the Test Status
            AssertTargetSpanEqual(targetSpan, TestTags.Status, TestTags.StatusSkip);

            // Check the Test skip reason
            AssertTargetSpanEqual(targetSpan, TestTags.SkipReason, "Simple skip reason");
        }
示例#10
0
            private bool IsNotServerLifeCheck(MockSpan span)
            {
                span.Tags.TryGetValue(Tags.HttpUrl, out var url);
                if (url == null)
                {
                    return(true);
                }

                return(!url.Contains("alive-check") && !url.Contains("shutdown"));
            }
示例#11
0
        public override bool Matches(MockSpan span)
        {
            var spanUri = GetTag(span, Tags.HttpUrl);

            if (spanUri == null || !spanUri.Contains(OriginalUri))
            {
                return(false);
            }

            return(base.Matches(span));
        }
示例#12
0
        private static void CheckSimpleTestSpan(MockSpan targetSpan)
        {
            // Check the Test Status
            AssertTargetSpanEqual(targetSpan, TestTags.Status, TestTags.StatusPass);

            // Check the `test.message` tag. We check if contains the default or the custom message.
            if (targetSpan.Tags.ContainsKey(TestTags.Message))
            {
                AssertTargetSpanAnyOf(targetSpan, TestTags.Message, new string[] { "Test is ok", "The test passed." });
            }
        }
示例#13
0
 protected override void OnSpanFinished(MockSpan span)
 {
     Console.WriteLine(span);
     Console.WriteLine("Tags:");
     Console.WriteLine(string.Join("; ", span.Tags.Select(e => $"{e.Key} = {e.Value}")));
     Console.WriteLine("Logs:");
     span.LogEntries.ForEach(entry =>
                             Console.WriteLine($"Timestamp: {entry.Timestamp}, Fields: "
                                               + string.Join("; ", entry.Fields.Select(e => $"{e.Key} = {e.Value}"))));
     Console.WriteLine();
 }
示例#14
0
            private bool IsNotServerLifeCheck(MockSpan span)
            {
                var url = SpanExpectation.GetTag(span, Tags.HttpUrl);

                if (url == null)
                {
                    return(true);
                }

                return(!url.Contains("alive-check") && !url.Contains("shutdown"));
            }
示例#15
0
        private static void CheckRuntimeValues(MockSpan targetSpan)
        {
            FrameworkDescription framework = FrameworkDescription.Instance;

            AssertTargetSpanEqual(targetSpan, CommonTags.RuntimeName, framework.Name);
            AssertTargetSpanEqual(targetSpan, CommonTags.RuntimeVersion, framework.ProductVersion);
            AssertTargetSpanEqual(targetSpan, CommonTags.RuntimeArchitecture, framework.ProcessArchitecture);
            AssertTargetSpanEqual(targetSpan, CommonTags.OSArchitecture, framework.OSArchitecture);
            AssertTargetSpanEqual(targetSpan, CommonTags.OSPlatform, framework.OSPlatform);
            AssertTargetSpanEqual(targetSpan, CommonTags.OSVersion, Environment.OSVersion.VersionString);
        }
示例#16
0
        protected override void OnSpanFinished(MockSpan mockSpan)
        {
            base.OnSpanFinished(mockSpan);

            _outputHelper.WriteLine($"TRACE {mockSpan.OperationName}:");
            foreach (var tag in mockSpan.Tags)
            {
                var output = $"  {tag.Key}: {tag.Value}";
                Console.WriteLine(output);
                _outputHelper.WriteLine(output);
            }
        }
        public void TestNonStandardReference()
        {
            MockTracer tracer = new MockTracer(Propagators.TextMap);
            MockSpan   parent = (MockSpan)tracer.BuildSpan("parent").Start();

            MockSpan nextSpan = (MockSpan)tracer.BuildSpan("follows")
                                .AddReference("a_reference", parent.Context)
                                .Start();

            Assert.Equal(parent.Context.SpanId, nextSpan.ParentId);
            Assert.Single(nextSpan.References);
            Assert.Equal(nextSpan.References[0],
                         new MockSpan.Reference(parent.Context, "a_reference"));
        }
示例#18
0
        private static void CompareSpans(MockSpan receivedSpan, OpenTracingSpan openTracingSpan)
        {
            var span = (Span)openTracingSpan.Span;

            receivedSpan.Should().BeEquivalentTo(new
            {
                TraceId  = span.TraceId,
                SpanId   = span.SpanId,
                Name     = span.OperationName,
                Resource = span.ResourceName,
                Service  = span.ServiceName,
                Type     = span.Type,
                Tags     = span.Tags,
            });
        }
        public void TestFollowFromReference()
        {
            MockTracer tracer    = new MockTracer(Propagators.TextMap);
            MockSpan   precedent = (MockSpan)tracer.BuildSpan("precedent").Start();

            MockSpan followingSpan = (MockSpan)tracer.BuildSpan("follows")
                                     .AddReference(References.FollowsFrom, precedent.Context)
                                     .Start();

            Assert.Equal(precedent.Context.SpanId, followingSpan.ParentId);
            Assert.Single(followingSpan.References);

            MockSpan.Reference followsFromRef = followingSpan.References[0];

            Assert.Equal(new MockSpan.Reference(precedent.Context, References.FollowsFrom), followsFromRef);
        }
示例#20
0
        private static void CheckSimpleErrorTest(MockSpan targetSpan)
        {
            // Check the Test Status
            AssertTargetSpanEqual(targetSpan, TestTags.Status, TestTags.StatusFail);

            // Check the span error flag
            Assert.Equal(1, targetSpan.Error);

            // Check the error type
            AssertTargetSpanEqual(targetSpan, Tags.ErrorType, typeof(DivideByZeroException).FullName);

            // Check the error stack
            AssertTargetSpanContains(targetSpan, Tags.ErrorStack, typeof(DivideByZeroException).FullName);

            // Check the error message
            AssertTargetSpanEqual(targetSpan, Tags.ErrorMsg, new DivideByZeroException().Message);
        }
        private static MockSpan GetOneByOperationName(List <MockSpan> spans, string name)
        {
            MockSpan found = null;

            foreach (MockSpan span in spans)
            {
                if (name == span.OperationName)
                {
                    if (found != null)
                    {
                        throw new ArgumentException("there is more than one span with operation name '"
                                                    + name + "'");
                    }
                    found = span;
                }
            }
            return(found);
        }
        private static bool VerifySpan(MockSpan span, bool parentTrace)
        {
            if (!span.Metrics.ContainsKey(Metrics.SamplingPriority))
            {
                return(true);
            }

            if (!parentTrace)
            {
                // The root asp.net trace has an automatic priority
                if (span.Name == "aspnet.request" && span.Resource == "GET /home/sampling")
                {
                    return(span.Metrics[Metrics.SamplingPriority] == 1);
                }
            }

            return(span.Metrics[Metrics.SamplingPriority] == 2);
        }
        public void TestStartTimestamp()
        {
            MockTracer     tracer = new MockTracer();
            DateTimeOffset startTimestamp;
            {
                ISpanBuilder fooSpan = tracer.BuildSpan("foo");
                Thread.Sleep(20);
                startTimestamp = DateTimeOffset.Now;
                fooSpan.Start().Finish();
            }
            List <MockSpan> finishedSpans = tracer.FinishedSpans();

            Assert.Single(finishedSpans);
            MockSpan span = finishedSpans[0];

            Assert.True(startTimestamp <= span.StartTimestamp);
            Assert.True(DateTimeOffset.Now >= span.FinishTimestamp);
        }
        public void TestMultiReferencesBaggage()
        {
            MockTracer tracer = new MockTracer(Propagators.TextMap);
            MockSpan   parent = (MockSpan)tracer.BuildSpan("parent").Start();

            parent.SetBaggageItem("parent", "foo");
            MockSpan precedent = (MockSpan)tracer.BuildSpan("precedent").Start();

            precedent.SetBaggageItem("precedent", "bar");

            MockSpan followingSpan = (MockSpan)tracer.BuildSpan("follows")
                                     .AddReference(References.FollowsFrom, precedent.Context)
                                     .AsChildOf(parent.Context)
                                     .Start();

            Assert.Equal("foo", followingSpan.GetBaggageItem("parent"));
            Assert.Equal("bar", followingSpan.GetBaggageItem("precedent"));
        }
示例#25
0
        private IEnumerable <string> ExpectErrorMatch(MockSpan span)
        {
            var error = GetTag(span, Tags.ErrorMsg);

            if (string.IsNullOrEmpty(error))
            {
                if (IsGraphQLError)
                {
                    yield return($"Expected an error message but {Tags.ErrorMsg} tag is missing or empty.");
                }
            }
            else
            {
                if (!IsGraphQLError)
                {
                    yield return($"Expected no error message but {Tags.ErrorMsg} tag was {error}.");
                }
            }
        }
示例#26
0
        public async Task When_SendingAsyncRespondsWithException_Expect_SetTagError()
        {
            // Arrange
            ServiceCollection services = new ServiceCollection();

            services.AddScoped <ITracer, MockTracer>();

            IServiceProvider serviceProvider = services.BuildServiceProvider();
            ITracer          tracer          = serviceProvider.GetRequiredService <ITracer>();

            IHttpContextAccessor httpContextAccessor = new HttpContextAccessor
            {
                HttpContext = new DefaultHttpContext {
                    RequestServices = serviceProvider
                },
            };

            Exception exception = new Exception();

            OpenTracingSpanTaggingHttpMessageHandler handler = new OpenTracingSpanTaggingHttpMessageHandler(httpContextAccessor)
            {
                InnerHandler = new MockExceptionThrowingInnerHandler(exception),
            };

            Exception result;

            // Act
            using (tracer.BuildSpan("Unit Test").StartActive())
                using (HttpClient client = new HttpClient(handler))
                {
                    result = await Record.ExceptionAsync(() => client.GetAsync(new Uri("http://localhost")));
                }

            // Assert
            MockTracer mockTracer = Assert.IsType <MockTracer>(tracer);
            MockSpan   mockSpan   = Assert.Single(mockTracer.FinishedSpans());

            Assert.True(mockSpan.Tags.ContainsKey("error"));
            Assert.True(Assert.IsType <bool>(mockSpan.Tags["error"]));

            Assert.NotNull(result);
            Assert.Equal(exception, result);
        }
示例#27
0
 private static bool ValidateSpanKey(MockSpan span)
 {
     if (span.Resource.Contains("Batch"))
     {
         return(span.Tags[Tags.AerospikeKey] == "test:myset1:mykey1;test:myset2:mykey2;test:myset3:mykey3");
     }
     else if (span.Resource.Contains("Record"))
     {
         return(span.Tags[Tags.AerospikeKey] == "test:myset1" &&
                span.Tags[Tags.AerospikeNamespace] == "test" &&
                span.Tags[Tags.AerospikeSetName] == "myset1");
     }
     else
     {
         return(span.Tags[Tags.AerospikeKey] == "test:myset1:mykey1" &&
                span.Tags[Tags.AerospikeNamespace] == "test" &&
                span.Tags[Tags.AerospikeSetName] == "myset1" &&
                span.Tags[Tags.AerospikeUserKey] == "mykey1");
     }
 }
        public void TestMultiReferences()
        {
            MockTracer tracer    = new MockTracer(Propagators.TextMap);
            MockSpan   parent    = (MockSpan)tracer.BuildSpan("parent").Start();
            MockSpan   precedent = (MockSpan)tracer.BuildSpan("precedent").Start();

            MockSpan followingSpan = (MockSpan)tracer.BuildSpan("follows")
                                     .AddReference(References.FollowsFrom, precedent.Context)
                                     .AsChildOf(parent.Context)
                                     .Start();

            Assert.Equal(parent.Context.SpanId, followingSpan.ParentId);
            Assert.Equal(2, followingSpan.References.Count);

            MockSpan.Reference followsFromRef = followingSpan.References[0];
            MockSpan.Reference parentRef      = followingSpan.References[1];

            Assert.Equal(new MockSpan.Reference(precedent.Context, References.FollowsFrom), followsFromRef);
            Assert.Equal(new MockSpan.Reference(parent.Context, References.ChildOf), parentRef);
        }
示例#29
0
        public async Task When_SendingAsyncRespondsWithStatusCode_Expect_SetTag(int statusCode, bool expectedError)
        {
            // Arrange
            ServiceCollection services = new ServiceCollection();

            services.AddScoped <ITracer, MockTracer>();

            IServiceProvider serviceProvider = services.BuildServiceProvider();
            ITracer          tracer          = serviceProvider.GetRequiredService <ITracer>();

            IHttpContextAccessor httpContextAccessor = new HttpContextAccessor
            {
                HttpContext = new DefaultHttpContext {
                    RequestServices = serviceProvider
                },
            };

            OpenTracingSpanTaggingHttpMessageHandler handler = new OpenTracingSpanTaggingHttpMessageHandler(httpContextAccessor)
            {
                InnerHandler = new MockResponseReturningInnerHandler(statusCode),
            };

            // Act
            using (tracer.BuildSpan("Unit Test").StartActive())
                using (HttpClient client = new HttpClient(handler))
                {
                    await client.GetAsync(new Uri("http://localhost"));
                }

            // Assert
            MockTracer mockTracer = Assert.IsType <MockTracer>(tracer);
            MockSpan   mockSpan   = Assert.Single(mockTracer.FinishedSpans());

            if (mockSpan.Tags.ContainsKey("error"))
            {
                Assert.Equal(expectedError, mockSpan.Tags["error"]);
            }

            Assert.Equal(expectedError, mockSpan.Tags.ContainsKey("error"));
        }
        public void TestChildSpan()
        {
            // Create and finish a root span.
            MockTracer tracer         = new MockTracer();
            ISpan      originalParent = tracer.BuildSpan("parent").WithStartTimestamp(GetTestTimestamp(100)).Start();
            ISpan      originalChild  = tracer.BuildSpan("child").WithStartTimestamp(GetTestTimestamp(200)).AsChildOf(originalParent).Start();

            originalChild.Finish(GetTestTimestamp(800));
            originalParent.Finish(GetTestTimestamp(900));

            List <MockSpan> finishedSpans = tracer.FinishedSpans();

            // Check that the spans look right.
            Assert.Equal(2, finishedSpans.Count);
            MockSpan child  = finishedSpans[0];
            MockSpan parent = finishedSpans[1];

            Assert.Equal("child", child.OperationName);
            Assert.Equal("parent", parent.OperationName);
            Assert.Equal(parent.Context.SpanId, child.ParentId);
            Assert.Equal(parent.Context.TraceId, child.Context.TraceId);
        }