Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        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();
            }
        }
Exemplo n.º 3
0
        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);
            }
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 10
0
        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();
            }
        }