示例#1
0
        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));
                }
            }
        }
示例#2
0
        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);
        }
示例#3
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);
        }
示例#4
0
        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);
        }