public void CallsOnErrorOnException() { // Arrange var mre = new ManualResetEventSlim(false); var onErrorCalled = false; var dbProviderFactory = new MockDbProviderFactory(); var dbBehavior = new Mock <IDbBehavior>(); dbBehavior.Setup(db => db.UpdateLoopRetryDelays).Returns(_defaultRetryDelays); dbBehavior.Setup(db => db.StartSqlDependencyListener()).Returns(false); dbProviderFactory.MockDataReader.Setup(r => r.Read()).Throws(new ApplicationException("test")); var operation = new ObservableDbOperation("test", "test", new TraceSource("test"), dbProviderFactory, dbBehavior.Object); operation.Faulted += _ => { onErrorCalled = true; mre.Set(); }; // Act ThreadPool.QueueUserWorkItem(_ => operation.ExecuteReaderWithUpdates((record, o) => { })); mre.Wait(); operation.Dispose(); // Assert Assert.True(onErrorCalled); }
public void ExecuteReaderWithUpdates_Fail() { var fakeOracleDependencyManager = A.Fake <IOracleDependencyManager>(); var fakeSignalrDbDependencyFactory = A.Fake <ISignalrDbDependencyFactory>(); ObservableDbOperation dbOperation = new ObservableDbOperation(string.Empty, string.Empty, new TraceSource("ss"), null, A.Fake <IDbProviderFactory>(), fakeOracleDependencyManager, fakeSignalrDbDependencyFactory, true); dbOperation.Queried += () => { throw new Exception(); }; int counter = 0; dbOperation.Faulted += (ex) => { counter++; }; using (var cts = new CancellationTokenSource()) { Task.Run(() => dbOperation.ExecuteReaderWithUpdates(A.Fake <Action <IDataRecord, IDbOperation> >()), cts.Token); Thread.Sleep(1000); dbOperation.Dispose(); cts.Cancel(); } Assert.IsTrue(counter > 0); }
public void ExecuteReaderSetsNotificationStateCorrectlyUpToAwaitingNotification() { // Arrange var retryLoopDelays = new[] { Tuple.Create(0, 1) }; var dbProviderFactory = new MockDbProviderFactory(); var dbBehavior = new Mock <IDbBehavior>(); var logger = new Mock <ILogger>(); dbBehavior.Setup(db => db.UpdateLoopRetryDelays).Returns(retryLoopDelays); dbBehavior.Setup(db => db.StartSqlDependencyListener()).Returns(true); dbBehavior.Setup(db => db.AddSqlDependency(It.IsAny <IDbCommand>(), It.IsAny <Action <SqlNotificationEventArgs> >())); var operation = new ObservableDbOperation("test", "test", logger.Object, dbProviderFactory, dbBehavior.Object); operation.Queried += () => { // Currently in the query loop Assert.Equal(ObservableDbOperation.NotificationState.ProcessingUpdates, operation.CurrentNotificationState); }; // Act operation.ExecuteReaderWithUpdates((_, __) => { }); // Assert Assert.Equal(ObservableDbOperation.NotificationState.AwaitingNotification, operation.CurrentNotificationState); operation.Dispose(); }
public void ExecuteReaderSetsNotificationStateCorrectlyWhenNotificationReceivedBeforeChangingStateToAwaitingNotification() { // Arrange var mre = new ManualResetEventSlim(false); var retryLoopDelays = new[] { Tuple.Create(0, 1) }; var dbProviderFactory = new MockDbProviderFactory(); var sqlDependencyAdded = false; var dbBehavior = new Mock <IDbBehavior>(); var logger = new Mock <ILogger>(); dbBehavior.Setup(db => db.UpdateLoopRetryDelays).Returns(retryLoopDelays); dbBehavior.Setup(db => db.StartSqlDependencyListener()).Returns(true); dbBehavior.Setup(db => db.AddSqlDependency(It.IsAny <IDbCommand>(), It.IsAny <Action <SqlNotificationEventArgs> >())) .Callback(() => sqlDependencyAdded = true); var operation = new ObservableDbOperation("test", "test", logger.Object, dbProviderFactory, dbBehavior.Object); dbProviderFactory.MockDataReader.Setup(r => r.Read()).Returns(() => { if (sqlDependencyAdded) { // Fake the SQL dependency firing while we're setting it up operation.CurrentNotificationState = ObservableDbOperation.NotificationState.NotificationReceived; sqlDependencyAdded = false; } return(false); }); long?stateOnLoopRestart = null; var queriedCount = 0; operation.Queried += () => { queriedCount++; if (queriedCount == 3) { // First query after the loop starts again, capture the state stateOnLoopRestart = operation.CurrentNotificationState; mre.Set(); } }; // Act ThreadPool.QueueUserWorkItem(_ => operation.ExecuteReaderWithUpdates((__, ___) => { })); mre.Wait(); Assert.True(stateOnLoopRestart.HasValue); Assert.Equal(ObservableDbOperation.NotificationState.ProcessingUpdates, stateOnLoopRestart.Value); operation.Dispose(); }
public void DoesRetryLoopConfiguredNumberOfTimes(int?length1, int?length2, int?length3) { // Arrange var retryLoopCount = 0; var mre = new ManualResetEventSlim(); var retryLoopArgs = new List <int?>(new[] { length1, length2, length3 }).Where(l => l.HasValue); var retryLoopTotal = retryLoopArgs.Sum().Value; var retryLoopDelays = new List <Tuple <int, int> >(retryLoopArgs.Select(l => new Tuple <int, int>(0, l.Value))); var sqlDependencyCreated = false; var dbProviderFactory = new MockDbProviderFactory(); var dbBehavior = new Mock <IDbBehavior>(); var logger = new Mock <ILogger>(); dbBehavior.Setup(db => db.UpdateLoopRetryDelays).Returns(retryLoopDelays); dbBehavior.Setup(db => db.StartSqlDependencyListener()).Returns(true); dbBehavior.Setup(db => db.AddSqlDependency(It.IsAny <IDbCommand>(), It.IsAny <Action <SqlNotificationEventArgs> >())) .Callback(() => { sqlDependencyCreated = true; mre.Set(); }); var operation = new ObservableDbOperation("test", "test", logger.Object, dbProviderFactory, dbBehavior.Object); operation.Faulted += _ => mre.Set(); operation.Queried += () => { if (!sqlDependencyCreated) { // Only update the loop count if the SQL dependency hasn't been created yet (we're still in the loop) retryLoopCount++; } if (retryLoopCount == retryLoopTotal) { mre.Set(); } }; // Act ThreadPool.QueueUserWorkItem(_ => operation.ExecuteReaderWithUpdates((record, o) => { })); mre.Wait(); operation.Dispose(); // Assert Assert.Equal(retryLoopTotal, retryLoopCount); }
public void ExecuteReaderSetsNotificationStateCorrectlyWhenRecordsReceivedWhileSettingUpSqlDependency() { // Arrange var mre = new ManualResetEventSlim(false); var retryLoopDelays = new[] { Tuple.Create(0, 1) }; var dbProviderFactory = new MockDbProviderFactory(); var readCount = 0; var sqlDependencyAddedCount = 0; dbProviderFactory.MockDataReader.Setup(r => r.Read()).Returns(() => ++ readCount == 2 && sqlDependencyAddedCount == 1); var dbBehavior = new Mock <IDbBehavior>(); dbBehavior.Setup(db => db.UpdateLoopRetryDelays).Returns(retryLoopDelays); dbBehavior.Setup(db => db.StartSqlDependencyListener()).Returns(true); dbBehavior.Setup(db => db.AddSqlDependency(It.IsAny <IDbCommand>(), It.IsAny <Action <SqlNotificationEventArgs> >())).Callback(() => sqlDependencyAddedCount++); var operation = new ObservableDbOperation("test", "test", new TraceSource("test"), dbProviderFactory, dbBehavior.Object); long?stateOnLoopRestart = null; var queriedCount = 0; operation.Queried += () => { queriedCount++; if (queriedCount == 3) { // First query after the loop starts again, check the state is reset stateOnLoopRestart = operation.CurrentNotificationState; mre.Set(); } }; // Act ThreadPool.QueueUserWorkItem(_ => operation.ExecuteReaderWithUpdates((__, ___) => { })); Assert.True(mre.Wait(5000)); Assert.True(stateOnLoopRestart.HasValue); Assert.Equal(ObservableDbOperation.NotificationState.ProcessingUpdates, stateOnLoopRestart.Value); operation.Dispose(); }
public void UseSqlNotificationsIfAvailable(bool supportSqlNotifications) { // Arrange var sqlDependencyAdded = false; var retryLoopCount = 0; var mre = new ManualResetEventSlim(); var dbProviderFactory = new MockDbProviderFactory(); var dbBehavior = new Mock <IDbBehavior>(); var logger = new Mock <ILogger>(); dbBehavior.Setup(db => db.UpdateLoopRetryDelays).Returns(_defaultRetryDelays); dbBehavior.Setup(db => db.StartSqlDependencyListener()).Returns(supportSqlNotifications); dbBehavior.Setup(db => db.AddSqlDependency(It.IsAny <IDbCommand>(), It.IsAny <Action <SqlNotificationEventArgs> >())) .Callback(() => { sqlDependencyAdded = true; mre.Set(); }); var operation = new ObservableDbOperation("test", "test", logger.Object, dbProviderFactory, dbBehavior.Object); operation.Faulted += _ => mre.Set(); operation.Queried += () => { retryLoopCount++; if (retryLoopCount > 1) { mre.Set(); } }; // Act ThreadPool.QueueUserWorkItem(_ => operation.ExecuteReaderWithUpdates((record, o) => { })); mre.Wait(); operation.Dispose(); // Assert Assert.Equal(supportSqlNotifications, sqlDependencyAdded); }
public void Pooling_Success() { var fakeDbReader = A.Fake <IDataReader>(); var fakeDbReaderReadCall = A.CallTo(() => fakeDbReader.Read()); fakeDbReaderReadCall.ReturnsNextFromSequence(true, true, false); var fakeEmptyDbReader = A.Fake <IDataReader>(); A.CallTo(() => fakeEmptyDbReader.Read()).Returns(false); var fakeDbCommand = A.Fake <IDbCommand>(); A.CallTo(() => fakeDbCommand.ExecuteReader()).ReturnsNextFromSequence(fakeDbReader, fakeEmptyDbReader); var fakeDbConnection = A.Fake <IDbConnection>(); A.CallTo(() => fakeDbConnection.CreateCommand()).Returns(fakeDbCommand); var fakeDbConnectionDisposeCall = A.CallTo(() => fakeDbConnection.Dispose()); var fakeDbProviderFactory = A.Fake <IDbProviderFactory>(); A.CallTo(() => fakeDbProviderFactory.CreateConnection()).Returns(fakeDbConnection); var fakeProcessRecordAction = A.Fake <Action <IDataRecord, IDbOperation> >(); var fakeProcessRecordActionInvokeCall = A.CallTo(() => fakeProcessRecordAction.Invoke(null, null)).WithAnyArguments(); var fakeDbBehavior = A.Fake <IDbBehavior>(); A.CallTo(() => fakeDbBehavior.UpdateLoopRetryDelays).Returns(_updateLoopRetryDelays); var fakeOracleDependencyManager = A.Fake <IOracleDependencyManager>(); var fakeOracleDependencyManagerRegistryDepCall = A.CallTo(() => fakeOracleDependencyManager.RegisterDependency(null)).WithAnyArguments(); var fakeOracleDependencyManagerRemoveRegistrationCall = A.CallTo(() => fakeOracleDependencyManager.RemoveRegistration(string.Empty)).WithAnyArguments(); var fakeSignalrDbDependencyFactory = A.Fake <ISignalrDbDependencyFactory>(); var fakeSignalrDbDependencyFactoryCreateDepCall = A.CallTo(() => fakeSignalrDbDependencyFactory.CreateDbDependency(null, false, 0, false)).WithAnyArguments(); ObservableDbOperation dbOperation = new ObservableDbOperation(string.Empty, string.Empty, new TraceSource("ss"), fakeDbBehavior, fakeDbProviderFactory, fakeOracleDependencyManager, fakeSignalrDbDependencyFactory, false); using (var cts = new CancellationTokenSource()) { Task.Run(() => dbOperation.ExecuteReaderWithUpdates(fakeProcessRecordAction), cts.Token); Thread.Sleep(1000); cts.Cancel(); } Thread.Sleep(1000); fakeOracleDependencyManagerRegistryDepCall.MustNotHaveHappened(); fakeSignalrDbDependencyFactoryCreateDepCall.MustNotHaveHappened(); fakeProcessRecordActionInvokeCall.MustHaveHappened(); fakeDbReaderReadCall.MustHaveHappened(Repeated.Exactly.Times(3)); fakeDbConnectionDisposeCall.MustHaveHappened(); dbOperation.Dispose(); fakeOracleDependencyManagerRemoveRegistrationCall.MustHaveHappened(Repeated.Exactly.Once); }