public async Task Scatter_gather_produces_a_unique_etag_per_sent_command() { var repo = configuration.Repository<MarcoPoloPlayerWhoIsIt>(); var it = new MarcoPoloPlayerWhoIsIt(); await repo.Save(it); var numberOfPlayers = 6; var players = Enumerable.Range(1, numberOfPlayers) .Select(_ => new MarcoPoloPlayerWhoIsNotIt()); foreach (var player in players) { var joinGame = new MarcoPoloPlayerWhoIsNotIt.JoinGame { IdOfPlayerWhoIsIt = it.Id }; await player.ApplyAsync(joinGame).AndSave(); } await repo.Refresh(it); await it.ApplyAsync(new MarcoPoloPlayerWhoIsIt.SayMarco()).AndSave(); await repo.Refresh(it); it.Events() .OfType<MarcoPoloPlayerWhoIsIt.HeardPolo>() .Count() .Should() .Be(numberOfPlayers); }
public async Task Aggregates_can_schedule_commands_against_themselves_idempotently() { var it = new MarcoPoloPlayerWhoIsIt(); await Save(it); await it.ApplyAsync(new MarcoPoloPlayerWhoIsIt.KeepSayingMarcoOverAndOver()); VirtualClock.Current.AdvanceBy(TimeSpan.FromMinutes(1)); it = await Get<MarcoPoloPlayerWhoIsIt>(it.Id); it.Events() .OfType<MarcoPoloPlayerWhoIsIt.SaidMarco>() .Count() .Should() .BeGreaterOrEqualTo(5); }
public async Task Multiple_scheduled_commands_having_the_some_causative_command_etag_have_repeatable_and_unique_etags() { var scheduled = new List<ICommand>(); string[] firstPassEtags; string[] secondPassEtags; configuration.AddToCommandSchedulerPipeline<MarcoPoloPlayerWhoIsIt>(async (cmd, next) => { scheduled.Add(cmd.Command); await next(cmd); }); configuration.AddToCommandSchedulerPipeline<MarcoPoloPlayerWhoIsNotIt>(async (cmd, next) => { scheduled.Add(cmd.Command); await next(cmd); }); var it = new MarcoPoloPlayerWhoIsIt() .Apply(new MarcoPoloPlayerWhoIsIt.AddPlayer { PlayerId = Any.Guid() }) .Apply(new MarcoPoloPlayerWhoIsIt.AddPlayer { PlayerId = Any.Guid() }); Console.WriteLine("[Saving]"); await itRepo.Save(it); var sourceEtag = Any.Guid().ToString(); await it.ApplyAsync(new MarcoPoloPlayerWhoIsIt.KeepSayingMarcoOverAndOver { ETag = sourceEtag }); // VirtualClock.Current.AdvanceBy(TimeSpan.FromSeconds(2)); firstPassEtags = scheduled.Select(c => c.ETag).ToArray(); Console.WriteLine(new { firstPassEtags }.ToLogString()); scheduled.Clear(); // revert the aggregate and do the same thing again it = await itRepo.GetLatest(it.Id); await it.ApplyAsync(new MarcoPoloPlayerWhoIsIt.KeepSayingMarcoOverAndOver { ETag = sourceEtag }); Console.WriteLine("about to advance clock for the second time"); // VirtualClock.Current.AdvanceBy(TimeSpan.FromSeconds(2)); secondPassEtags = scheduled.Select(c => c.ETag).ToArray(); Console.WriteLine(new { secondPassEtags }.ToLogString()); secondPassEtags.Should() .Equal(firstPassEtags); }
public async Task Multiple_scheduled_commands_having_the_some_causative_command_etag_have_repeatable_and_unique_etags() { var scheduled = new List<ICommand>(); var configuration = Configuration.Current; configuration.AddToCommandSchedulerPipeline<MarcoPoloPlayerWhoIsIt>(async (cmd, next) => { scheduled.Add(cmd.Command); await next(cmd); }); configuration.AddToCommandSchedulerPipeline<MarcoPoloPlayerWhoIsNotIt>(async (cmd, next) => { scheduled.Add(cmd.Command); await next(cmd); }); var it = new MarcoPoloPlayerWhoIsIt() .Apply(new MarcoPoloPlayerWhoIsIt.AddPlayer { PlayerId = Any.Guid() }) .Apply(new MarcoPoloPlayerWhoIsIt.AddPlayer { PlayerId = Any.Guid() }); await Save(it); var sourceEtag = Any.Guid().ToString(); await it.ApplyAsync(new MarcoPoloPlayerWhoIsIt.KeepSayingMarcoOverAndOver { ETag = sourceEtag }); var firstPassEtags = scheduled.Select(c => c.ETag).ToArray(); scheduled.Clear(); // revert the aggregate and do the same thing again it = await Get<MarcoPoloPlayerWhoIsIt>(it.Id); await it.ApplyAsync(new MarcoPoloPlayerWhoIsIt.KeepSayingMarcoOverAndOver { ETag = sourceEtag }); var secondPassEtags = scheduled.Select(c => c.ETag).ToArray(); secondPassEtags.Should() .Equal(firstPassEtags); }