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); }
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); }
public async Task RetryOn429WithSpecificDate_429HappensOnce() { const int delayMs = 10000; // The actual retry delay will be slightly less than delayMs since UtcNow is recalculated in RetryWithServerDelay() var errorMargin = TimeSpan.FromMilliseconds(1000).TotalMilliseconds; var actualResponseFromTestRun = new List <Response>(); uint actualDelayFromTestRun = 0; var dataSender = new TraceDataSender(new TelemetryConfiguration() { ApiKey = "123456", MaxRetryAttempts = 1 }, null); dataSender.WithDelayFunction(async(uint milliSecondsDelay) => { actualDelayFromTestRun = milliSecondsDelay; await Task.Delay(0); return; }); dataSender.WithHttpHandlerImpl((json) => { var httpResponse = new HttpResponseMessage((HttpStatusCode)429); var retryOnSpecificTime = DateTimeOffset.UtcNow + TimeSpan.FromMilliseconds(delayMs); httpResponse.Headers.RetryAfter = new System.Net.Http.Headers.RetryConditionHeaderValue(retryOnSpecificTime); return(Task.FromResult(httpResponse)); }); 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.True(actualDelayFromTestRun >= delayMs - errorMargin && actualDelayFromTestRun <= delayMs + errorMargin, $"Expected delay: {delayMs}, margin: +/-{errorMargin}, actual delay: {actualDelayFromTestRun}"); }
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); }