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")); }
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); }
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"]); } }
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"); }
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")); }
public override bool Matches(MockSpan span) { var spanUri = GetTag(span, Tags.HttpUrl); if (spanUri == null || !spanUri.Contains(OriginalUri)) { return(false); } return(base.Matches(span)); }
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." }); } }
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(); }
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")); }
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); }
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")); }
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); }
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")); }
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}."); } } }
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); }
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); }
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); }