public async Task StoresTransmissionWhenBufferIsFull()
            {
                Transmission storedTransmission = null;
                var          storage            = new StubTransmissionStorage
                {
                    OnEnqueue = transmission =>
                    {
                        if (transmission != null)
                        {
                            storedTransmission = transmission;
                            transmission.IsFlushAsyncInProgress = true;
                            return(true);
                        }

                        return(false);
                    }
                };


                var sender = new StubTransmissionSender {
                    OnEnqueue = t => false
                };
                var buffer = new StubTransmissionBuffer {
                    OnEnqueue = t => false
                };
                Transmitter transmitter = CreateTransmitter(sender: sender, buffer: buffer, storage: storage);

                var enqueuedTransmission = new StubTransmission();
                var result = await transmitter.FlushAsync(enqueuedTransmission, default);

                Assert.AreSame(enqueuedTransmission, storedTransmission);
                Assert.IsTrue(result);
            }
            public void IsRaisedWhenTransmissionReturnsPartialSuccessResult()
            {
                var sender = new TransmissionSender();

                var    eventIsRaised = new ManualResetEventSlim();
                object eventSender   = null;
                TransmissionProcessedEventArgs eventArgs = null;

                sender.TransmissionSent += (s, a) =>
                {
                    eventSender = s;
                    eventArgs   = a;
                    eventIsRaised.Set();
                };

                var          wrapper      = new HttpWebResponseWrapper();
                Transmission transmission = new StubTransmission {
                    OnSend = () => wrapper
                };

                sender.Enqueue(() => transmission);

                Assert.IsTrue(eventIsRaised.Wait(50));
                Assert.AreSame(sender, eventSender);
                Assert.AreSame(transmission, eventArgs.Transmission);
                Assert.AreSame(wrapper, eventArgs.Response);
            }
            public void SavesTransmissionToTheNewlyCreatedFile()
            {
                string     writtenContents = null;
                StubStream fileStream      = new StubStream();

                fileStream.OnDispose = disposing =>
                {
                    writtenContents = Encoding.UTF8.GetString(fileStream.ToArray());
                };

                var file = new StubPlatformFile {
                    OnOpen = () => fileStream
                };
                var folder = new StubPlatformFolder {
                    OnCreateFile = fileName => file
                };
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage();

                storage.Initialize(provider);

                byte[] contents     = Encoding.UTF8.GetBytes(Path.GetRandomFileName());
                var    transmission = new StubTransmission(contents);

                storage.Enqueue(() => transmission);

                string encodedContent = writtenContents.Split(Environment.NewLine.ToCharArray()).Last();

                AssertEx.AreEqual(contents, Convert.FromBase64String(encodedContent));
            }
示例#4
0
            public void RetriesFailedTransmissionInfinitely()
            {
                Transmission enqueuedTransmission = null;

                var transmitter = new StubTransmitter(new TestableBackoffLogicManager(TimeSpan.FromMilliseconds(10)));

                transmitter.OnEnqueue = transmission =>
                {
                    enqueuedTransmission = transmission;
                };

                var policy = new ErrorHandlingTransmissionPolicy();

                policy.Initialize(transmitter);
                var failedTransmission = new StubTransmission();

                transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, new Exception("Error"), new HttpWebResponseWrapper()
                {
                    StatusCode = ResponseStatusCodes.InternalServerError
                }));
                transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, new Exception("Error"), new HttpWebResponseWrapper()
                {
                    StatusCode = ResponseStatusCodes.InternalServerError
                }));
                transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, new Exception("Error"), new HttpWebResponseWrapper()
                {
                    StatusCode = ResponseStatusCodes.InternalServerError
                }));
                Assert.AreSame(failedTransmission, enqueuedTransmission);
            }
示例#5
0
            public void LogsDataLossEventsWhenExceptionisNull()
            {
                using (var listener = new TestEventListener())
                {
                    // Arrange:
                    const long AllKeywords = -1;
                    listener.EnableEvents(TelemetryChannelEventSource.Log, EventLevel.LogAlways, (EventKeywords)AllKeywords);

                    Transmission enqueuedTransmission = null;
                    var          transmitter          = new StubTransmitter(new BackoffLogicManager(TimeSpan.FromMilliseconds(10)))
                    {
                        OnEnqueue = transmission => { enqueuedTransmission = transmission; }
                    };

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

                    var failedTransmission = new StubTransmission();

                    // Act:
                    transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, null, null));

                    // Assert:
                    var traces = listener.Messages.Where(item => item.Level == EventLevel.Error).ToList();
                    Assert.AreEqual(1, traces.Count);
                    Assert.AreEqual(69, traces[0].EventId); // failed to send
                    Assert.AreEqual("Unknown Exception Message", traces[0].Payload[1]);
                }
            }
