public void CallsOnErrorOnException() { // Arrange var mre = new ManualResetEventSlim(false); var onErrorCalled = false; 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(false); dbProviderFactory.MockDataReader.Setup(r => r.Read()).Throws(new ApplicationException("test")); var operation = new ObservableDbOperation("test", "test", logger.Object, 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 UseSqlNotificationsIfAvailable(bool supportSqlNotifications) { // Arrange var sqlDependencyAdded = false; var retryLoopCount = 0; var mre = new ManualResetEventSlim(); var dbProviderFactory = new MockDbProviderFactory(); var dbBehavior = new Mock<IDbBehavior>(); 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", new TraceSource("test"), 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 Dispose() { lock (this) { if (_dbOperation != null) { _dbOperation.Dispose(); } _disposed = true; } }
public void Dispose() { lock (this) { if (_dbOperation != null) { _dbOperation.Dispose(); } _disposed = true; _trace.TraceInformation("{0}SqlReceiver disposed", _tracePrefix); } }
public void Dispose() { lock (this) { if (_dbOperation != null) { _dbOperation.Dispose(); } _disposed = true; _logger.LogInformation("{0}SqlReceiver disposed", _loggerPrefix); } }
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>(); 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", new TraceSource("test"), 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 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>(); 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", new TraceSource("test"), 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 ExecuteReaderSetsNotificationStateCorrectlyUpToAwaitingNotification() { // Arrange var retryLoopDelays = new [] { Tuple.Create(0, 1) }; var dbProviderFactory = new MockDbProviderFactory(); 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>>())); var operation = new ObservableDbOperation("test", "test", new TraceSource("test"), 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 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>(); 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(() => sqlDependencyAddedCount++); var operation = new ObservableDbOperation("test", "test", logger.Object, 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((__, ___) => { })); mre.Wait(); Assert.True(stateOnLoopRestart.HasValue); Assert.Equal(ObservableDbOperation.NotificationState.ProcessingUpdates, stateOnLoopRestart.Value); operation.Dispose(); }