예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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.");
            }
        }
예제 #4
0
        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);
        }
예제 #7
0
        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));
        }
예제 #8
0
        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}.");
                }
            }
        }
예제 #12
0
        /// <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);
        }
예제 #13
0
 /// <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);
 }
예제 #14
0
 private bool IsServerSpan(MockTracerAgent.Span span) =>
 span.Tags.GetValueOrDefault(Tags.SpanKind) == SpanKinds.Server;
예제 #15
0
        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));
                }
            }
        }
예제 #16
0
 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);
 }