示例#6
0
            public void LogsWarningWhenDataLossIntentional()
            {
                // ErrorHandlingTransmissionPolicy does retry only for a whitelisted set of status codes. For
                // others telemetry is dropped. This test is to validate that those are logged.
                using (var listener = new TestEventListener())
                {
                    // Arrange:
                    const long AllKeywords = -1;
                    listener.EnableEvents(TelemetryChannelEventSource.Log, EventLevel.LogAlways, (EventKeywords)AllKeywords);

                    Transmission enqueuedTransmission = null;
                    var          transmitter          = new StubTransmitter(new BackoffLogicManager(TimeSpan.FromMilliseconds(10)))
                    {
                        OnEnqueue = transmission => { enqueuedTransmission = transmission; }
                    };

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

                    var failedTransmission = new StubTransmission();

                    // Act:
                    var res = new HttpWebResponseWrapper();
                    res.StatusCode = 8989;  // some status code not whitelisted for retry.
                    transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, null, res));

                    // Assert:
                    var traces = listener.Messages.Where(item => item.Level == EventLevel.Warning).ToList();
                    Assert.AreEqual(1, traces.Count);
                    Assert.AreEqual(71, traces[0].EventId); // failed to send
                    Assert.AreEqual("8989", traces[0].Payload[1]);
                }
            }
示例#7
0
            public void NoWarningLogsWhenResponseIsPartiallSuccess()
            {
                // ErrorHandlingTransmissionPolicy does retry only for a whitelisted set of status codes. For
                // partial success (206) status, there should be no warnings as this is handled by separate
                // Retry policy. This test is to validate that no warning is logged.
                using (var listener = new TestEventListener())
                {
                    // Arrange:
                    const long AllKeywords = -1;
                    listener.EnableEvents(TelemetryChannelEventSource.Log, EventLevel.LogAlways, (EventKeywords)AllKeywords);

                    Transmission enqueuedTransmission = null;
                    var          transmitter          = new StubTransmitter(new BackoffLogicManager(TimeSpan.FromMilliseconds(10)))
                    {
                        OnEnqueue = transmission => { enqueuedTransmission = transmission; }
                    };

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

                    var failedTransmission = new StubTransmission();

                    // Act:
                    var res = new HttpWebResponseWrapper();
                    res.StatusCode = 206;  // Sucess
                    transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, null, res));

                    // Assert:
                    var traces = listener.Messages.Where(item => item.Level == EventLevel.Warning).ToList();
                    Assert.AreEqual(0, traces.Count);
                }
            }
