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)); }
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); }
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]); } }
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]); } }
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); } }
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); }
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); }
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); }
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); }