public async Task Can_write_payload_successfully()
        {
            // Arrange
            var httpMessageHandlerMock = new Mock <HttpMessageHandler>();

            httpMessageHandlerMock.Protected().Setup <Task <HttpResponseMessage> >(
                "SendAsync",
                ItExpr.IsAny <HttpRequestMessage>(),
                ItExpr.IsAny <CancellationToken>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));

            var settings = new MetricsReportingDatadogOptions
            {
                Datadog = new DatadogOptions
                {
                    BaseUri = new Uri("http://localhost"),
                    ApiKey  = "123"
                },
                HttpPolicy = new HttpPolicy()
            };

            var hostedMetricsClient = DatadogReporterBuilder.CreateClient(settings, settings.HttpPolicy, httpMessageHandlerMock.Object);

            // Act
            var response = await hostedMetricsClient.WriteAsync(Payload, CancellationToken.None);

            // Assert
            response.Success.Should().BeTrue();
        }
        public async Task Should_back_off_when_reached_max_failures_then_retry_after_backoff_period()
        {
            var httpMessageHandlerMock = new Mock <HttpMessageHandler>();

            httpMessageHandlerMock.Protected().Setup <Task <HttpResponseMessage> >(
                "SendAsync",
                ItExpr.IsAny <HttpRequestMessage>(),
                ItExpr.IsAny <CancellationToken>()).
            Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)));
            var policy = new HttpPolicy {
                FailuresBeforeBackoff = 3, BackoffPeriod = TimeSpan.FromSeconds(1)
            };
            var settings = new MetricsReportingDatadogOptions
            {
                Datadog = new DatadogOptions
                {
                    BaseUri = new Uri("http://localhost"),
                    ApiKey  = "123"
                },
                HttpPolicy = new HttpPolicy()
            };
            var hostedMetricsClient = DatadogReporterBuilder.CreateClient(settings, policy, httpMessageHandlerMock.Object);

            foreach (var attempt in Enumerable.Range(0, 10))
            {
                await hostedMetricsClient.WriteAsync(Payload, CancellationToken.None);

                if (attempt <= policy.FailuresBeforeBackoff)
                {
                    httpMessageHandlerMock.Protected().Verify <Task <HttpResponseMessage> >(
                        "SendAsync",
                        Times.AtLeastOnce(),
                        ItExpr.IsAny <HttpRequestMessage>(),
                        ItExpr.IsAny <CancellationToken>());
                }
                else
                {
                    httpMessageHandlerMock.Protected().Verify <Task <HttpResponseMessage> >(
                        "SendAsync",
                        Times.AtMost(3),
                        ItExpr.IsAny <HttpRequestMessage>(),
                        ItExpr.IsAny <CancellationToken>());
                }
            }

            await Task.Delay(policy.BackoffPeriod);

            httpMessageHandlerMock = new Mock <HttpMessageHandler>();
            httpMessageHandlerMock.Protected().Setup <Task <HttpResponseMessage> >(
                "SendAsync",
                ItExpr.IsAny <HttpRequestMessage>(),
                ItExpr.IsAny <CancellationToken>()).Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));

            hostedMetricsClient = DatadogReporterBuilder.CreateClient(settings, policy, httpMessageHandlerMock.Object);

            var response = await hostedMetricsClient.WriteAsync(Payload, CancellationToken.None);

            response.Success.Should().BeTrue();
        }
        public async Task Should_back_off_when_reached_max_failures()
        {
            // Arrange
            var httpMessageHandlerMock = new Mock <HttpMessageHandler>();

            httpMessageHandlerMock.Protected().Setup <Task <HttpResponseMessage> >(
                "SendAsync",
                ItExpr.IsAny <HttpRequestMessage>(),
                ItExpr.IsAny <CancellationToken>()).
            Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)));
            var policy = new HttpPolicy {
                FailuresBeforeBackoff = 3, BackoffPeriod = TimeSpan.FromMinutes(1)
            };
            var settings = new MetricsReportingDatadogOptions
            {
                Datadog = new DatadogOptions
                {
                    BaseUri = new Uri("http://localhost"),
                    ApiKey  = "123"
                },
                HttpPolicy = policy
            };
            var hostedMetricsClient = DatadogReporterBuilder.CreateClient(settings, policy, httpMessageHandlerMock.Object);

            // Act
            foreach (var attempt in Enumerable.Range(0, 10))
            {
                await hostedMetricsClient.WriteAsync(Payload, CancellationToken.None);

                // ReSharper disable ConvertIfStatementToConditionalTernaryExpression
                if (attempt <= policy.FailuresBeforeBackoff)
                {
                    // ReSharper restore ConvertIfStatementToConditionalTernaryExpression
                    // Assert
                    httpMessageHandlerMock.Protected().Verify <Task <HttpResponseMessage> >(
                        "SendAsync",
                        Times.AtLeastOnce(),
                        ItExpr.IsAny <HttpRequestMessage>(),
                        ItExpr.IsAny <CancellationToken>());
                }
                else
                {
                    // Assert
                    httpMessageHandlerMock.Protected().Verify <Task <HttpResponseMessage> >(
                        "SendAsync",
                        Times.AtMost(6), // TODO: Starting failing when running all tests with 2.0.0 upgrade, should be 3
                        ItExpr.IsAny <HttpRequestMessage>(),
                        ItExpr.IsAny <CancellationToken>());
                }
            }
        }