Пример #1
0
        public async Task RetryBackoffSequence_RetriesExceeded()
        {
            var expectedNumSendBatchAsyncCall      = 9; // 1 first call + 8 calls from retries
            var expectedBackoffSequenceFromTestRun = new List <uint>()
            {
                5000,
                10000,
                20000,
                40000,
                80000,
                80000,
                80000,
                80000,
            };
            var actualBackoffSequenceFromTestRun = new List <uint>();
            var actualCountCallsSendData         = 0;

            var dataSender = new TraceDataSender(new TelemetryConfiguration()
            {
                ApiKey = "123456"
            }, null);

            dataSender.WithDelayFunction(async(uint milliSecondsDelay) =>
            {
                actualBackoffSequenceFromTestRun.Add(milliSecondsDelay);
                await Task.Delay(0);
                return;
            });

            dataSender.WithCaptureSendDataAsyncDelegate((newRelicSpanBatch, retryNum) =>
            {
                actualCountCallsSendData++;
            });

            dataSender.WithHttpHandlerImpl((json) =>
            {
                return(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.RequestTimeout)));
            });

            var spans = new List <NewRelicSpan>()
            {
                new NewRelicSpan(
                    traceId: null,
                    spanId: "Test Span",
                    timestamp: 12345,
                    parentSpanId: null,
                    attributes: null),
            };

            var spanBatch = new NewRelicSpanBatch(spans);

            var result = await dataSender.SendDataAsync(spanBatch);

            Assert.Equal(NewRelicResponseStatus.Failure, result.ResponseStatus);
            Assert.Equal(HttpStatusCode.RequestTimeout, result.HttpStatusCode);
            Assert.Equal(expectedNumSendBatchAsyncCall, actualCountCallsSendData);
            Assert.Equal(expectedBackoffSequenceFromTestRun, actualBackoffSequenceFromTestRun);
        }
Пример #2
0
        public async Task SendDataAsyncThrowsNonHttpException()
        {
            const int expectedNumSendBatchAsyncCall = 1;
            const int expectedNumHttpHandlerCall    = 0;

            var dataSender = new TraceDataSender(new TelemetryConfiguration()
            {
                ApiKey = "123456"
            }, null);

            dataSender.WithDelayFunction(async(uint milliSecondsDelay) =>
            {
                await Task.Delay(0);
                return;
            });

            var actualCountCallsSendData = 0;

            dataSender.WithCaptureSendDataAsyncDelegate((sb, retry) =>
            {
                actualCountCallsSendData++;
                throw new Exception("Test Exception");
            });

            var actualCallsHttpHandler = 0;

            dataSender.WithHttpHandlerImpl((json) =>
            {
                actualCallsHttpHandler++;
                return(Task.FromResult(new HttpResponseMessage()
                {
                    StatusCode = HttpStatusCode.OK
                }));
            });

            var spans = new List <NewRelicSpan>()
            {
                new NewRelicSpan(
                    traceId: null,
                    spanId: "Test Span",
                    timestamp: 12345,
                    parentSpanId: null,
                    attributes: null),
            };

            var spanBatch = new NewRelicSpanBatch(spans);

            var result = await dataSender.SendDataAsync(spanBatch);

            Assert.Equal(NewRelicResponseStatus.Failure, result.ResponseStatus);
            Assert.Equal("Test Exception", result.Message);
            Assert.Null(result.HttpStatusCode);

            Assert.Equal(expectedNumSendBatchAsyncCall, actualCountCallsSendData);
            Assert.Equal(expectedNumHttpHandlerCall, actualCallsHttpHandler);
        }
Пример #3
0
        public async Task RetryOn429WithDuration_429HappensOnce()
        {
            const int delayMS = 10000;
            const int expectedNumSendBatchAsyncCall      = 2;
            var       expectedBackoffSequenceFromTestRun = new List <uint>()
            {
                delayMS,
            };

            var actualBackoffSequenceFromTestRun = new List <uint>();

            var dataSender = new TraceDataSender(new TelemetryConfiguration()
            {
                ApiKey = "123456"
            }, null);

            dataSender.WithDelayFunction(async(uint milliSecondsDelay) =>
            {
                actualBackoffSequenceFromTestRun.Add(milliSecondsDelay);
                await Task.Delay(0);
                return;
            });

            var actualCountCallsSendData = 0;

            dataSender.WithCaptureSendDataAsyncDelegate((newRelicSpanBatch, retryNum) =>
            {
                actualCountCallsSendData++;
            });

            dataSender.WithHttpHandlerImpl((json) =>
            {
                if (actualCountCallsSendData < 2)
                {
                    var httpResponse = new HttpResponseMessage((HttpStatusCode)429);
                    httpResponse.Headers.RetryAfter = new System.Net.Http.Headers.RetryConditionHeaderValue(TimeSpan.FromMilliseconds(delayMS));

                    return(Task.FromResult(httpResponse));
                }

                return(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK)));
            });

            var spans = new List <NewRelicSpan>()
            {
                new NewRelicSpan(
                    traceId: null,
                    spanId: "Test Span",
                    timestamp: 12345,
                    parentSpanId: null,
                    attributes: null),
            };

            var spanBatch = new NewRelicSpanBatch(spans);

            var result = await dataSender.SendDataAsync(spanBatch);

            Assert.Equal(NewRelicResponseStatus.Success, result.ResponseStatus);
            Assert.Equal(expectedNumSendBatchAsyncCall, actualCountCallsSendData);
            Assert.Equal(expectedBackoffSequenceFromTestRun, actualBackoffSequenceFromTestRun);
        }