示例#8
0
            public void LogsAdditionalTracesIfResponseIsProvided()
            {
                using (var listener = new TestEventListener())
                {
                    // Arrange:
                    const long AllKeywords = -1;
                    listener.EnableEvents(TelemetryChannelEventSource.Log, EventLevel.LogAlways, (EventKeywords)AllKeywords);

                    Transmission enqueuedTransmission = null;
                    var          transmitter          = new StubTransmitter(new BackoffLogicManager(TimeSpan.FromMilliseconds(10)))
                    {
                        OnEnqueue = transmission => { enqueuedTransmission = transmission; }
                    };

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

                    var failedTransmission = new StubTransmission();
                    var response           = new HttpWebResponseWrapper {
                        Content = BackendResponseHelper.CreateBackendResponse(2, 1, new[] { "123" })
                    };

                    // Act:
                    transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, CreateException(statusCode: 408), response));

                    // Assert:
                    var traces = listener.Messages.Where(item => item.Level == EventLevel.Warning).ToList();
                    Assert.AreEqual(2, traces.Count);
                    Assert.AreEqual(23, traces[0].EventId); // failed to send
                    Assert.AreEqual(7, traces[1].EventId);  // additional trace
                    Assert.AreEqual("Explanation", traces[1].Payload[0]);
                }
            }
            public void StoresTransmissionWhenBufferIsFull()
            {
                Transmission storedTransmission = null;
                var          storage            = new StubTransmissionStorage
                {
                    OnEnqueue = transmission =>
                    {
                        storedTransmission = transmission;
                        return(false);
                    }
                };

                var sender = new StubTransmissionSender {
                    OnEnqueue = t => false
                };
                var buffer = new StubTransmissionBuffer {
                    OnEnqueue = t => false
                };
                Transmitter transmitter = CreateTransmitter(sender: sender, buffer: buffer, storage: storage);

                var enqueuedTransmission = new StubTransmission();

                transmitter.Enqueue(enqueuedTransmission);

                Assert.Same(enqueuedTransmission, storedTransmission);
            }
            public void MovesTransmissionsFromBufferToSenderWhenSenderCapacityIsGreaterThanZero()
            {
                var bufferedTransmission = new StubTransmission();
                var buffer = new TransmissionBuffer();

                buffer.Enqueue(() => bufferedTransmission);

                Transmission sentTransmission = null;
                var          sender           = new StubTransmissionSender();

                sender.OnEnqueue = getTransmission =>
                {
                    sentTransmission = getTransmission();
                    return(false);
                };

                var policy = new StubTransmissionPolicy {
                    MaxSenderCapacity = 0
                };

                Transmitter transmitter = CreateTransmitter(sender: sender, buffer: buffer, policies: new[] { policy });

                policy.MaxSenderCapacity = 1;
                policy.Apply();

                Assert.Same(bufferedTransmission, sentTransmission);
            }
            public void IsRaisedWhenTransmissionThrownExceptionWhileSending()
            {
                var sender = new TransmissionSender();

                var    eventIsRaised = new ManualResetEventSlim();
                object eventSender   = null;
                TransmissionProcessedEventArgs eventArgs = null;

                sender.TransmissionSent += (s, a) =>
                {
                    eventSender = s;
                    eventArgs   = a;
                    eventIsRaised.Set();
                };

                var          exception    = new TimeoutException();
                Transmission transmission = new StubTransmission {
                    OnSend = () => { throw exception; }
                };

                sender.Enqueue(() => transmission);

                Assert.IsTrue(eventIsRaised.Wait(5000));
                Assert.AreSame(sender, eventSender);
                Assert.AreSame(transmission, eventArgs.Transmission);
                Assert.AreSame(exception, eventArgs.Exception);
            }
        public void TransmissionReturnsValueSuppliedByConstructor()
        {
            Transmission transmission = new StubTransmission();
            var          args         = new TransmissionProcessedEventArgs(transmission);

            Assert.Same(transmission, args.Transmission);
        }
            public void ReflectsContentLengthOfTransmissionsAddedByEnqueueAsync()
            {
                Transmission transmission = new StubTransmission(new byte[42]);
                var          buffer       = new TransmissionBuffer();

                buffer.Enqueue(() => transmission);

                Assert.Equal(transmission.Content.Length, buffer.Size);
            }
            public void StartsSendingTransmissionAndReturnsImmediatelyToUnblockCallingThread()
            {
                var transmissionCanFinishSending = new ManualResetEventSlim();
                var transmission = new StubTransmission {
                    OnSend = () => { transmissionCanFinishSending.Wait(); return(null); }
                };
                var sender = new TransmissionSender();

                sender.Enqueue(() => transmission);

                transmissionCanFinishSending.Set();
            }
            public void DoesNotCountNullTransmissionsReturnedFromEmptyBufferAgainstMaxNumber()
            {
                var sender = new TransmissionSender {
                    Capacity = 1
                };

                sender.Enqueue(() => null);

                Transmission transmission2 = new StubTransmission();

                Assert.IsTrue(sender.Enqueue(() => transmission2));
            }
            public void DoesNotCountNullTransmissionsReturnedFromEmptyStorageAgainstMaxNumber()
            {
                var buffer = new TransmissionBuffer {
                    Capacity = 1
                };

                buffer.Enqueue(() => null);

                Transmission transmission2 = new StubTransmission();

                Assert.True(buffer.Enqueue(() => transmission2));
            }
            public void DoesNotCountRejectedTransmissionsAgainstMaxNumber()
            {
                var sender = new TransmissionSender {
                    Capacity = 0
                };
                Transmission transmission1 = new StubTransmission();

                sender.Enqueue(() => transmission1);

                sender.Capacity = 1;

                Transmission transmission2 = new StubTransmission();

                Assert.IsTrue(sender.Enqueue(() => transmission2));
            }
            public void ReturnsOldestEnquedTransmission()
            {
                var buffer = new TransmissionBuffer();

                Transmission transmission1 = new StubTransmission();

                buffer.Enqueue(() => transmission1);

                Transmission transmission2 = new StubTransmission();

                buffer.Enqueue(() => transmission2);

                Assert.Same(transmission1, buffer.Dequeue());
                Assert.Same(transmission2, buffer.Dequeue());
            }
            public void DoesNotCountTransmissionsSentWithExceptionsAgainstMaxNumber()
            {
                var sender = new TransmissionSender {
                    Capacity = 1
                };

                Transmission transmission1 = new StubTransmission {
                    OnSend = () => { throw new TimeoutException(); }
                };

                sender.Enqueue(() => transmission1);
                Thread.Sleep(10);

                Transmission transmission2     = new StubTransmission();
                bool         transmission2Sent = sender.Enqueue(() => transmission2);

                Assert.IsTrue(transmission2Sent);
            }
            public async Task FlushAsyncReturnsFalseWhenTransmissionIsNotSentOrStored()
            {
                var sender = new StubTransmissionSender {
                    OnEnqueue = t => false
                };
                var buffer = new StubTransmissionBuffer {
                    OnEnqueue = t => false
                };
                var storage = new StubTransmissionStorage {
                    OnEnqueue = t => false
                };
                Transmitter transmitter = CreateTransmitter(sender: sender, buffer: buffer, storage: storage);

                var enqueuedTransmission = new StubTransmission();
                var result = await transmitter.FlushAsync(enqueuedTransmission, default);

                Assert.IsFalse(result);
            }
            public void MovesTransmissionsFromStorageToSenderToAvoidWaitingUntilBufferIsFullBeforeSendingStarts()
            {
                var storedTransmission = new StubTransmission();
                var storage            = new StubTransmissionStorage();

                storage.Enqueue(() => storedTransmission);
                var buffer = new StubTransmissionBuffer();

                var sentTransmissions         = new List <Transmission>();
                StubTransmissionSender sender = CreateSender(sentTransmissions);

                sender.OnGetCapacity = () => 1;

                Transmitter transmitter = CreateTransmitter(sender, buffer, storage);

                transmitter.ApplyPolicies();

                Assert.Contains(storedTransmission, sentTransmissions);
            }
            public void IsRaisedWhenTransmissionIsThrottledLocallyWithByteArray()
            {
                var sender = new TransmissionSender();

                sender.ApplyThrottle = true;

                var eventIsRaised = new ManualResetEventSlim();
                var firedCount    = 0;
                var eventArgs     = new List <Implementation.TransmissionProcessedEventArgs>();

                sender.TransmissionSent += (s, a) =>
                {
                    firedCount++;
                    eventArgs.Add(a);
                    if (firedCount == 2)
                    {
                        eventIsRaised.Set();
                    }
                };

                var telemetryItems = new List <ITelemetry>();

                for (var i = 0; i < sender.ThrottleLimit + 10; i++)
                {
                    telemetryItems.Add(new DataContracts.EventTelemetry());
                }

                var          wrapper      = new HttpWebResponseWrapper();
                Transmission transmission = new StubTransmission(JsonSerializer.Serialize(telemetryItems, false))
                {
                    OnSend = () => wrapper
                };

                sender.Enqueue(() => transmission);

                Assert.IsTrue(eventIsRaised.Wait(50));
                Assert.AreEqual(2, firedCount);
                Assert.AreEqual(429, eventArgs[0].Response.StatusCode);
                Assert.AreEqual("Internally Throttled", eventArgs[0].Response.StatusDescription);
                Assert.AreSame(wrapper, eventArgs[1].Response);
                Assert.AreEqual(sender.ThrottleLimit, ((StubTransmission)eventArgs[0].Transmission).CountOfItems());
                Assert.AreEqual(10, ((StubTransmission)eventArgs[1].Transmission).CountOfItems());
            }
            public void PassesTransmissionToSenderAndReturnsTrue()
            {
                Transmission sentTransmission = null;
                var          sender           = new StubTransmissionSender
                {
                    OnEnqueue = getTransmission =>
                    {
                        sentTransmission = getTransmission();
                        return(sentTransmission != null);
                    },
                };

                Transmitter transmitter = CreateTransmitter(sender: sender);

                var transmission = new StubTransmission();

                transmitter.Enqueue(transmission);

                Assert.Same(transmission, sentTransmission);
            }
