public void CannotParseRetryAfterWritesToEventSource()
            {
                const string unparsableDate = "no one can parse me! :)";

                var transmitter = new StubTransmitter();
                var policy      = new ThrottlingTransmissionPolicy();

                policy.Initialize(transmitter);

                using (var listener = new TestEventListener())
                {
                    const long AllKeyword = -1;
                    listener.EnableEvents(TelemetryChannelEventSource.Log, EventLevel.LogAlways, (EventKeywords)AllKeyword);

                    transmitter.OnTransmissionSent(
                        new TransmissionProcessedEventArgs(
                            new StubTransmission(), null, new HttpWebResponseWrapper()
                    {
                        StatusCode       = ResponseStatusCodes.ResponseCodeTooManyRequests,
                        RetryAfterHeader = unparsableDate
                    })
                        );
                    EventWrittenEventArgs trace = listener.Messages.First(args => args.EventId == 24);
                    Assert.AreEqual(unparsableDate, (string)trace.Payload[0]);
                }
            }
            public void RetryAfterOlderThanNow()
            {
                // An old date
                string retryAfterDateString = DateTime.Now.AddMinutes(-1).ToString("R", CultureInfo.InvariantCulture);

                var policyApplied = new AutoResetEvent(false);
                var transmitter   = new StubTransmitter();

                transmitter.OnApplyPolicies = () =>
                {
                    policyApplied.Set();
                };

                var policy = new ThrottlingTransmissionPolicy();

                policy.Initialize(transmitter);

                transmitter.OnTransmissionSent(
                    new TransmissionProcessedEventArgs(
                        new StubTransmission(),
                        CreateThrottledResponse(ResponseCodeTooManyRequests, retryAfterDateString)));

                Assert.True(policyApplied.WaitOne(100));
                Assert.Null(policy.MaxSenderCapacity);
                Assert.Null(policy.MaxBufferCapacity);
                Assert.Null(policy.MaxStorageCapacity);
            }
            private void PositiveTest(int responseCode, int?expectedSenderCapacity, int?expectedBufferCapacity, int?expectedStorageCapacity, bool hasFlushTask)
            {
                const int RetryAfterSeconds          = 2;
                string    retryAfter                 = DateTime.Now.ToUniversalTime().AddSeconds(RetryAfterSeconds).ToString("R", CultureInfo.InvariantCulture);
                const int WaitForTheFirstApplyAsync  = 100;
                int       waitForTheSecondApplyAsync = (RetryAfterSeconds * 1000) /*to milliseconds*/ +
                                                       500 /**magic number to wait for other code before/after
                                                            * timer which calls 2nd ApplyAsync
                                                            **/;

                var policyApplied = new AutoResetEvent(false);
                var transmitter   = new StubTransmitter();

                transmitter.OnApplyPolicies = () =>
                {
                    policyApplied.Set();
                };

                var policy = new ThrottlingTransmissionPolicy();

                policy.Initialize(transmitter);

                string statusDescription = null;

                transmitter.OnTransmissionSent(
                    new TransmissionProcessedEventArgs(
                        new StubTransmission()
                {
                    IsFlushAsyncInProgress = hasFlushTask
                }, null, new HttpWebResponseWrapper()
                {
                    StatusCode        = responseCode,
                    StatusDescription = statusDescription,
                    RetryAfterHeader  = retryAfter
                }));

                Assert.IsTrue(policyApplied.WaitOne(WaitForTheFirstApplyAsync));

                Assert.AreEqual(expectedSenderCapacity, policy.MaxSenderCapacity);
                Assert.AreEqual(expectedBufferCapacity, policy.MaxBufferCapacity);
                Assert.AreEqual(expectedStorageCapacity, policy.MaxStorageCapacity);

                Assert.IsTrue(policyApplied.WaitOne(waitForTheSecondApplyAsync));

                // Check that it resets after retry-after interval
                Assert.IsNull(policy.MaxSenderCapacity);
                Assert.IsNull(policy.MaxBufferCapacity);
                Assert.IsNull(policy.MaxStorageCapacity);
            }
            public void AssertUnsupportedResponseCodeDoesntChangeCapacity()
            {
                var transmitter = new StubTransmitter();
                transmitter.OnApplyPolicies = () =>
                {
                    throw new Exception("Apply shouldn't be called because unsupported response code was passed");
                };

                var policy = new ThrottlingTransmissionPolicy();
                policy.Initialize(transmitter);

                transmitter.OnTransmissionSent(
                    new TransmissionProcessedEventArgs(
                        new StubTransmission(),
                    CreateThrottledResponse(ResponseCodeUnsupported, 1)));

                Assert.Null(policy.MaxSenderCapacity);
                Assert.Null(policy.MaxBufferCapacity);
                Assert.Null(policy.MaxStorageCapacity);
            }
            private void PositiveTest(int responseCode, int?expectedSenderCapacity, int?expectedBufferCapacity, int?expectedStorageCapacity)
            {
                const int RetryAfterSeconds          = 2;
                string    retryAfter                 = DateTime.Now.ToUniversalTime().AddSeconds(RetryAfterSeconds).ToString("R", CultureInfo.InvariantCulture);
                const int WaitForTheFirstApplyAsync  = 100;
                int       waitForTheSecondApplyAsync = (RetryAfterSeconds * 1000) /*to miliseconds*/ +
                                                       500 /**magic number to wait for other code before/after
                                                            * timer which calls 2nd ApplyAsync
                                                            **/;

                var policyApplied = new AutoResetEvent(false);
                var transmitter   = new StubTransmitter();

                transmitter.OnApplyPolicies = () =>
                {
                    policyApplied.Set();
                };

                var policy = new ThrottlingTransmissionPolicy();

                policy.Initialize(transmitter);

                transmitter.OnTransmissionSent(
                    new TransmissionProcessedEventArgs(
                        new StubTransmission(),
                        CreateThrottledResponse(responseCode, retryAfter)));

                Assert.True(policyApplied.WaitOne(WaitForTheFirstApplyAsync));

                Assert.Equal(expectedSenderCapacity, policy.MaxSenderCapacity);
                Assert.Equal(expectedBufferCapacity, policy.MaxBufferCapacity);
                Assert.Equal(expectedStorageCapacity, policy.MaxStorageCapacity);

                Assert.True(policyApplied.WaitOne(waitForTheSecondApplyAsync));

                // Check that it resets after retry-after interval
                Assert.Null(policy.MaxSenderCapacity);
                Assert.Null(policy.MaxBufferCapacity);
                Assert.Null(policy.MaxStorageCapacity);
            }
            public void AssertIfDateParseErrorCausesDefaultDelay()
            {
                var policyApplied = new AutoResetEvent(false);
                var transmitter = new StubTransmitter();
                transmitter.OnApplyPolicies = () =>
                {
                    policyApplied.Set();
                };

                var policy = new ThrottlingTransmissionPolicy();
                policy.Initialize(transmitter);

                transmitter.OnTransmissionSent(
                    new TransmissionProcessedEventArgs(
                        new StubTransmission(),
                    CreateThrottledResponse(ResponseCodeTooManyRequests, "no one can parse me! :)")));

                Assert.True(policyApplied.WaitOne(100));
                Assert.Null(policy.MaxSenderCapacity);
                Assert.Null(policy.MaxBufferCapacity);
                Assert.Null(policy.MaxStorageCapacity);
            }
            public void AssertUnsupportedResponseCodeDoesntChangeCapacity()
            {
                var transmitter = new StubTransmitter();

                transmitter.OnApplyPolicies = () =>
                {
                    throw new Exception("Apply shouldn't be called because unsupported response code was passed");
                };

                var policy = new ThrottlingTransmissionPolicy();

                policy.Initialize(transmitter);

                transmitter.OnTransmissionSent(
                    new TransmissionProcessedEventArgs(
                        new StubTransmission(),
                        CreateThrottledResponse(ResponseCodeUnsupported, 1)));

                Assert.Null(policy.MaxSenderCapacity);
                Assert.Null(policy.MaxBufferCapacity);
                Assert.Null(policy.MaxStorageCapacity);
            }
            public void AssertPaymentRequiredDoesntChangeCapacity()
            {
                var transmitter = new StubTransmitter();

                transmitter.OnApplyPolicies = () =>
                {
                    throw new Exception("Apply shouldn't be called because unsupported response code was passed");
                };

                var policy = new ThrottlingTransmissionPolicy();

                policy.Initialize(transmitter);

                transmitter.OnTransmissionSent(
                    new TransmissionProcessedEventArgs(
                        new StubTransmission(), null, new HttpWebResponseWrapper()
                {
                    StatusCode = ResponseCodePaymentRequired
                }));

                Assert.IsNull(policy.MaxSenderCapacity);
                Assert.IsNull(policy.MaxBufferCapacity);
                Assert.IsNull(policy.MaxStorageCapacity);
            }
            public void AssertIfDateParseErrorCausesDefaultDelay()
            {
                var policyApplied = new AutoResetEvent(false);
                var transmitter   = new StubTransmitter();

                transmitter.OnApplyPolicies = () =>
                {
                    policyApplied.Set();
                };

                var policy = new ThrottlingTransmissionPolicy();

                policy.Initialize(transmitter);

                transmitter.OnTransmissionSent(
                    new TransmissionProcessedEventArgs(
                        new StubTransmission(),
                        CreateThrottledResponse(ResponseCodeTooManyRequests, "no one can parse me! :)")));

                Assert.True(policyApplied.WaitOne(100));
                Assert.Null(policy.MaxSenderCapacity);
                Assert.Null(policy.MaxBufferCapacity);
                Assert.Null(policy.MaxStorageCapacity);
            }
            public void CannotParseRetryAfterWritesToEventSource()
            {
                const string UnparsableDate = "no one can parse me! :)";

                var transmitter = new StubTransmitter();
                var policy = new ThrottlingTransmissionPolicy();
                policy.Initialize(transmitter);

                using (var listener = new TestEventListener())
                {
                    const long AllKeyword = -1;
                    listener.EnableEvents(TelemetryChannelEventSource.Log, EventLevel.LogAlways, (EventKeywords)AllKeyword);

                    transmitter.OnTransmissionSent(
                        new TransmissionProcessedEventArgs(
                            new StubTransmission(),
                        CreateThrottledResponse(ResponseCodeTooManyRequests, UnparsableDate)));

                    EventWrittenEventArgs trace = listener.Messages.First(args => args.EventId == 24);
                    Assert.Equal(UnparsableDate, (string)trace.Payload[0]);
                }
            }
            private void PositiveTest(int responseCode, int? expectedSenderCapacity, int? expectedBufferCapacity, int? expectedStorageCapacity)
            {
                const int RetryAfterSeconds = 2;
                string retryAfter = DateTime.Now.ToUniversalTime().AddSeconds(RetryAfterSeconds).ToString("R", CultureInfo.InvariantCulture);
                const int WaitForTheFirstApplyAsync = 100;
                int waitForTheSecondApplyAsync = (RetryAfterSeconds * 1000) /*to miliseconds*/ +
                    500 /**magic number to wait for other code before/after 
                         * timer which calls 2nd ApplyAsync
                         **/;

                var policyApplied = new AutoResetEvent(false);
                var transmitter = new StubTransmitter();
                transmitter.OnApplyPolicies = () =>
                {
                    policyApplied.Set();
                };

                var policy = new ThrottlingTransmissionPolicy();
                policy.Initialize(transmitter);

                transmitter.OnTransmissionSent(
                    new TransmissionProcessedEventArgs(
                        new StubTransmission(),
                    CreateThrottledResponse(responseCode, retryAfter)));

                Assert.True(policyApplied.WaitOne(WaitForTheFirstApplyAsync));
                
                Assert.Equal(expectedSenderCapacity, policy.MaxSenderCapacity);
                Assert.Equal(expectedBufferCapacity, policy.MaxBufferCapacity);
                Assert.Equal(expectedStorageCapacity, policy.MaxStorageCapacity);

                Assert.True(policyApplied.WaitOne(waitForTheSecondApplyAsync));

                // Check that it resets after retry-after interval
                Assert.Null(policy.MaxSenderCapacity);
                Assert.Null(policy.MaxBufferCapacity);
                Assert.Null(policy.MaxStorageCapacity);
            }
            public void RetryAfterOlderThanNow()
            {
                // An old date
                string retryAfterDateString = DateTime.Now.AddMinutes(-1).ToString("R", CultureInfo.InvariantCulture);

                var policyApplied = new AutoResetEvent(false);
                var transmitter = new StubTransmitter();
                transmitter.OnApplyPolicies = () =>
                {
                    policyApplied.Set();
                };

                var policy = new ThrottlingTransmissionPolicy();
                policy.Initialize(transmitter);

                transmitter.OnTransmissionSent(
                    new TransmissionProcessedEventArgs(
                        new StubTransmission(),
                    CreateThrottledResponse(ResponseCodeTooManyRequests, retryAfterDateString)));

                Assert.True(policyApplied.WaitOne(100));
                Assert.Null(policy.MaxSenderCapacity);
                Assert.Null(policy.MaxBufferCapacity);
                Assert.Null(policy.MaxStorageCapacity);
            }