protected async Task AssertHttpSpan( string path, MockTracerAgent agent, int httpPort, HttpStatusCode expectedHttpStatusCode, string expectedSpanType, string expectedOperationName, string expectedResourceName) { IImmutableList <MockTracerAgent.Span> spans; using (var httpClient = new HttpClient()) { // disable tracing for this HttpClient request httpClient.DefaultRequestHeaders.Add(HttpHeaderNames.TracingEnabled, "false"); var response = await httpClient.GetAsync($"http://localhost:{httpPort}" + path); var content = await response.Content.ReadAsStringAsync(); Output.WriteLine($"[http] {response.StatusCode} {content}"); Assert.Equal(expectedHttpStatusCode, response.StatusCode); spans = agent.WaitForSpans(1); Assert.True(spans.Count == 1, "expected one span"); } MockTracerAgent.Span span = spans[0]; Assert.Equal(expectedSpanType, span.Type); Assert.Equal(expectedOperationName, span.Name); Assert.Equal(expectedResourceName, span.Resource); }
protected async Task AssertHttpSpan( string path, int agentPort, int httpPort, HttpStatusCode expectedHttpStatusCode, string expectedSpanType, string expectedOperationName, string expectedResourceName) { List <MockTracerAgent.Span> spans; using (var agent = new MockTracerAgent(agentPort)) using (var httpClient = new HttpClient()) { var response = await httpClient.GetAsync($"http://localhost:{httpPort}" + path); var content = await response.Content.ReadAsStringAsync(); Output.WriteLine($"[http] {response.StatusCode} {content}"); Assert.Equal(expectedHttpStatusCode, response.StatusCode); spans = agent.WaitForSpans(1); Assert.True(spans.Count == 1, "expected one span"); } MockTracerAgent.Span span = spans[0]; Assert.Equal(expectedSpanType, span.Type); Assert.Equal(expectedOperationName, span.Name); Assert.Equal(expectedResourceName, span.Resource); }
private IEnumerable <string> ExpectBasicSpanDataExists(MockTracerAgent.Span 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."); } }
protected async Task AssertWebServerSpan( string path, MockTracerAgent agent, int httpPort, HttpStatusCode expectedHttpStatusCode, bool isError, string expectedErrorType, string expectedErrorMessage, string expectedSpanType, string expectedOperationName, string expectedResourceName, string expectedServiceVersion, IDictionary <string, string> expectedTags = null) { IImmutableList <MockTracerAgent.Span> spans; using (var httpClient = new HttpClient()) { // disable tracing for this HttpClient request httpClient.DefaultRequestHeaders.Add(HttpHeaderNames.TracingEnabled, "false"); var testStart = DateTime.UtcNow; var response = await httpClient.GetAsync($"http://localhost:{httpPort}" + path); var content = await response.Content.ReadAsStringAsync(); Output.WriteLine($"[http] {response.StatusCode} {content}"); Assert.Equal(expectedHttpStatusCode, response.StatusCode); spans = agent.WaitForSpans( count: 1, minDateTime: testStart, operationName: expectedOperationName); Assert.True(spans.Count == 1, "expected one span"); } MockTracerAgent.Span span = spans[0]; // base properties Assert.Equal(expectedSpanType, span.Type); Assert.Equal(expectedOperationName, span.Name); Assert.Equal(expectedResourceName, span.Resource); // errors Assert.Equal(isError, span.Error == 1); Assert.Equal(expectedErrorType, span.Tags.GetValueOrDefault(Tags.ErrorType)); Assert.Equal(expectedErrorMessage, span.Tags.GetValueOrDefault(Tags.ErrorMsg)); // other tags Assert.Equal(SpanKinds.Server, span.Tags.GetValueOrDefault(Tags.SpanKind)); Assert.Equal(expectedServiceVersion, span.Tags.GetValueOrDefault(Tags.Version)); if (expectedTags is not null) { foreach (var expectedTag in expectedTags) { Assert.Equal(expectedTag.Value, span.Tags.GetValueOrDefault(expectedTag.Key)); } } }
public override bool IsSimpleMatch(MockTracerAgent.Span span) { return(span.Name == OperationName && span.Type == Type && !string.IsNullOrEmpty(GetTag(span, Tags.ErrorMsg)) == IsGraphQLError && SourceStringsAreEqual(GetTag(span, Tags.GraphQLSource), GraphQLSource)); }
protected string GetTag(MockTracerAgent.Span span, string tag) { if (span.Tags.ContainsKey(tag)) { return(span.Tags[tag]); } return(null); }
public override bool Matches(MockTracerAgent.Span span) { var spanUri = GetTag(span, Tags.HttpUrl); if (spanUri == null || !spanUri.Contains(OriginalUri)) { return(false); } return(base.Matches(span)); }
protected async Task AssertAspNetSpanOnly( string path, MockTracerAgent agent, int httpPort, HttpStatusCode expectedHttpStatusCode, bool isError, string expectedErrorType, string expectedErrorMessage, string expectedSpanType, string expectedResourceName, string expectedServiceVersion) { IImmutableList <MockTracerAgent.Span> spans; using (var httpClient = new HttpClient()) { // disable tracing for this HttpClient request httpClient.DefaultRequestHeaders.Add(HttpHeaderNames.TracingEnabled, "false"); var testStart = DateTime.UtcNow; var response = await httpClient.GetAsync($"http://localhost:{httpPort}" + path); var content = await response.Content.ReadAsStringAsync(); Output.WriteLine($"[http] {response.StatusCode} {content}"); Assert.Equal(expectedHttpStatusCode, response.StatusCode); spans = agent.WaitForSpans( count: 1, minDateTime: testStart, operationName: "aspnet.request", returnAllOperations: true); Assert.True(spans.Count == 1, $"expected two span, saw {spans.Count}"); } MockTracerAgent.Span span = spans[0]; // base properties Assert.Equal(expectedResourceName, span.Resource); Assert.Equal(expectedSpanType, span.Type); // errors Assert.Equal(isError, span.Error == 1); Assert.Equal(expectedErrorType, span.Tags.GetValueOrDefault(Tags.ErrorType)); Assert.Equal(expectedErrorMessage, span.Tags.GetValueOrDefault(Tags.ErrorMsg)); // other tags Assert.Equal(SpanKinds.Server, span.Tags.GetValueOrDefault(Tags.SpanKind)); Assert.Equal(expectedServiceVersion, span.Tags.GetValueOrDefault(Tags.Version)); }
public override bool IsMatch(MockTracerAgent.Span span, out string message) { var mismatches = new List <string>(); if (span.Name != OperationName) { mismatches.Add(FailureMessage(nameof(OperationName), actual: span.Name, expected: OperationName)); } if (span.Service != ServiceName) { mismatches.Add(FailureMessage(nameof(ServiceName), actual: span.Service, expected: ServiceName)); } if (span.Type != Type) { mismatches.Add(FailureMessage(nameof(Type), actual: span.Type, expected: Type)); } var spanIsError = !string.IsNullOrEmpty(GetTag(span, Tags.ErrorMsg)); if (spanIsError != IsGraphQLError) { mismatches.Add(FailureMessage(nameof(IsGraphQLError), actual: spanIsError.ToString(), expected: IsGraphQLError.ToString())); } var actualSource = GetTag(span, Tags.GraphQLSource); if (!SourceStringsAreEqual(actualSource, GraphQLSource)) { mismatches.Add(FailureMessage(nameof(GraphQLSource), actual: actualSource, expected: GraphQLSource)); } var actualGraphQLOperationType = GetTag(span, Tags.GraphQLOperationType); if (actualGraphQLOperationType != GraphQLOperationType) { mismatches.Add(FailureMessage(nameof(GraphQLOperationType), actual: actualGraphQLOperationType, expected: GraphQLOperationType)); } if (CustomAssertion != null) { mismatches.AddRange(CustomAssertion(span)); } message = string.Join(", ", mismatches); return(!mismatches.Any()); }
public virtual bool IsMatch(MockTracerAgent.Span span, out string message) { var mismatches = new List <string>(); if (span.Name != OperationName) { mismatches.Add(FailureMessage(nameof(OperationName), actual: span.Name, expected: OperationName)); } if (span.Service != ServiceName) { mismatches.Add(FailureMessage(nameof(ServiceName), actual: span.Service, expected: ServiceName)); } if (span.Type != Type) { mismatches.Add(FailureMessage(nameof(Type), actual: span.Type, expected: Type)); } var expectedResourceName = ResourceName.TrimEnd(); if (span.Resource != expectedResourceName) { mismatches.Add(FailureMessage(nameof(ResourceName), actual: span.Resource, expected: expectedResourceName)); } var actualStatusCode = GetTag(span, Tags.HttpStatusCode); var actualHttpMethod = GetTag(span, Tags.HttpMethod); if (StatusCode != null && actualStatusCode != StatusCode) { mismatches.Add(FailureMessage(nameof(StatusCode), actual: actualStatusCode, expected: StatusCode)); } if (actualHttpMethod != HttpMethod) { mismatches.Add(FailureMessage(nameof(HttpMethod), actual: actualHttpMethod, expected: HttpMethod)); } if (CustomAssertion != null) { mismatches.AddRange(CustomAssertion(span)); } message = string.Join(", ", mismatches); return(!mismatches.Any()); }
private IEnumerable <string> ExpectErrorMatch(MockTracerAgent.Span 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}."); } } }
/// <summary> /// The aggregate assertion which is run for a test. /// </summary> /// <param name="span">The span being asserted against.</param> /// <param name="message">The developer friendly message for the test failure.</param> /// <returns>Whether the span meets expectations.</returns> public bool MeetsExpectations(MockTracerAgent.Span span, out string message) { message = string.Empty; var messages = new List <string>(); foreach (var assertion in Assertions) { var mismatchMessage = assertion(span); if (!string.IsNullOrWhiteSpace(mismatchMessage)) { messages.Add(mismatchMessage); } } if (messages.Any()) { message = string.Join(",", messages); return(false); } return(true); }
/// <summary> /// Override for custom filters. /// </summary> /// <param name="span">The span on which to filter.</param> /// <returns>Whether the span qualifies for this expectation.</returns> public virtual bool Matches(MockTracerAgent.Span span) { return(span.Service == ServiceName && span.Name == OperationName && span.Type == Type); }
private bool IsServerSpan(MockTracerAgent.Span span) => span.Tags.GetValueOrDefault(Tags.SpanKind) == SpanKinds.Server;
protected async Task AssertWebServerSpan( string path, MockTracerAgent agent, int httpPort, HttpStatusCode expectedHttpStatusCode, bool isError, string expectedAspNetErrorType, string expectedAspNetErrorMessage, string expectedErrorType, string expectedErrorMessage, string expectedSpanType, string expectedOperationName, string expectedAspNetResourceName, string expectedResourceName, string expectedServiceVersion, SerializableDictionary expectedTags = null) { IImmutableList <MockTracerAgent.Span> spans; using (var httpClient = new HttpClient()) { // disable tracing for this HttpClient request httpClient.DefaultRequestHeaders.Add(HttpHeaderNames.TracingEnabled, "false"); var testStart = DateTime.UtcNow; var response = await httpClient.GetAsync($"http://localhost:{httpPort}" + path); var content = await response.Content.ReadAsStringAsync(); Output.WriteLine($"[http] {response.StatusCode} {content}"); Assert.Equal(expectedHttpStatusCode, response.StatusCode); agent.SpanFilters.Add(IsServerSpan); spans = agent.WaitForSpans( count: 2, minDateTime: testStart, returnAllOperations: true); Assert.True(spans.Count == 2, $"expected two span, saw {spans.Count}"); } MockTracerAgent.Span aspnetSpan = spans.Where(s => s.Name == "aspnet.request").FirstOrDefault(); MockTracerAgent.Span innerSpan = spans.Where(s => s.Name == expectedOperationName).FirstOrDefault(); Assert.NotNull(aspnetSpan); Assert.Equal(expectedAspNetResourceName, aspnetSpan.Resource); Assert.NotNull(innerSpan); Assert.Equal(expectedResourceName, innerSpan.Resource); foreach (MockTracerAgent.Span span in spans) { // base properties Assert.Equal(expectedSpanType, span.Type); // errors Assert.Equal(isError, span.Error == 1); if (span == aspnetSpan) { Assert.Equal(expectedAspNetErrorType, span.Tags.GetValueOrDefault(Tags.ErrorType)); Assert.Equal(expectedAspNetErrorMessage, span.Tags.GetValueOrDefault(Tags.ErrorMsg)); } else if (span == innerSpan) { Assert.Equal(expectedErrorType, span.Tags.GetValueOrDefault(Tags.ErrorType)); Assert.Equal(expectedErrorMessage, span.Tags.GetValueOrDefault(Tags.ErrorMsg)); } // other tags Assert.Equal(SpanKinds.Server, span.Tags.GetValueOrDefault(Tags.SpanKind)); Assert.Equal(expectedServiceVersion, span.Tags.GetValueOrDefault(Tags.Version)); } if (expectedTags?.Values is not null) { foreach (var expectedTag in expectedTags) { Assert.Equal(expectedTag.Value, innerSpan.Tags.GetValueOrDefault(expectedTag.Key)); } } }
public static string GetTag(MockTracerAgent.Span span, string tag) { span.Tags.TryGetValue(tag, out var value); return(value); }
public virtual bool IsSimpleMatch(MockTracerAgent.Span span) { return(span.Resource == ResourceName && span.Name == OperationName && span.Type == Type); }