public void CatchesAndLogsSynchronousExceptionsThrownByTransmitterWhenPausingTransmission() { var policy = new ErrorHandlingTransmissionPolicy(); var exception = CreateException(statusCode: 408); var transmitter = new StubTransmitter { OnApplyPolicies = () => { throw exception; } }; CatchesAndLogsExceptionThrownByTransmitter(policy, transmitter, exception); }
public void IfIndexMoreThanNumberOfItemsInTransmissionIgnoreError() { IList<Transmission> enqueuedTransmissions = new List<Transmission>(); var transmitter = new StubTransmitter { OnEnqueue = t => { enqueuedTransmissions.Add(t); } }; var policy = new PartialSuccessTransmissionPolicy(); policy.Initialize(transmitter); var items = new List<ITelemetry> { new EventTelemetry() }; Transmission transmission = new Transmission(new Uri("http://uri"), items, "type", "encoding"); // Index is 0-based string response = this.GetBackendResponse( itemsReceived: 2, itemsAccepted: 1, errorCodes: new[] { "408" }, indexStartWith: 1); var wrapper = new HttpWebResponseWrapper { StatusCode = 206, Content = response }; transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(transmission, null, wrapper)); Assert.Equal(0, policy.ConsecutiveErrors); Assert.Equal(0, enqueuedTransmissions.Count); }
public void DoesNotSendTransmissionForUnsupportedCodes() { IList<Transmission> enqueuedTransmissions = new List<Transmission>(); var transmitter = new StubTransmitter { OnEnqueue = t => { enqueuedTransmissions.Add(t); } }; var policy = new PartialSuccessTransmissionPolicy(); policy.Initialize(transmitter); var items = new List<ITelemetry> { new EventTelemetry(), new EventTelemetry() }; Transmission transmission = new Transmission(new Uri("http://uri"), items, "type", "encoding"); string response = this.GetBackendResponse( itemsReceived: 50, itemsAccepted: 45, errorCodes: new[] { "400", "402", "502", "409", "417" }); var wrapper = new HttpWebResponseWrapper { StatusCode = 206, Content = response }; transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(transmission, null, wrapper)); Assert.Equal(0, policy.ConsecutiveErrors); Assert.Equal(0, enqueuedTransmissions.Count); }
public void InitializeStoresTransmitterForUseByChildClasses() { var transmitter = new StubTransmitter(); var policy = new TestableTransmissionPolicy(); policy.Initialize(transmitter); Assert.Same(transmitter, policy.Transmitter); }
public void StopsTransmissionSendingAndBuffering() { var transmitter = new StubTransmitter(); var applicationLifecycle = new StubApplicationLifecycle(); var policy = new ApplicationLifecycleTransmissionPolicy(applicationLifecycle); policy.Initialize(transmitter); applicationLifecycle.OnStopping(ApplicationStoppingEventArgs.Empty); Assert.Equal(0, policy.MaxSenderCapacity); Assert.Equal(0, policy.MaxBufferCapacity); }
public void CatchesAndLogsSynchronousExceptionsThrownByTransmitterWhenResumingTransmission() { var policy = new TestableErrorHandlingTransmissionPolicy { BackOffTime = TimeSpan.FromMilliseconds(1) }; var exception = CreateException(statusCode: 408); var transmitter = new StubTransmitter(); transmitter.OnApplyPolicies = () => { if (policy.MaxSenderCapacity == null) { throw exception; } }; CatchesAndLogsExceptionThrownByTransmitter(policy, transmitter, exception); }
public void SerializesTelemetryOnSameThreadBecauseItAssumesItIsAlreadyOnThreadPool() { int serializationThreadId = -1; var transmitter = new StubTransmitter(); transmitter.OnEnqueue = t => { serializationThreadId = Thread.CurrentThread.ManagedThreadId; }; var serializer = new TelemetrySerializer(transmitter); serializer.Serialize(new[] { new StubTelemetry() }); Assert.Equal(serializationThreadId, Thread.CurrentThread.ManagedThreadId); }
public void ApplyInvokesApplyPoliciesAsyncOfTransmitter() { bool policiesApplied = false; var transmitter = new StubTransmitter { OnApplyPolicies = () => { policiesApplied = true; } }; var policy = new StubTransmissionPolicy(); policy.Initialize(transmitter); policy.Apply(); Assert.True(policiesApplied); }
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.Null(enqueuedTransmission); Assert.Equal(0, policy.ConsecutiveErrors); }
public void StopsTransmissionSendingWhenTransmissionTimesOut() { var policyApplied = new AutoResetEvent(false); var transmitter = new StubTransmitter(); transmitter.OnApplyPolicies = () => { policyApplied.Set(); }; var policy = new TestableErrorHandlingTransmissionPolicy(); policy.Initialize(transmitter); policy.BackOffTime = TimeSpan.FromSeconds(10); transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(new StubTransmission(), CreateException(statusCode: 408))); Assert.True(policyApplied.WaitOne(100)); Assert.Equal(0, policy.MaxSenderCapacity); }
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 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); }
private static void CatchesAndLogsExceptionThrownByTransmitter(ErrorHandlingTransmissionPolicy policy, StubTransmitter transmitter, Exception exception) { policy.Initialize(transmitter); using (var listener = new TestEventListener()) { const long AllKeywords = -1; listener.EnableEvents(TelemetryChannelEventSource.Log, EventLevel.Warning, (EventKeywords)AllKeywords); transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(new StubTransmission(), CreateException(statusCode: 408))); EventWrittenEventArgs error = listener.Messages.First(args => args.EventId == 23); Assert.Contains(exception.Message, (string)error.Payload[1], StringComparison.Ordinal); } }
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); }
public void AsksTransmitterToApplyPoliciesWhenNetworkAvailabilityChanges() { bool policiesApplied = false; var transmitter = new StubTransmitter(); transmitter.OnApplyPolicies = () => { policiesApplied = true; }; var network = new StubNetwork(); var policy = new NetworkAvailabilityTransmissionPolicy(network); policy.Initialize(transmitter); network.OnStatusChanged(EventArgs.Empty); Assert.True(policiesApplied); }
public void IfResponseIsBadJsonWeDoNotIncreaseErrorCount() { IList<Transmission> enqueuedTransmissions = new List<Transmission>(); var transmitter = new StubTransmitter { OnEnqueue = t => { enqueuedTransmissions.Add(t); } }; var policy = new PartialSuccessTransmissionPolicy(); policy.Initialize(transmitter); var items = new List<ITelemetry> { new EventTelemetry(), new EventTelemetry() }; Transmission transmission = new Transmission(new Uri("http://uri"), items, "type", "encoding"); string response = "[,]"; var wrapper = new HttpWebResponseWrapper { StatusCode = 206, Content = response }; transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(transmission, null, wrapper)); Assert.Equal(0, policy.ConsecutiveErrors); Assert.Equal(0, enqueuedTransmissions.Count); }
public void NewTransmissionCreatedByIndexesFromResponse() { IList<Transmission> enqueuedTransmissions = new List<Transmission>(); var transmitter = new StubTransmitter { OnEnqueue = t => { enqueuedTransmissions.Add(t); } }; var policy = new PartialSuccessTransmissionPolicy(); policy.Initialize(transmitter); var items = new List<ITelemetry> { new EventTelemetry("1"), new EventTelemetry("2"), new EventTelemetry("3"), }; Transmission transmission = new Transmission(new Uri("http://uri"), items, "type", "encoding"); string response = this.GetBackendResponse( itemsReceived: 3, itemsAccepted: 1, errorCodes: new[] { "439", "439" }); var wrapper = new HttpWebResponseWrapper { StatusCode = 206, Content = response }; transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(transmission, null, wrapper)); string[] newItems = JsonSerializer .Deserialize(enqueuedTransmissions[0].Content) .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); Assert.Equal(2, newItems.Length); Assert.True(newItems[0].Contains("\"name\":\"1\"")); Assert.True(newItems[1].Contains("\"name\":\"2\"")); }
public void IfItemIsRejectedOnlyThisItemIsUploadedBack() { IList<Transmission> enqueuedTransmissions = new List<Transmission>(); var transmitter = new StubTransmitter { OnEnqueue = t => { enqueuedTransmissions.Add(t); } }; var policy = new PartialSuccessTransmissionPolicy(); policy.Initialize(transmitter); var items = new List<ITelemetry> { new EventTelemetry(), new EventTelemetry() }; Transmission transmission = new Transmission(new Uri("http://uri"), items, "type", "encoding"); string response = this.GetBackendResponse( itemsReceived: 2, itemsAccepted: 1, errorCodes: new[] { "429" }); var wrapper = new HttpWebResponseWrapper { StatusCode = 206, Content = response }; transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(transmission, null, wrapper)); Assert.Equal(1, enqueuedTransmissions.Count); }
public void EnqueuesTransmissionWithExpectedProperties() { Transmission transmission = null; var transmitter = new StubTransmitter(); transmitter.OnEnqueue = t => { transmission = t; }; var serializer = new TelemetrySerializer(transmitter) { EndpointAddress = new Uri("http://expected.uri") }; serializer.Serialize(new[] { new StubTelemetry() }); Assert.Equal(serializer.EndpointAddress, transmission.EndpointAddress); Assert.Equal("application/x-json-stream", transmission.ContentType); Assert.Equal("gzip", transmission.ContentEncoding); Assert.Equal(string.Empty, Unzip(transmission.Content)); }
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.Same(failedTransmission, enqueuedTransmission); }
public void DoesNotContinueAsyncOperationsOnCapturedSynchronizationContextToImprovePerformance() { var transmitter = new StubTransmitter() { OnEnqueue = transmission => TaskEx.Run(() => { }) }; var serializer = new TelemetrySerializer(transmitter); bool postedBack = false; using (var context = new StubSynchronizationContext()) { context.OnPost = (callback, state) => { postedBack = true; callback(state); }; serializer.Serialize(new[] { new StubTelemetry() }); } Assert.False(postedBack); }
public void IfNumberOfRecievedItemsEqualsToNumberOfAcceptedErrorsListIsIgnored() { var transmitter = new StubTransmitter(); var policy = new PartialSuccessTransmissionPolicy(); policy.Initialize(transmitter); var items = new List<ITelemetry> { new EventTelemetry(), new EventTelemetry() }; Transmission transmission = new Transmission(new Uri("http://uri"), items, "type", "encoding"); string response = this.GetBackendResponse( itemsReceived: 2, itemsAccepted: 2, errorCodes: new[] { "408", "408" }); var wrapper = new HttpWebResponseWrapper { StatusCode = 206, Content = response }; transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(transmission, null, wrapper)); Assert.Equal(0, policy.ConsecutiveErrors); }
public void AppliesTransmissionPoliciesToBeginSendingStoredTelemetry() { var transmissionPoliciesApplied = new ManualResetEvent(false); var transmitter = new StubTransmitter(); transmitter.OnApplyPolicies = () => { transmissionPoliciesApplied.Set(); }; var channel = new ServerTelemetryChannel { Transmitter = transmitter }; channel.Initialize(TelemetryConfiguration.CreateDefault()); var initializedConfiguration = new TelemetryConfiguration(); channel.Initialize(initializedConfiguration); Assert.True(transmissionPoliciesApplied.WaitOne(1000)); }
public void RetriesFailedTransmissionInfinitely() { Transmission enqueuedTransmission = null; var transmitter = new StubTransmitter(); transmitter.OnEnqueue = transmission => { enqueuedTransmission = transmission; }; var policy = new TestableErrorHandlingTransmissionPolicy(); policy.BackOffTime = TimeSpan.FromMilliseconds(10); 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.Same(failedTransmission, enqueuedTransmission); }
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]); } }
public void KeepsTransmissionSenderPausedWhenAdditionalTransmissionsFail() { var transmitter = new StubTransmitter(); var policy = new TestableErrorHandlingTransmissionPolicy(); policy.Initialize(transmitter); policy.BackOffTime = TimeSpan.FromMilliseconds(10); transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(new StubTransmission(), CreateException(statusCode: 408))); policy.BackOffTime = TimeSpan.FromMilliseconds(50); transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(new StubTransmission(), CreateException(statusCode: 408))); Thread.Sleep(TimeSpan.FromMilliseconds(30)); Assert.Equal(0, policy.MaxSenderCapacity); }
public void InitializeCallsTransmitterInitialize() { var transmitterInitialized = new ManualResetEvent(false); var transmitter = new StubTransmitter(); transmitter.OnInitialize = () => { transmitterInitialized.Set(); }; var channel = new ServerTelemetryChannel { Transmitter = transmitter }; var initializedConfiguration = new TelemetryConfiguration(); channel.Initialize(initializedConfiguration); Assert.True(transmitterInitialized.WaitOne(1000)); }
public void IfMultipleItemsAreRejectedNumberOfErrorsIsIncreasedByOne() { // Number of errors determine backoff timeout. // When we get several bad items in one batch we want to increase errors by 1 only since it is one attempt to access Breeze var transmitter = new StubTransmitter(); var policy = new PartialSuccessTransmissionPolicy(); policy.Initialize(transmitter); var items = new List<ITelemetry> { new EventTelemetry(), new EventTelemetry() }; Transmission transmission = new Transmission(new Uri("http://uri"), items, "type", "encoding"); string response = this.GetBackendResponse( itemsReceived: 100, itemsAccepted: 95, errorCodes: new[] { "500", "500", "503", "503", "429" }); var wrapper = new HttpWebResponseWrapper { StatusCode = 206, Content = response }; transmitter.OnTransmissionSent(new TransmissionProcessedEventArgs(transmission, null, wrapper)); Assert.Equal(1, policy.ConsecutiveErrors); }