Пример #4
0
        public async Task RequestTooLarge_SplitSuccess()
        {
            const int    expectedCountSpans                 = 9;
            const int    expectedCountCallsSendData         = 7;
            const int    expectedCountSuccessfulSpanBatches = 4;
            const string expectedTraceID = "TestTrace";

            var actualCountCallsSendData = 0;

            // Arrange
            var successfulSpanBatches = new List <NewRelicSpanBatch>();

            var dataSender = new TraceDataSender(new TelemetryConfiguration()
            {
                ApiKey = "123456"
            }, null);

            var okJsons = new List <string>();

            // Mock the behavior to return EntityTooLarge for any span batch with 4 or more spans.
            // Anything with less than 4 will return success.
            dataSender.WithCaptureSendDataAsyncDelegate((spanBatch, retryNum) =>
            {
                actualCountCallsSendData++;

                if (spanBatch.Spans.Count() < 4)
                {
                    okJsons.Add(spanBatch.ToJson());
                    successfulSpanBatches.Add(spanBatch);
                }
            });

            dataSender.WithHttpHandlerImpl((json) =>
            {
                var response = okJsons.Contains(json)
                    ? new HttpResponseMessage(System.Net.HttpStatusCode.OK)
                    : new HttpResponseMessage(System.Net.HttpStatusCode.RequestEntityTooLarge);

                return(Task.FromResult(response));
            });

            var attribs = new Dictionary <string, object>()
            {
                { "testAttrib1", "testAttribValue1" },
            };

            var spans = new List <NewRelicSpan>();

            for (var i = 0; i < expectedCountSpans; i++)
            {
                spans.Add(new NewRelicSpan(null, i.ToString(), i, null, null));
            }

            var spanBatch = new NewRelicSpanBatch(spans, new NewRelicSpanBatchCommonProperties(expectedTraceID, attribs));

            // Act
            await dataSender.SendDataAsync(spanBatch);

            // Assert
            Assert.Equal(expectedCountCallsSendData, actualCountCallsSendData);

            // Test the Spans
            Assert.Equal(expectedCountSuccessfulSpanBatches, successfulSpanBatches.Count);
            Assert.Equal(expectedCountSpans, successfulSpanBatches.SelectMany(x => x.Spans).Count());
            Assert.Equal(expectedCountSpans, successfulSpanBatches.SelectMany(x => x.Spans).Select(x => x.Id).Distinct().Count());

            // Test the attributes on the NewRelicSpanBatch
            Assert.Single(successfulSpanBatches.Select(x => x.CommonProperties.TraceId).Distinct());
            Assert.Equal(expectedTraceID, successfulSpanBatches.FirstOrDefault().CommonProperties.TraceId);
            Assert.Single(successfulSpanBatches.Select(x => x.CommonProperties.Attributes).Distinct());
            Assert.Equal(attribs, successfulSpanBatches.Select(x => x.CommonProperties.Attributes).FirstOrDefault());
        }
Пример #5
0
        public async Task RequestTooLarge_SplitFail()
        {
            const int    expectedCountCallsSendData = 7;
            const string traceID_Success            = "OK";
            const string traceID_SplitBatch_Prefix  = "TooLarge";

            var actualCountCallsSendData = 0;
            var successfulSpans          = new List <NewRelicSpan>();

            var dataSender = new TraceDataSender(new TelemetryConfiguration()
            {
                ApiKey = "123456"
            }, null);

            var shouldSplitJsons = new List <string>();

            // Mock the behavior to return EntityTooLarge for any span batch that has a span with an
            // id that starts with TooLarge.
            dataSender.WithCaptureSendDataAsyncDelegate((newRelicSpanBatch, retryNum) =>
            {
                actualCountCallsSendData++;

                if (newRelicSpanBatch.Spans == null)
                {
                    return;
                }

                if (newRelicSpanBatch.Spans.Any(x => x.Id.StartsWith(traceID_SplitBatch_Prefix)))
                {
                    shouldSplitJsons.Add(newRelicSpanBatch.ToJson());
                }
                else
                {
                    successfulSpans.AddRange(newRelicSpanBatch.Spans);
                }
            });

            dataSender.WithHttpHandlerImpl((json) =>
            {
                var response = shouldSplitJsons.Contains(json)
                    ? new HttpResponseMessage(System.Net.HttpStatusCode.RequestEntityTooLarge)
                    : new HttpResponseMessage(System.Net.HttpStatusCode.OK);

                return(Task.FromResult(response));
            });

            var spans = new List <NewRelicSpan>();

            spans.Add(new NewRelicSpan(null, $"{traceID_SplitBatch_Prefix}1", 0, null, null));
            spans.Add(new NewRelicSpan(null, $"{traceID_SplitBatch_Prefix}2", 0, null, null));
            spans.Add(new NewRelicSpan(null, $"{traceID_SplitBatch_Prefix}3", 0, null, null));
            spans.Add(new NewRelicSpan(null, traceID_Success, 0, null, null));

            // Act
            var result = await dataSender.SendDataAsync(spans);

            // Assert
            Assert.Equal(NewRelicResponseStatus.Failure, result.ResponseStatus);
            Assert.Equal(expectedCountCallsSendData, actualCountCallsSendData);
            Assert.Single(successfulSpans);
            Assert.Equal(traceID_Success, successfulSpans[0].Id);
        }