示例#24
0
            public void RetriesFailedTransmissionIfItsNumberOfAttemptsDidNotReachMaximum()
            {
                Transmission enqueuedTransmission = null;
                var          transmitter          = new StubTransmitter();

                transmitter.OnEnqueue = transmission =>
                {
                    enqueuedTransmission = transmission;
                };

                var policy = new ErrorHandlingTransmissionPolicy();

                policy.Initialize(transmitter);

                var failedTransmission = new StubTransmission();

                transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, CreateException(statusCode: 408)));

                Assert.AreSame(failedTransmission, enqueuedTransmission);
            }
            public async Task PassesTransmissionToSenderAndReturnsTrue()
            {
                Transmission sentTransmission = null;
                var          sender           = new StubTransmissionSender
                {
                    OnEnqueue = getTransmission =>
                    {
                        sentTransmission = getTransmission();
                        return(sentTransmission != null);
                    },
                };

                Transmitter transmitter = CreateTransmitter(sender: sender);

                var transmission = new StubTransmission();
                var result       = await transmitter.FlushAsync(transmission, default);

                Assert.AreSame(transmission, sentTransmission);
                Assert.IsTrue(result);
            }
            public void FlushAsyncTransmissionWithThrottle()
            {
                var sender = new TransmissionSender();

                sender.ApplyThrottle = true;

                var eventIsRaised = new ManualResetEventSlim();
                var firedCount    = 0;
                var eventArgs     = new List <Implementation.TransmissionProcessedEventArgs>();

                sender.TransmissionSent += (s, a) =>
                {
                    firedCount++;
                    eventArgs.Add(a);
                    if (firedCount == 2)
                    {
                        eventIsRaised.Set();
                    }
                };

                var telemetryItems = new List <ITelemetry>();

                for (var i = 0; i < sender.ThrottleLimit + 10; i++)
                {
                    telemetryItems.Add(new DataContracts.EventTelemetry());
                }

                var          wrapper      = new HttpWebResponseWrapper();
                Transmission transmission = new StubTransmission(telemetryItems)
                {
                    OnSend = () => wrapper
                };

                transmission.IsFlushAsyncInProgress = true;
                sender.Enqueue(() => transmission);

                Assert.IsTrue(eventIsRaised.Wait(50));
                // Both accepted and rejected transmission has flush task
                Assert.IsTrue(eventArgs[0].Transmission.IsFlushAsyncInProgress);
                Assert.IsTrue(eventArgs[1].Transmission.IsFlushAsyncInProgress);
            }
            public void DoesNotMoveTransmissionsFromStorageToSenderWhenBufferIsNotEmptyToPreserveQueueOrder()
            {
                var storedTransmission = new StubTransmission();
                var storage            = new StubTransmissionStorage();

                storage.Enqueue(() => storedTransmission);
                var buffer = new StubTransmissionBuffer {
                    OnGetSize = () => 1
                };

                var sentTransmissions         = new List <Transmission>();
                StubTransmissionSender sender = CreateSender(sentTransmissions);

                sender.OnGetCapacity = () => 1;

                Transmitter transmitter = CreateTransmitter(sender, buffer, storage);

                transmitter.ApplyPolicies();

                Assert.DoesNotContain(storedTransmission, sentTransmissions);
            }
