public void GetNextDelay_returns_shorter_delay_for_InMemory_transient_errors() { var strategy = new TestSqlServerRetryingExecutionStrategy(CreateContext()); var inMemoryError = SqlExceptionFactory.CreateSqlException(41302); var delays = new List <TimeSpan>(); var delay = strategy.GetNextDelay(inMemoryError); while (delay != null) { delays.Add(delay.Value); delay = strategy.GetNextDelay(inMemoryError); } var expectedDelays = new List <TimeSpan> { TimeSpan.FromMilliseconds(0), TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(3), TimeSpan.FromMilliseconds(7), TimeSpan.FromMilliseconds(15), TimeSpan.FromMilliseconds(31) }; Assert.Equal(expectedDelays.Count, delays.Count); for (var i = 0; i < expectedDelays.Count; i++) { Assert.True( Math.Abs((delays[i] - expectedDelays[i]).TotalMilliseconds) <= expectedDelays[i].TotalMilliseconds * 0.1 + 1, $"Expected: {expectedDelays[i]}; Actual: {delays[i]}"); } }
public async Task Retries_BeginTransaction_on_execution_failure(bool async) { using (var context = CreateContext()) { var connection = (TestSqlServerConnection)context.GetService <ISqlServerConnection>(); connection.OpenFailures.Enqueue(new bool?[] { true }); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); if (async) { var transaction = await new TestSqlServerRetryingExecutionStrategy(context).ExecuteAsync( context, c => context.Database.BeginTransactionAsync()); transaction.Dispose(); } else { var transaction = new TestSqlServerRetryingExecutionStrategy(context).Execute( context, c => context.Database.BeginTransaction()); transaction.Dispose(); } Assert.Equal(2, connection.OpenCount); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); } }
public async Task Retries_query_on_execution_failure(bool async) { CleanContext(); using (var context = CreateContext()) { context.Products.Add(new Product()); context.Products.Add(new Product()); context.SaveChanges(); } using (var context = CreateContext()) { var connection = (TestSqlServerConnection)context.GetService <ISqlServerConnection>(); connection.ExecutionFailures.Enqueue(new bool?[] { true }); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); if (async) { var list = await new TestSqlServerRetryingExecutionStrategy(context).ExecuteInTransactionAsync( context, (c, _) => context.Products.ToListAsync(), (c, _) => { // This shouldn't be called if query failed Assert.True(false); return(Task.FromResult(false)); }); Assert.Equal(2, list.Count); } else { var list = new TestSqlServerRetryingExecutionStrategy(context).ExecuteInTransaction( context, c => context.Products.ToList(), c => { // This shouldn't be called if query failed Assert.True(false); return(false); }); Assert.Equal(2, list.Count); } Assert.Equal(2, connection.OpenCount); Assert.Equal(2, connection.ExecutionCount); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); } }
public async Task Retries_query_on_execution_failure(bool externalStrategy, bool async) { CleanContext(); using (var context = CreateContext()) { context.Products.Add(new Product()); context.Products.Add(new Product()); context.SaveChanges(); } using (var context = CreateContext()) { var connection = (TestSqlServerConnection)context.GetService <ISqlServerConnection>(); connection.ExecutionFailures.Enqueue(new bool?[] { true }); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); List <Product> list; if (async) { if (externalStrategy) { list = await new TestSqlServerRetryingExecutionStrategy(context) .ExecuteAsync(context, (c, ct) => c.Products.ToListAsync(ct), null); } else { list = await context.Products.ToListAsync(); } } else { if (externalStrategy) { list = new TestSqlServerRetryingExecutionStrategy(context) .Execute(context, c => c.Products.ToList(), null); } else { list = context.Products.ToList(); } } Assert.Equal(2, list.Count); Assert.Equal(1, connection.OpenCount); Assert.Equal(2, connection.ExecutionCount); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); } }