public async Task Verify_aggregation_call() { ProjectionStatusLoader sut = new ProjectionStatusLoader(Database, Database, 5); SampleAggregateId identity1 = new SampleAggregateId(1); var aggregate = await Repository.GetByIdAsync <SampleAggregate>(identity1).ConfigureAwait(false); aggregate.Create(); await Repository.SaveAsync(aggregate, Guid.NewGuid().ToString(), h => { }).ConfigureAwait(false); SampleAggregateId identity2 = new SampleAggregateId(2); aggregate = await Repository.GetByIdAsync <SampleAggregate>(identity2).ConfigureAwait(false); aggregate.Create(); await Repository.SaveAsync(aggregate, Guid.NewGuid().ToString(), h => { }).ConfigureAwait(false); await Engine.UpdateAndWaitAsync().ConfigureAwait(false); var result = sut.GetSlotMetrics(); Assert.That(result.Count(), Is.EqualTo(2)); Assert.That(result.ElementAt(0).CommitBehind, Is.EqualTo(0)); Assert.That(result.ElementAt(0).CommitBehind, Is.EqualTo(0)); }
public void can_serialize_access_to_the_same_entity() { //create an aggregate. var sampleAggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); aggregate.Create(); _sut.Save(aggregate, new Guid("135E4E5F-3D65-43AC-9D8D-8A8B0EFF8501"), null); NeventStoreExGlobalConfiguration.SetLockThreadSleepCount(100); using (var repo1 = CreateRepository()) using (var repo2 = CreateRepository()) { aggregate = repo1.GetById <SampleAggregate>(sampleAggregateId); aggregate.Touch(); //now create another thread that loads and change the same entity var task = Task <Boolean> .Factory.StartNew(() => { var aggregate2 = repo2.GetById <SampleAggregate>(sampleAggregateId); aggregate2.Touch(); repo2.Save(aggregate2, Guid.NewGuid(), null); return(true); }); Thread.Sleep(100); //Let be sure the other task is started doing something. repo1.Save(aggregate, Guid.NewGuid(), null); //should not throw Assert.IsTrue(task.Result); //inner should not throw. } }
public void verify_persistence_honor_database_version_when_threshold_passed() { var sampleAggregateId = new SampleAggregateId(_counter++); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); var memento = new AggregateSnapshot <SampleAggregate.State>() { Id = sampleAggregateId, Version = 30, State = new SampleAggregate.State() }; var snapshot = new Snapshot("Jarvis", sampleAggregateId, 30, memento); _persister.Load(null, 0, null).ReturnsForAnyArgs(snapshot); //Simulate the flow of a repository, first operation load the snapshot _sut.Load(sampleAggregateId, Int32.MaxValue, typeof(SampleAggregate)); //then the repository restored the snapshot ((ISnapshotable)aggregate).Restore(memento); //now iterate _persister.DidNotReceiveWithAnyArgs().Persist(null, null); for (int i = 0; i < NumberOfCommitsBeforeSnapshot; i++) { aggregate.Touch(); } _sut.Snapshot(aggregate, "Jarvis", NumberOfCommitsBeforeSnapshot); //should be persisted, becauase it is loaded at version 30, but then another snapshotthreshold count of event were raised _persister.ReceivedWithAnyArgs().Persist(null, aggregate.GetType().FullName); }
protected void CreateAggregate(Int64 id = 1) { var aggregateId = new SampleAggregateId(id); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(aggregateId); aggregate.Create(); Repository.Save(aggregate, Guid.NewGuid(), h => { }); }
protected async Task CreateAggregate(Int64 id = 1) { var aggregateId = new SampleAggregateId(id); var aggregate = await Repository.GetByIdAsync <SampleAggregate>(aggregateId).ConfigureAwait(false); aggregate.Create(); await Repository.SaveAsync(aggregate, Guid.NewGuid().ToString(), h => { }).ConfigureAwait(false); }
public void verify_snapshot_on_new_aggregate_not_call_persistence() { var sampleAggregateId = new SampleAggregateId(_counter++); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); aggregate.Create(); _sut.Snapshot(aggregate, "Jarvis", 1); _persister.DidNotReceiveWithAnyArgs().Persist(null, null); }
public void Verify_equality_base() { var id1 = new SampleAggregateId(42); var id2 = new SampleAggregateId(42); Assert.That(id1.Equals(id2)); Assert.That(id1 == id2); Assert.That(object.Equals(id1, id2)); }
private SimpleTestAtomicReadModel GenerateChangesetWithTwoEvents() { _aggregateIdSeed++; var id = new SampleAggregateId(_aggregateIdSeed); var rm1 = new SimpleTestAtomicReadModel(id); rm1.ProcessChangeset(GenerateCreatedEvent(false)); rm1.ProcessChangeset(GenerateTouchedEvent(false)); return(rm1); }
protected async Task <SampleAggregateId> CreateAggregateAndTouchAsync(Int64 id = 1, Dictionary <String, Object> headers = null) { var aggregateId = new SampleAggregateId(id); var aggregate = await Repository.GetByIdAsync <SampleAggregate>(aggregateId).ConfigureAwait(false); aggregate.Create(); aggregate.Touch(); await Repository.SaveAsync(aggregate, Guid.NewGuid().ToString(), h => SetHeaders(h, headers)).ConfigureAwait(false); return(aggregateId); }
private async Task <SampleAggregate> CreateAndSaveAggregate() { var sampleAggregateId = new SampleAggregateId(1); var aggregate = await _repositoryEx.GetByIdAsync <SampleAggregate>(sampleAggregateId).ConfigureAwait(false); aggregate.Create(); aggregate.Touch(); await _repositoryEx.SaveAsync(aggregate, Guid.NewGuid().ToString(), null).ConfigureAwait(false); return(aggregate); }
public async Task Check_tracking_of_aggregate_id() { var id = new SampleAggregateId(1); var sampleMessage = new SampleAggregateTestCommand(id); await _bus.Send(sampleMessage).ConfigureAwait(false); _handler.Reset.WaitOne(10000); Thread.Sleep(50); var track = _messages.AsQueryable().Single(); Assert.That(track.AggregateId, Is.EqualTo(id.AsString())); }
public void can_save_and_load() { var sampleAggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); aggregate.Create(); _sut.Save(aggregate, new Guid("135E4E5F-3D65-43AC-9D8D-8A8B0EFF8501"), null); var loaded = _sut.GetById <SampleAggregate>(sampleAggregateId); Assert.IsTrue(loaded.HasBeenCreated); }
public void verify_saving_snapshot() { //create an aggregate. var sampleAggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); aggregate.Create(); for (int i = 0; i < NumberOfCommitsBeforeSnapshot; i++) { ((IAggregateEx)aggregate).ApplyEvent(new SampleAggregateTouched()); } var events = _sut.Save(aggregate, new Guid("135E4E5F-3D65-43AC-9D8D-8A8B0EFF8501"), null); _sut.SnapshotManager.Received().Snapshot(aggregate, "Jarvis", events); }
public void Verify_reverse_translation_is_resilient_to_missing_id() { TestMapper sut = new TestMapper(_db, _identityManager); String key1 = Guid.NewGuid().ToString(); String key2 = Guid.NewGuid().ToString(); var id1 = sut.MapWithAutomaticCreate(key1); var id2 = sut.MapWithAutomaticCreate(key2); var id3 = new SampleAggregateId(100000); var reversed = sut.ReverseMap(id1, id2, id3); Assert.That(reversed[id1], Is.EqualTo(key1)); Assert.That(reversed[id2], Is.EqualTo(key2)); Assert.That(reversed.ContainsKey(id3), Is.False); }
public async Task verify_filtering_for_id_list() { SampleAggregateId id1 = GenerateId(); SampleAggregateId id2 = GenerateId(); SampleAggregateId id3 = GenerateId(); await SaveAggregateWithHeaders(id1, null).ConfigureAwait(false); await SaveAggregateWithHeaders(id2, null).ConfigureAwait(false); await SaveAggregateWithHeaders(id3, null).ConfigureAwait(false); var returnValue = await sut.GetCommitsAfterCheckpointTokenAsync(0, new List <string>() { id2, id3 }).ConfigureAwait(false); Assert.That(returnValue, Has.Count.EqualTo(2), "We have a single commit for the aggregate"); Assert.That(returnValue.Any(e => e.PartitionId == id2)); Assert.That(returnValue.Any(e => e.PartitionId == id3)); }
public void can_save_with_aggregate_identity() { var sampleAggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>( new SampleAggregate.State(), sampleAggregateId ); aggregate.Create(); _sut.Save(aggregate, new Guid("135E4E5F-3D65-43AC-9D8D-8A8B0EFF8501"), null); var stream = _eventStore.OpenStream("Jarvis", sampleAggregateId, int.MinValue, int.MaxValue); Assert.IsNotNull(stream); Assert.AreEqual(1, stream.CommittedEvents.Count); }
public void verify_persistence_called_after_threshold_new_aggregate() { var sampleAggregateId = new SampleAggregateId(_counter++); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); aggregate.Create(); _sut.Snapshot(aggregate, "Jarvis", 1); _persister.DidNotReceiveWithAnyArgs().Persist(null, null); for (int i = 0; i < NumberOfCommitsBeforeSnapshot; i++) { aggregate.Touch(); } _sut.Snapshot(aggregate, "Jarvis", NumberOfCommitsBeforeSnapshot); //should be persisted because it has more events than snapshotreshold _persister.ReceivedWithAnyArgs().Persist(null, aggregate.GetType().FullName); }
private async Task SaveAggregateWithHeaders(SampleAggregateId id, Dictionary <string, string> headers) { var sampleAggregate = await repository.GetByIdAsync <SampleAggregate>(id).ConfigureAwait(false); sampleAggregate.Create(); sampleAggregate.Touch(); await repository.SaveAsync(sampleAggregate, Guid.NewGuid().ToString(), a => { if (headers != null) { foreach (var h in headers) { a.Add(h.Key, h.Value); } } }).ConfigureAwait(false); }
public void profile_snapshot_opt_out() { var sampleAggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); aggregate.Create(); _sut.Save(aggregate, Guid.NewGuid(), null); int max = 20; for (int t = 1; t < max; t++) { aggregate.Touch(); _sut.Save(aggregate, Guid.NewGuid(), null); if (t == max - 5) { var snap = ((ISnapshotable)aggregate).GetSnapshot(); _eventStore.Advanced.AddSnapshot(new Snapshot("Jarvis", sampleAggregateId.AsString(), aggregate.Version, snap)); } } SnapshotsSettings.OptOut(typeof(SampleAggregate)); var sw = new Stopwatch(); sw.Start(); for (int c = 1; c <= 100; c++) { using (var repo = new RepositoryEx( _eventStore, _aggregateFactory, new ConflictDetector(), _identityConverter, NSubstitute.Substitute.For <NEventStore.Logging.ILog>())) { var loaded = repo.GetById <SampleAggregate>(sampleAggregateId); } } sw.Stop(); SnapshotsSettings.ClearOptOut(); Debug.WriteLine("Read time {0} ms", sw.ElapsedMilliseconds); }
public void verify_basic_unwinding_with_headers() { var aggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(aggregateId); aggregate.Create(); Repository.Save(aggregate, Guid.NewGuid(), h => { h.Add("test.with.dot", "BLAH"); }); sut.Unwind(); var allEvents = sut.UnwindedCollection.FindAll(); Assert.That(allEvents.Count(), Is.EqualTo(1)); var evt = allEvents.Single(); Assert.That(evt.EventType, Is.EqualTo("SampleAggregateCreated")); Assert.That(evt.GetEvent().AggregateId, Is.EqualTo(aggregateId)); Assert.That(evt.GetEvent().Context["test.with.dot"], Is.EqualTo("BLAH")); }
public async Task verify_basic_unwinding_with_headers() { var aggregateId = new SampleAggregateId(1); var aggregate = await Repository.GetByIdAsync <SampleAggregate>(aggregateId).ConfigureAwait(false); aggregate.Create(); await Repository.SaveAsync(aggregate, Guid.NewGuid().ToString(), h => h.Add("test.with.dot", "BLAH")).ConfigureAwait(false); await sut.UnwindAsync().ConfigureAwait(false); var allEvents = sut.UnwindedCollection.FindAll(); Assert.That(allEvents.Count(), Is.EqualTo(1)); var evt = allEvents.Single(); Assert.That(evt.EventType, Is.EqualTo("SampleAggregateCreated")); Assert.That((evt.GetEvent() as DomainEvent).AggregateId, Is.EqualTo(aggregateId)); Assert.That((evt.GetEvent() as DomainEvent).Context["test.with.dot"], Is.EqualTo("BLAH")); }
public void can_reuse_repository_with_same_aggregate() { var sampleAggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>( new SampleAggregate.State(), sampleAggregateId ); aggregate.Create(); _sut.Save(aggregate, Guid.NewGuid(), null); aggregate.Touch(); _sut.Save(aggregate, Guid.NewGuid(), null); var stream = _eventStore.OpenStream("Jarvis", sampleAggregateId, int.MinValue, int.MaxValue); Assert.IsNotNull(stream); Assert.AreEqual(2, stream.CommittedEvents.Count); }
public async Task verify_headers_with_null_value() { SampleAggregateId id = GenerateId(); Dictionary <String, String> headers = new Dictionary <string, string>() { ["test"] = "blah", ["anothertest"] = null }; await SaveAggregateWithHeaders(id, headers).ConfigureAwait(false); var element = await sut.GetCommitsAfterCheckpointTokenAsync(0, new List <string>() { id }).ConfigureAwait(false); Assert.That(element, Has.Count.EqualTo(1), "We have a single commit for the aggregate"); Assert.That(element[0].Id, Is.Not.Null); Assert.That(element[0].PartitionId, Is.EqualTo(id.ToString())); Assert.That(element[0].Headers.Count, Is.EqualTo(2)); Assert.That(element[0].Headers["test"], Is.EqualTo("blah")); Assert.That(element[0].Headers["anothertest"], Is.EqualTo(null)); }
public void verify_single_cached_aggregate_repository_tolerance_to_domain_exception() { var id = new SampleAggregateId(1); //First call, everything is ok. Int32 stateCount; SampleAggregate aggregate; using (var repo = _aggregateCachedRepositoryFactory.Create <SampleAggregate>(id)) { aggregate = repo.Aggregate; aggregate.Create(); aggregate.Touch(); repo.Save(Guid.NewGuid(), updateHeaders => { }); stateCount = aggregate.InternalState.TouchCount; } try { //second call, methdo that throws exception using (var repo = _aggregateCachedRepositoryFactory.Create <SampleAggregate>(id)) { Assert.That(Object.ReferenceEquals(repo.Aggregate, aggregate), "Cache is not working"); aggregate = repo.Aggregate; aggregate.Create(); aggregate.TouchWithThrow(); //this throws repo.Save(Guid.NewGuid(), updateHeaders => { }); } } catch (Exception) { //Ignore the exception } //now I want the repository to be fresh with new aggregate using (var repo = _aggregateCachedRepositoryFactory.Create <SampleAggregate>(id)) { Assert.That(repo.Aggregate.InternalState.TouchCount, Is.EqualTo(stateCount)); Assert.That(Object.ReferenceEquals(repo.Aggregate, aggregate), Is.False, "Cache should be invalidated"); } }
public void raise_exception_if_invariants_are_not_satisfied() { var sampleAggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); aggregate.Create(); aggregate.InvalidateState(); try { _sut.Save(aggregate, new Guid("135E4E5F-3D65-43AC-9D8D-8A8B0EFF8501"), null); Assert.Fail("We expect an exception"); } catch (InvariantNotSatifiedException ex) { Assert.That(ex.AggregateId, Is.EqualTo(sampleAggregateId.AsString())); } catch (Exception ex) { Assert.Fail("We expect an exception of type InvariantNotSatifiedException but we catched " + ex.GetType().Name); } }
public void verify_reloading_with_snapshot() { //create an aggregate. var sampleAggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); aggregate.Create(); for (int i = 0; i < NumberOfCommitsBeforeSnapshot; i++) { ((IAggregateEx)aggregate).ApplyEvent(new SampleAggregateTouched()); } _sut.SnapshotManager = new CachedSnapshotManager( new MongoSnapshotPersisterProvider(_db, NullLogger.Instance), new NullSnapshotPersistenceStrategy()); //this will save the snapshot _sut.Save(aggregate, new Guid("135E4E5F-3D65-43AC-9D8D-8A8B0EFF8501"), null); var discriminated = BsonSerializer.IsTypeDiscriminated(typeof(AggregateSnapshot <>)); Console.WriteLine("Discriminated: {0}", discriminated); //now reload the aggregate var reloaded = _sut.GetById <SampleAggregate>(sampleAggregateId); Assert.That(reloaded.SnapshotRestoreVersion, Is.EqualTo(51)); }