示例#28
0
            public void DoesNotRetrySuccessfulTransmission()
            {
                Transmission enqueuedTransmission = null;
                var          transmitter          = new StubTransmitter();

                transmitter.OnEnqueue = transmission =>
                {
                    enqueuedTransmission = transmission;
                };

                var policy = new ErrorHandlingTransmissionPolicy();

                policy.Initialize(transmitter);

                var successfulTransmission = new StubTransmission();

                transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(successfulTransmission));

                Assert.IsNull(enqueuedTransmission);
                Assert.AreEqual(0, transmitter.BackoffLogicManager.ConsecutiveErrors);
            }
            public void MovesOldestTransmissionFromBufferToSender()
            {
                Transmission sentTransmission = null;
                var          sender           = new StubTransmissionSender();

                sender.OnEnqueue = getTransmission =>
                {
                    sentTransmission = getTransmission();
                    return(false);
                };

                Transmission bufferedTransmission = new StubTransmission();
                var          buffer = new TransmissionBuffer();

                buffer.Enqueue(() => bufferedTransmission);

                Transmitter transmitter = CreateTransmitter(sender: sender, buffer: buffer);

                sender.OnTransmissionSent(new TransmissionProcessedEventArgs(new StubTransmission()));

                Assert.Same(bufferedTransmission, sentTransmission);
            }
示例#30
0
            public void RetriesFailedTransmissionInfinitely()
            {
                Transmission enqueuedTransmission = null;

                var transmitter = new StubTransmitter(new TestableBackoffLogicManager(TimeSpan.FromMilliseconds(10)));

                transmitter.OnEnqueue = transmission =>
                {
                    enqueuedTransmission = transmission;
                };

                var policy = new ErrorHandlingTransmissionPolicy();

                policy.Initialize(transmitter);

                var failedTransmission = new StubTransmission();

                transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, CreateException(statusCode: 408)));
                transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, CreateException(statusCode: 408)));
                transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(failedTransmission, CreateException(statusCode: 408)));
                Assert.AreSame(failedTransmission, enqueuedTransmission);
            }