public override async Task Immediately_scheduled_commands_triggered_by_a_scheduled_command_have_their_due_time_set_to_the_causative_command_clock() { var aggregate = new CommandSchedulerTestAggregate(); await Save(aggregate); var dueTime = Clock.Now().AddMinutes(5); await Schedule( aggregate.Id, dueTime : dueTime, command : new CommandSchedulerTestAggregate.CommandThatSchedulesAnotherCommand { NextCommandAggregateId = aggregate.Id, NextCommand = new CommandSchedulerTestAggregate.Command { CommandId = Any.CamelCaseName() } }); VirtualClock.Current.AdvanceBy(TimeSpan.FromDays(1)); using (var db = CommandSchedulerDbContext()) { foreach (var command in db.ScheduledCommands.Where(c => c.AggregateId == aggregate.Id)) { command.AppliedTime .IfNotNull() .ThenDo(v => v.Should().BeCloseTo(dueTime, 10)); } } }
public async Task When_a_scheduled_command_fails_then_the_events_written_by_the_command_handler_are_not_saved_to_the_aggregate() { var aggregate = new CommandSchedulerTestAggregate(); await Save(aggregate); await Schedule( aggregate.Id, command : new CommandSchedulerTestAggregate.CommandThatRecordsCommandSucceededEventWithoutExplicitlySavingAndThenFails()); var latestAggregate = await Get <CommandSchedulerTestAggregate>(aggregate.Id); latestAggregate.EventHistory.OfType <CommandSchedulerTestAggregate.CommandSucceeded>().Should().HaveCount(0); }
public async Task When_a_command_schedules_another_command_on_a_specific_clock_the_new_command_is_on_the_same_clock() { // arrange var targetId = Any.Guid(); var nextCommandId = Any.CamelCaseName(); var theFirst = DateTimeOffset.Parse("2012-01-01"); var theThird = theFirst.AddDays(2); var theFourth = theThird.AddDays(1); var customClock = CreateClock(Any.CamelCaseName(), theFirst); var delivered = new ConcurrentBag <IScheduledCommand>(); Configuration.Current .TraceScheduledCommands( onDelivered: command => { delivered.Add(command); }); var target = new CommandSchedulerTestAggregate(targetId); await Save(target); await Schedule( targetId, new CommandSchedulerTestAggregate.CommandThatSchedulesAnotherCommand { NextCommand = new CommandSchedulerTestAggregate.Command { CommandId = nextCommandId }, NextCommandDueTime = theFourth }, theThird, clock : customClock); // act await AdvanceClock(theThird, customClock.Name); await AdvanceClock(theFourth, customClock.Name); //assert delivered.Should().HaveCount(2); delivered .OfType <ScheduledCommand <CommandSchedulerTestAggregate> >() .Select(_ => _.Command) .OfType <CommandSchedulerTestAggregate.Command>() .Should() .Contain(c => c.CommandId == nextCommandId); }
public async Task When_the_clock_is_advanced_then_commands_are_delivered_in_the_expected_order() { // arrange VirtualClock.Start(DateTimeOffset.Parse("2016-04-08 12:00:00 PM")); var aggregate = new CommandSchedulerTestAggregate(Any.Guid()); var commandsDelivered = new List <IScheduledCommand <CommandSchedulerTestAggregate> >(); var configuration = Configuration.Current .TraceScheduledCommands(onDelivering: c => commandsDelivered.Add((IScheduledCommand <CommandSchedulerTestAggregate>)c)); await configuration.Repository <CommandSchedulerTestAggregate>().Save(aggregate); var firstCommandSchedulesSecond = new CommandSchedulerTestAggregate.CommandThatSchedulesAnotherCommand { NextCommand = new CommandSchedulerTestAggregate.Command { ETag = "second" }, NextCommandAggregateId = aggregate.Id, NextCommandDueTime = Clock.Now().AddHours(1), ETag = "first" }; var thirdCommand = new CommandSchedulerTestAggregate.Command { ETag = "third" }; var scheduler = configuration.CommandScheduler <CommandSchedulerTestAggregate>(); await scheduler.Schedule(aggregate.Id, firstCommandSchedulesSecond, Clock.Now().AddMinutes(1)); await scheduler.Schedule(aggregate.Id, thirdCommand, Clock.Now().AddDays(1)); // act VirtualClock.Current.AdvanceBy(1.Days().And(1.Seconds())); // assert Console.WriteLine(commandsDelivered.Select(c => c.DueTime).ToLogString()); commandsDelivered .Select(c => c.Command.ETag) .Should() .ContainInOrder("first", "second", "third"); }
public async Task When_the_clock_is_advanced_then_commands_are_delivered_in_the_expected_order() { // arrange VirtualClock.Start(DateTimeOffset.Parse("2016-04-08 12:00:00 PM")); var aggregate = new CommandSchedulerTestAggregate(Any.Guid()); var commandsDelivered = new List<IScheduledCommand<CommandSchedulerTestAggregate>>(); var configuration = Configuration.Current .TraceScheduledCommands(onDelivering: c => commandsDelivered.Add((IScheduledCommand<CommandSchedulerTestAggregate>) c)); await configuration.Repository<CommandSchedulerTestAggregate>().Save(aggregate); var firstCommandSchedulesSecond = new CommandSchedulerTestAggregate.CommandThatSchedulesAnotherCommand { NextCommand = new CommandSchedulerTestAggregate.Command { ETag = "second" }, NextCommandAggregateId = aggregate.Id, NextCommandDueTime = Clock.Now().AddHours(1), ETag = "first" }; var thirdCommand = new CommandSchedulerTestAggregate.Command { ETag = "third" }; var scheduler = configuration.CommandScheduler<CommandSchedulerTestAggregate>(); await scheduler.Schedule(aggregate.Id, firstCommandSchedulesSecond, Clock.Now().AddMinutes(1)); await scheduler.Schedule(aggregate.Id, thirdCommand, Clock.Now().AddDays(1)); // act VirtualClock.Current.AdvanceBy(1.Days().And(1.Seconds())); // assert Console.WriteLine(commandsDelivered.Select(c => c.DueTime).ToLogString()); commandsDelivered .Select(c => c.Command.ETag) .Should() .ContainInOrder("first", "second", "third"); }
public async Task Immediately_scheduled_commands_triggered_by_a_scheduled_command_have_their_due_time_set_to_the_causative_command_clock() { VirtualClock.Start(); var aggregate = new CommandSchedulerTestAggregate(); var repository = Configuration.Current .Repository<CommandSchedulerTestAggregate>(); await repository.Save(aggregate); var scheduler = Configuration.Current.CommandScheduler<CommandSchedulerTestAggregate>(); var dueTime = Clock.Now().AddMinutes(5); await scheduler.Schedule( aggregate.Id, dueTime: dueTime, command: new CommandSchedulerTestAggregate.CommandThatSchedulesAnotherCommandImmediately { NextCommandAggregateId = aggregate.Id, NextCommand = new CommandSchedulerTestAggregate.Command { CommandId = Any.CamelCaseName() } }); VirtualClock.Current.AdvanceBy(TimeSpan.FromDays(1)); using (var db = new CommandSchedulerDbContext()) { foreach (var command in db.ScheduledCommands.Where(c => c.AggregateId == aggregate.Id)) { command.AppliedTime .IfNotNull() .ThenDo(v => v.Should().BeCloseTo(dueTime, 10)); } } }
public async Task Scheduled_commands_triggered_by_a_scheduled_command_are_idempotent() { var aggregate = new CommandSchedulerTestAggregate(); await Save(aggregate); var dueTime = Clock.Now().AddMinutes(5); Console.WriteLine(new { dueTime }); var command = new CommandSchedulerTestAggregate.CommandThatSchedulesTwoOtherCommandsImmediately { NextCommand1AggregateId = aggregate.Id, NextCommand1 = new CommandSchedulerTestAggregate.Command { CommandId = Any.CamelCaseName() }, NextCommand2AggregateId = aggregate.Id, NextCommand2 = new CommandSchedulerTestAggregate.Command { CommandId = Any.CamelCaseName() } }; await Schedule( aggregate.Id, dueTime: dueTime, command: command); await Schedule( aggregate.Id, dueTime: dueTime, command: command); VirtualClock.Current.AdvanceBy(TimeSpan.FromDays(1)); aggregate = await Get<CommandSchedulerTestAggregate>(aggregate.Id); var events = aggregate.Events().ToArray(); events.Count().Should().Be(3); var succeededEvents = events.OfType<CommandSchedulerTestAggregate.CommandSucceeded>().ToArray(); succeededEvents.Count().Should().Be(2); succeededEvents.First().Command.CommandId .Should().NotBe(succeededEvents.Last().Command.CommandId); }
public async Task When_a_scheduled_command_fails_then_the_events_written_by_the_command_handler_are_not_saved_to_the_aggregate() { var aggregate = new CommandSchedulerTestAggregate(); var repository = Configuration.Current.Repository<CommandSchedulerTestAggregate>(); await repository.Save(aggregate); var scheduler = Configuration.Current.CommandScheduler<CommandSchedulerTestAggregate>(); await scheduler.Schedule( aggregate.Id, command: new CommandSchedulerTestAggregate.CommandThatRecordsCommandSucceededEventWithoutExplicitlySavingAndThenFails()); var latestAggregate = await repository.GetLatest(aggregate.Id); latestAggregate.EventHistory.OfType<CommandSchedulerTestAggregate.CommandSucceeded>().Should().HaveCount(0); }