public async Task Activity_is_notified_when_a_command_is_delivered_immediately() { // arrange var order = CommandSchedulingTests.CreateOrder(); var activity = new List <ICommandSchedulerActivity>(); using (Configuration.Current .Container .Resolve <SqlCommandScheduler>() .Activity .Subscribe(a => activity.Add(a))) { // act order.Apply(new ShipOn(Clock.Now().Subtract(TimeSpan.FromDays(2)))); await orderRepository.Save(order); await SchedulerWorkComplete(); //assert activity.Should() .ContainSingle(a => a.ScheduledCommand.AggregateId == order.Id && a is CommandSucceeded); } }
public async Task A_command_is_not_marked_as_applied_if_no_handler_is_registered() { // arrange var order = CommandSchedulingTests.CreateOrder(); order.Apply( new ChargeCreditCardOn { Amount = 10, ChargeDate = Clock.Now().AddDays(10) }); await orderRepository.Save(order); // act var schedulerWithNoHandlers = new SqlCommandScheduler( new Configuration().UseSqlEventStore()); await schedulerWithNoHandlers.AdvanceClock(clockName, @by : TimeSpan.FromDays(20)); // assert using (var db = new CommandSchedulerDbContext()) { db.ScheduledCommands.Single(c => c.AggregateId == order.Id) .AppliedTime .Should() .BeNull(); } }
public async Task When_a_command_has_been_completed_and_a_message_for_it_arrives_the_message_is_also_Completed() { var aggregateId = Any.Guid(); // due in the past so that it's scheduled immediately var order = CommandSchedulingTests.CreateOrder(orderId: aggregateId) .Apply(new ShipOn(Clock.Now().AddSeconds(-5))); queueSender.MessageDeliveryOffsetFromCommandDueTime = TimeSpan.FromSeconds(0); await orderRepository.Save(order); await RunCatchup(); using (var receiver = CreateQueueReceiver()) { var receivedMessages = new List <IScheduledCommand>(); receiver.Messages .Where(c => c.AggregateId == aggregateId) .Subscribe(receivedMessages.Add); await receiver.StartReceivingMessages(); await Task.Delay(TimeSpan.FromSeconds(5)); receivedMessages.Should().ContainSingle(e => e.AggregateId == aggregateId); } using (var receiver = CreateQueueReceiver()) { var receivedMessages = new List <IScheduledCommand>(); receiver.Messages .Where(c => c.AggregateId == aggregateId) .Subscribe(receivedMessages.Add); await receiver.StartReceivingMessages(); await Task.Delay(TimeSpan.FromSeconds(10)); receivedMessages.Count().Should().Be(0); } }
public async Task When_a_command_trigger_message_arrives_early_it_is_not_Completed() { VirtualClock.Start(Clock.Now().AddHours(-1)); var aggregateId = Any.Guid(); var appliedCommands = new List <ICommandSchedulerActivity>(); scheduler.Activity .Where(c => c.ScheduledCommand.AggregateId == aggregateId) .Subscribe(appliedCommands.Add); using (var receiver = CreateQueueReceiver()) { await receiver.StartReceivingMessages(); // due enough in the future that the scheduler won't apply the commands immediately var order = await CommandSchedulingTests.CreateOrder(orderId : aggregateId) .ApplyAsync(new ShipOn(Clock.Now().AddMinutes(2))); await orderRepository.Save(order); await RunCatchup(); await receiver.Messages .FirstAsync(c => c.AggregateId == aggregateId) .Timeout(TimeSpan.FromMinutes(1)); await Task.Delay(1000); appliedCommands.Should().BeEmpty(); } Clock.Reset(); using (var receiver = CreateQueueReceiver()) { await receiver.StartReceivingMessages(); await Task.Delay(1000); appliedCommands.Should().Contain(c => c.ScheduledCommand.AggregateId == aggregateId); } }
public async Task SqlCommandScheduler_Activity_is_notified_when_a_command_is_delivered_via_Trigger() { // arrange var order = CommandSchedulingTests.CreateOrder(); var activity = new List <ICommandSchedulerActivity>(); order.Apply(new ShipOn(Clock.Now().Add(TimeSpan.FromDays(2)))); await orderRepository.Save(order); using (sqlCommandScheduler.Activity.Subscribe(activity.Add)) { // act await clockTrigger.AdvanceClock(clockName, TimeSpan.FromDays(3)); //assert activity.Should() .ContainSingle(a => a.ScheduledCommand.AggregateId == order.Id && a is CommandSucceeded); } }
public async Task When_ServiceBusCommandQueueSender_is_subscribed_to_the_service_bus_then_messages_are_scheduled_to_trigger_event_based_scheduled_commands() { VirtualClock.Start(DateTimeOffset.Now.AddHours(-13)); using (var queueReceiver = CreateQueueReceiver()) { var aggregateIds = Enumerable.Range(1, 5) .Select(_ => Guid.NewGuid()) .ToArray(); aggregateIds.ForEach(async id => { var order = CommandSchedulingTests.CreateOrder(orderId: id); // due enough in the future that the scheduler won't apply the commands immediately var due = Clock.Now().AddSeconds(5); order.Apply(new ShipOn(due)); Console.WriteLine(new { ShipOrderId = order.Id, due }); await orderRepository.Save(order); }); await RunCatchup(); // reset the clock so that when the messages are delivered, the target commands are now due Clock.Reset(); await queueReceiver.StartReceivingMessages(); var activity = await scheduler.Activity .Where(a => aggregateIds.Contains(a.ScheduledCommand.AggregateId)) .Take(5) .ToList() .Timeout(TimeSpan.FromMinutes(5)); activity.Select(a => a.ScheduledCommand.AggregateId) .ShouldBeEquivalentTo(aggregateIds); } }