public void UpdateIfExistsTest(bool circuitBreakerRecordExists) { // Setup var lastCircuitOpenDate = DateTime.Now; var testCircuitBreaker = new CircuitBreakerDetails() { CircuitBreakerStatus = CircuitBreakerStatus.HalfOpen, HalfOpenRetryCount = 5, LastCircuitOpenDate = lastCircuitOpenDate }; if (circuitBreakerRecordExists) { testCircuitBreakerTable.Add(new CircuitBreaker()); } var result = repo.UpdateIfExistsAsync(testCircuitBreaker).Result; // Asserts result.Should().Be(circuitBreakerRecordExists); if (circuitBreakerRecordExists) { var insertedCircuitBreaker = testCircuitBreakerTable.FirstOrDefault(); insertedCircuitBreaker.CircuitBreakerStatus.Should().Be(testCircuitBreaker.CircuitBreakerStatus.ToString()); insertedCircuitBreaker.HalfOpenRetryCount.Should().Be(testCircuitBreaker.HalfOpenRetryCount); insertedCircuitBreaker.LastCircuitOpenDate.Should().Be(testCircuitBreaker.LastCircuitOpenDate); } }
public void UpdateCircuitBreakerAsyncTest(bool recordExists) { // Arrange SetupCalls(); var dummyCircuitBreakerDetails = new CircuitBreakerDetails() { CircuitBreakerStatus = CircuitBreakerStatus.Closed, HalfOpenRetryCount = 0, LastCircuitOpenDate = DateTime.Now }; A.CallTo(() => fakeCircuitBreakerCommandRepository.Add(A <CircuitBreakerDetails> ._)).DoesNothing(); A.CallTo(() => fakeCircuitBreakerCommandRepository.UpdateIfExistsAsync(A <CircuitBreakerDetails> ._)).Returns(recordExists); // Act var accountService = new AccountsService(fakeApplicationLogger, fakeConfiguration, fakeAccountQueryRepository, fakeAuditCommandRepository, fakeCircuitBreakerQueryRepository, fakeCircuitBreakerCommandRepository); var result = accountService.UpdateCircuitBreakerAsync(dummyCircuitBreakerDetails); // Assert if (recordExists) { A.CallTo(() => fakeCircuitBreakerCommandRepository.UpdateIfExistsAsync(A <CircuitBreakerDetails> ._)).MustHaveHappenedOnceExactly(); } else { A.CallTo(() => fakeCircuitBreakerCommandRepository.UpdateIfExistsAsync(A <CircuitBreakerDetails> ._)).MustHaveHappenedTwiceExactly(); } }
public void GetCircuitBreakerStatusAsyncDoesExistTest(CircuitBreakerStatus circuitBreakerStatus, int hoursInSate) { // Arrange SetupCalls(); var dummyCircuitBreakerDetails = new CircuitBreakerDetails() { CircuitBreakerStatus = circuitBreakerStatus, HalfOpenRetryCount = 2, LastCircuitOpenDate = DateTime.Now.AddHours(hoursInSate * -1) }; A.CallTo(() => fakeCircuitBreakerQueryRepository.GetBreakerDetails()).Returns(dummyCircuitBreakerDetails); A.CallTo(() => fakeCircuitBreakerCommandRepository.UpdateIfExistsAsync(A <CircuitBreakerDetails> ._)).Returns(true); // Act var accountService = new AccountsService(fakeApplicationLogger, fakeConfiguration, fakeAccountQueryRepository, fakeAuditCommandRepository, fakeCircuitBreakerQueryRepository, fakeCircuitBreakerCommandRepository); var result = accountService.GetCircuitBreakerStatusAsync().Result; // Assert if (circuitBreakerStatus == CircuitBreakerStatus.Open && hoursInSate > 24) { // if it was open and it been over 24 hours since then it gets reset A.CallTo(() => fakeCircuitBreakerCommandRepository.UpdateIfExistsAsync(A <CircuitBreakerDetails> ._)).MustHaveHappenedOnceExactly(); result.CircuitBreakerStatus.Should().Be(CircuitBreakerStatus.Closed); result.HalfOpenRetryCount.Should().Be(0); result.LastCircuitOpenDate.Should().BeCloseTo(DateTime.Now, 1000); } else { A.CallTo(() => fakeCircuitBreakerCommandRepository.UpdateIfExistsAsync(A <CircuitBreakerDetails> ._)).MustNotHaveHappened(); result.Should().BeEquivalentTo(dummyCircuitBreakerDetails); } }
public void HalfOpenCircuitBreakerAsyncTest(CircuitBreakerStatus circuitBreakerStatus) { // Arrange SetupCalls(); var dummyCircuitBreakerDetails = new CircuitBreakerDetails() { CircuitBreakerStatus = circuitBreakerStatus, HalfOpenRetryCount = 0, LastCircuitOpenDate = DateTime.Now }; A.CallTo(() => fakeCircuitBreakerQueryRepository.GetBreakerDetails()).Returns(dummyCircuitBreakerDetails); A.CallTo(() => fakeCircuitBreakerCommandRepository.UpdateIfExistsAsync(A <CircuitBreakerDetails> ._)).Returns(true); // Act var accountService = new AccountsService(fakeApplicationLogger, fakeConfiguration, fakeAccountQueryRepository, fakeAuditCommandRepository, fakeCircuitBreakerQueryRepository, fakeCircuitBreakerCommandRepository); var result = accountService.HalfOpenCircuitBreakerAsync(); // Assert A.CallTo(() => fakeCircuitBreakerCommandRepository.UpdateIfExistsAsync(A <CircuitBreakerDetails> ._)).MustHaveHappened(); dummyCircuitBreakerDetails.CircuitBreakerStatus.Should().Be(CircuitBreakerStatus.HalfOpen); if (circuitBreakerStatus == CircuitBreakerStatus.HalfOpen) { dummyCircuitBreakerDetails.HalfOpenRetryCount.Should().Be(1); } }
public void Add(CircuitBreakerDetails entity) { CircuitBreaker circuitBreaker = new CircuitBreaker { CircuitBreakerStatus = entity.CircuitBreakerStatus.ToString(), HalfOpenRetryCount = entity.HalfOpenRetryCount, LastCircuitOpenDate = entity.LastCircuitOpenDate }; accountsContext.CircuitBreaker.Add(circuitBreaker); accountsContext.SaveChanges(); }
private CircuitBreakerDetails AddDefaultCircuitBreaker() { var initialCircuitBreaker = new CircuitBreakerDetails() { CircuitBreakerStatus = CircuitBreakerStatus.Closed, HalfOpenRetryCount = 0, LastCircuitOpenDate = DateTime.Now }; circuitBreakerCommandRepository.Add(initialCircuitBreaker); return(initialCircuitBreaker); }
public async Task UpdateCircuitBreakerAsync(CircuitBreakerDetails circuitBreakerDetails) { var updated = await circuitBreakerCommandRepository.UpdateIfExistsAsync(circuitBreakerDetails); if (!updated) { applicationLogger.Trace("Adding default circuit breaker record on update as one does not exist"); AddDefaultCircuitBreaker(); await circuitBreakerCommandRepository.UpdateIfExistsAsync(circuitBreakerDetails); } }
public async Task <bool> UpdateIfExistsAsync(CircuitBreakerDetails entity) { var circuitBreaker = accountsContext.CircuitBreaker.FirstOrDefault(); if (circuitBreaker != null) { circuitBreaker.CircuitBreakerStatus = entity.CircuitBreakerStatus.ToString(); circuitBreaker.LastCircuitOpenDate = entity.LastCircuitOpenDate; circuitBreaker.HalfOpenRetryCount = entity.HalfOpenRetryCount; await accountsContext.SaveChangesAsync(); return(true); } return(false); }
public void AddAuditTest() { // Setup var lastCircuitOpenDate = DateTime.Now; var testCircuitBreaker = new CircuitBreakerDetails() { CircuitBreakerStatus = CircuitBreakerStatus.HalfOpen, HalfOpenRetryCount = 5, LastCircuitOpenDate = lastCircuitOpenDate }; // Act repo.Add(testCircuitBreaker); // Asserts A.CallTo(() => fakeDbContext.CircuitBreaker.Add(A <CircuitBreaker> ._)).MustHaveHappened(); testCircuitBreakerTable.Count().Should().Be(1); var insertedCircuitBreaker = testCircuitBreakerTable.FirstOrDefault(); insertedCircuitBreaker.CircuitBreakerStatus.Should().Be(testCircuitBreaker.CircuitBreakerStatus.ToString()); insertedCircuitBreaker.HalfOpenRetryCount.Should().Be(testCircuitBreaker.HalfOpenRetryCount); insertedCircuitBreaker.LastCircuitOpenDate.Should().Be(testCircuitBreaker.LastCircuitOpenDate); }
public async Task ProcessEmailNotificationsAsyncTests( CircuitBreakerDetails circuitBreakerDetails, int batchAccountSize, SendNotificationResponse sendNotificationResponse, bool throwSendNotificationException = false, int halfOpenRetryMax = 5) { // Configure Calls A.CallTo(() => fakeAccountsService.GetCircuitBreakerStatusAsync()).Returns(circuitBreakerDetails); A.CallTo(() => fakeAccountsService.GetNextBatchOfEmailsAsync(A <int> ._)).Returns(GetAccountsToProcess(batchAccountSize)); if (throwSendNotificationException) { A.CallTo(() => fakeSendCitizenNotificationService.SendCitizenNotificationAsync(A <Account> ._)).Throws(() => new Exception(nameof(Exception), new Exception(nameof(Exception)))); } else { A.CallTo(() => fakeSendCitizenNotificationService.SendCitizenNotificationAsync(A <Account> ._)).Returns(sendNotificationResponse); } A.CallTo(() => fakeConfiguration.GetConfig <int>(A <string> ._)) .Returns(halfOpenRetryMax); //For this test the function call is not diasbled in the config. A.CallTo(() => fakeConfiguration.GetConfig <bool>(A <string> ._)).Returns(false); // Assign var emailProcessor = new EmailNotificationProcessor(fakeSendCitizenNotificationService, fakeApplicationLogger, fakeConfiguration, fakeAccountsService); // Act await emailProcessor.ProcessEmailNotificationsAsync(); // Assert A.CallTo(() => fakeAccountsService.GetCircuitBreakerStatusAsync()).MustHaveHappened(); if (circuitBreakerDetails.CircuitBreakerStatus != CircuitBreakerStatus.Open) { if (throwSendNotificationException) { A.CallTo(() => fakeAccountsService.InsertAuditAsync(A <AccountNotificationAudit> .That.Matches(audit => audit.NotificationProcessingStatus == NotificationProcessingStatus.Failed && !string.IsNullOrWhiteSpace(audit.Note)))) .MustHaveHappened(); A.CallTo(() => fakeAccountsService.HalfOpenCircuitBreakerAsync()).MustHaveHappened(); if (circuitBreakerDetails.HalfOpenRetryCount == halfOpenRetryMax) { A.CallTo(() => fakeAccountsService.SetBatchToCircuitGotBrokenAsync(A <IEnumerable <Account> > ._)).MustHaveHappened(); A.CallTo(() => fakeAccountsService.OpenCircuitBreakerAsync()).MustHaveHappened(); } } else { if (sendNotificationResponse.Success) { A.CallTo(() => fakeAccountsService.InsertAuditAsync(A <AccountNotificationAudit> ._)).MustHaveHappened(batchAccountSize, Times.Exactly); if (circuitBreakerDetails.CircuitBreakerStatus == CircuitBreakerStatus.HalfOpen) { A.CallTo(() => fakeAccountsService.CloseCircuitBreakerAsync()).MustHaveHappened(); } } else { if (sendNotificationResponse.RateLimitException) { A.CallTo(() => fakeAccountsService.OpenCircuitBreakerAsync()).MustHaveHappened(); A.CallTo(() => fakeAccountsService.SetBatchToCircuitGotBrokenAsync( A <IEnumerable <Account> > ._)) .MustHaveHappened(); A.CallTo(() => fakeApplicationLogger.Info(A <string> ._)).MustHaveHappened(); } else { A.CallTo(() => fakeAccountsService.InsertAuditAsync(A <AccountNotificationAudit> .That.Matches(audit => audit.NotificationProcessingStatus == NotificationProcessingStatus.Failed))) .MustHaveHappened(); } } } } else { A.CallTo(() => fakeAccountsService.GetNextBatchOfEmailsAsync(A <int> ._)).MustNotHaveHappened(); A.CallTo(() => fakeSendCitizenNotificationService.SendCitizenNotificationAsync(A <Account> ._)).MustNotHaveHappened(); } }