private void CreateClockIfNotExists() { try { using (var con = new SqlConnection(TestSettings.ConnectionStringCommandScheduler)) { con.Open(); using ( var command = new SqlCommand( $"select 1 from [Scheduler].[Clock] where [Name]='{TestSettings.CustomClockName}'", con)) { var exists = command.ExecuteScalar(); if (exists == null) { _configuration .SchedulerClockRepository() .CreateClock(TestSettings.CustomClockName, Clock.Now()); } } } } catch (Exception e) { Console.WriteLine(e); } }
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_EventSourced.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 Configuration.Current.Repository <Order>().Save(order); }); // reset the clock so that when the messages are delivered, the target commands are now due Clock.Reset(); await queueReceiver.StartReceivingMessages(); schedulerActivity .Select(a => Guid.Parse(a.TargetId)) .ShouldBeEquivalentTo(aggregateIds); } }
public async Task When_ServiceBusCommandQueueSender_is_subscribed_to_the_service_bus_then_messages_are_scheduled_to_trigger_directly_scheduled_commands() { VirtualClock.Start(DateTimeOffset.Now.AddHours(-13)); using (var queueReceiver = CreateQueueReceiver()) { var aggregateIds = Enumerable.Range(1, 5) .Select(_ => Guid.NewGuid()) .ToArray(); aggregateIds.ForEach(id => { // TODO: (When_ServiceBusCommandQueueSender_is_subscribed_to_the_service_bus_then_messages_are_scheduled_to_trigger_directly_scheduled_commands) }); // reset the clock so that when the messages are delivered, the target commands are now due Clock.Reset(); await queueReceiver.StartReceivingMessages(); schedulerActivity .Select(a => Guid.Parse(a.TargetId)) .ShouldBeEquivalentTo(aggregateIds); } }
public override void TearDown() { Settings.Reset(); disposables.Dispose(); Clock.Reset(); base.TearDown(); }
public async Task When_ServiceBusCommandQueueSender_is_subscribed_to_the_service_bus_then_messages_are_scheduled_to_trigger_directly_scheduled_commands() { VirtualClock.Start(DateTimeOffset.Now.AddHours(-13)); using (var queueReceiver = CreateQueueReceiver()) { var aggregateIds = Enumerable.Range(1, 5) .Select(_ => Guid.NewGuid()) .ToArray(); aggregateIds.ForEach(id => { // FIX: (When_ServiceBusCommandQueueSender_is_subscribed_to_the_service_bus_then_messages_are_scheduled_to_trigger_directly_scheduled_commands) }); 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); } }
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_EventSourced.CreateOrder(orderId: aggregateId) .Apply(new ShipOn(Clock.Now().AddSeconds(-5))); queueSender.MessageDeliveryOffsetFromCommandDueTime = TimeSpan.FromSeconds(0); await Configuration.Current.Repository <Order>().Save(order); using (var receiver = CreateQueueReceiver()) { var receivedMessages = new List <IScheduledCommand>(); receiver.Messages .Where(m => m.IfTypeIs <IScheduledCommand <Order> >() .Then(c => c.TargetId == aggregateId.ToString()) .ElseDefault()) .Subscribe(receivedMessages.Add); await receiver.StartReceivingMessages(); await Task.Delay(TimeSpan.FromSeconds(5)); receivedMessages.Should() .ContainSingle(m => m.IfTypeIs <IScheduledCommand <Order> >() .Then(c => c.TargetId == aggregateId.ToString()) .ElseDefault()); } using (var receiver = CreateQueueReceiver()) { var receivedMessages = new List <IScheduledCommand>(); receiver.Messages .Where(m => m.IfTypeIs <IScheduledCommand <Order> >() .Then(c => c.TargetId == aggregateId.ToString()) .ElseDefault()) .Subscribe(receivedMessages.Add); await receiver.StartReceivingMessages(); await Task.Delay(TimeSpan.FromSeconds(10)); receivedMessages.Count.Should().Be(0); } }
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 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(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 }); orderRepository.Save(order); }); RunCatchup(); // reset the clock so that when the messages are delivered, the target commands are now due Clock.Reset(); 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); } }
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>(); 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_EventSourced.CreateOrder(orderId : aggregateId) .ApplyAsync(new ShipOn(Clock.Now().AddMinutes(2))); await Configuration.Current.Repository <Order>().Save(order); await receiver.Messages .OfType <IScheduledCommand <Order> >() .FirstAsync(c => c.TargetId == aggregateId.ToString()) .Timeout(TimeSpan.FromMinutes(1)); await Task.Delay(1000); appliedCommands.Should().BeEmpty(); } Clock.Reset(); using (var receiver = CreateQueueReceiver()) { await receiver.StartReceivingMessages(); await Task.Delay(1000); // FIX: (When_a_command_trigger_message_arrives_early_it_is_not_Completed) how was this even passing? // appliedCommands.Should().Contain(c => c.ScheduledCommand.AggregateId == aggregateId); } }