public void A140_UpdateAndCheckEventOutboxDequeue() { using var agentTester = AgentTester.CreateWaf <Startup>(); var r = agentTester.Test <ContactAgent, Contact>() .ExpectStatusCode(HttpStatusCode.OK) .ExpectValue((t) => new Contact { Id = 1.ToGuid(), FirstName = "Jenny", LastName = "Cuthbert", Status = "P" }) .Run(a => a.GetAsync(1.ToGuid())); Assert.NotNull(r.Response.Headers?.ETag?.Tag); var etag = r.Response.Headers?.ETag?.Tag; var db = new Beef.Demo.Business.Data.Database(agentTester.WebApplicationFactory.Services.GetService <IConfiguration>()["ConnectionStrings:BeefDemo"]); db.SqlStatement("DELETE FROM [Demo].[EventOutbox]").NonQueryAsync().GetAwaiter().GetResult(); var v = r.Value; v.LastName += "X"; r = agentTester.Test <ContactAgent, Contact>() .ExpectStatusCode(HttpStatusCode.OK) .ExpectValue((t) => v) .ExpectEvent("Demo.Contact.00000001-0000-0000-0000-000000000000", "Update") .Run(a => a.UpdateAsync(v, 1.ToGuid())); Assert.NotNull(r.Response.Headers?.ETag?.Tag); Assert.AreNotEqual(etag, r.Response.Headers?.ETag?.Tag); // Make sure the event is sent from the outbox. var count = db.SqlStatement("SELECT COUNT(*) FROM [Demo].[EventOutbox]").ScalarAsync <int>().GetAwaiter().GetResult(); Assert.AreEqual(1, count); for (int i = 0; i < 10; i++) { count = db.SqlStatement("SELECT COUNT(*) FROM [Demo].[EventOutbox] WHERE [DequeuedDate] IS NULL").ScalarAsync <int>().GetAwaiter().GetResult(); if (count == 0) { return; } System.Threading.Thread.Sleep(1000); } Assert.Fail("It would appear that the event was not dequeued by the hosted service."); }
public void A200_RaiseEvent_EventOutboxFailure() { using var agentTester = AgentTester.CreateWaf <Startup>(); var r = agentTester.Test <ContactAgent>() .ExpectStatusCode(HttpStatusCode.InternalServerError) .Run(a => a.RaiseEventAsync(true)); var db = new Beef.Demo.Business.Data.Database(agentTester.WebApplicationFactory.Services.GetService <IConfiguration>()["ConnectionStrings:BeefDemo"]); var count = db.SqlStatement("SELECT COUNT(*) FROM [Demo].[EventOutboxData] WHERE [Subject] = 'Contact' and [Action] = 'Made'").ScalarAsync <int>().GetAwaiter().GetResult(); Assert.AreEqual(0, count); }
public void A010_DatabaseDeadlock_Retry() { int count = 0; SqlRetryDatabaseInvoker.ExceptionRetry += (s, e) => count++; var p1 = AgentTester.Test <PersonAgent, PersonDetail>().ExpectStatusCode(HttpStatusCode.OK).Run(a => a.GetDetailAsync(1.ToGuid())).Value; var p2 = AgentTester.Test <PersonAgent, PersonDetail>().ExpectStatusCode(HttpStatusCode.OK).Run(a => a.GetDetailAsync(2.ToGuid())).Value; var db = new Beef.Demo.Business.Data.Database(BuildConfiguration()["ConnectionStrings:BeefDemo"]); var task1 = Task.Run(async() => { await db.SqlStatement( @"begin transaction select * from Demo.WorkHistory with (tablock, holdlock) waitfor delay '00:00:02' select * from Demo.Person with (tablock, holdlock) waitfor delay '00:00:04' commit transaction" ).NonQueryAsync(); }); var task2 = Task.Run(() => { Thread.Sleep(500); p1.FirstName += "X"; var r1 = AgentTester.Test <PersonAgent, PersonDetail>().Run(a => a.UpdateDetailAsync(p1, p1.Id)); Console.WriteLine($"Person {p1.Id} update status code: {r1.StatusCode}"); }); var task3 = Task.Run(() => { Thread.Sleep(750); p2.FirstName += "X"; var r2 = AgentTester.Test <PersonAgent, PersonDetail>().Run(a => a.UpdateDetailAsync(p2, p2.Id)); Console.WriteLine($"Person {p2.Id} update status code: {r2.StatusCode}"); }); Task.WaitAll(task1, task2, task3); if (count == 0) { Assert.Inconclusive("Unable to cause the required database deadlock; therefore, the retry logic was not exercised for this test."); } }