public void GivenAMongoMessageDataRepository_WhenPuttingMessageDataWithExpiration() { var db = new MongoClient().GetDatabase("messagedatastoretests"); _bucket = new GridFSBucket(db); _now = DateTime.UtcNow; SystemDateTime.Set(_now); var fixture = new Fixture(); var resolver = new Mock <IMongoMessageUriResolver>(); resolver.Setup(x => x.Resolve(It.IsAny <ObjectId>())) .Callback((ObjectId id) => _id = id); var nameCreator = new Mock <IFileNameCreator>(); nameCreator.Setup(x => x.CreateFileName()) .Returns(fixture.Create <string>()); var sut = new MongoMessageDataRepository(resolver.Object, _bucket, nameCreator.Object); _expectedTtl = TimeSpan.FromHours(1); using (var stream = new MemoryStream(fixture.Create <byte[]>())) { sut.Put(stream, _expectedTtl).GetAwaiter().GetResult(); } }
public void should_not_ack_message_with_other_peer_id() { _batchSize = 100; _delay = 2.Seconds(); var signal = new ManualResetEventSlim(); var persistedEntries = new List <MatcherEntry>(); _storeBatchFunc = entries => { persistedEntries.AddRange(entries); signal.Set(); }; using (SystemDateTime.PauseTime()) { _matcher.Start(); var messageId = MessageId.NextId(); _matcher.EnqueueMessage(_peerId, messageId, new MessageTypeId("X"), new byte[0]); _matcher.EnqueueMessage(_otherPeerId, messageId, new MessageTypeId("X"), new byte[0]); _matcher.EnqueueAck(_otherPeerId, messageId); SystemDateTime.Set(utcNow: SystemDateTime.UtcNow.Add(_delay.Value)); var persistCalled = signal.Wait(1.Second()); persistCalled.ShouldBeTrue(); var persistedEntry = persistedEntries.ExpectedSingle(); persistedEntry.PeerId.ShouldEqual(_peerId); } }
public void should_timeout_if_any_debug_service_does_not_respond_in_time() { SetupPeerRepository(_debugPersistentAlivePeer, _debugTransientAlivePeer); SetupPeerResponse(_debugPersistentAlivePeer.PeerId, false, false); SetupPeerResponse(_debugTransientAlivePeer.PeerId, false, false); using (SystemDateTime.PauseTime()) { var startTime = SystemDateTime.UtcNow; var firstPingTimestampUtc = startTime; _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand(), new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_debugPeerTimeout - 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand(), new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_debugPeerTimeout + 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly( new UnregisterPeerCommand(_debugTransientAlivePeer.Peer, firstPingTimestampUtc), new UnregisterPeerCommand(_debugPersistentAlivePeer.Peer, firstPingTimestampUtc) ); } }
public void should_not_decommission_the_persistence() { SetupPeerRepository(_persistencePeer); SetupPeerResponse(_persistencePeer.PeerId, false, false); using (SystemDateTime.PauseTime()) { var startTime = SystemDateTime.UtcNow; var persistenceDownDetectedCount = 0; _detector.PersistenceDownDetected += () => persistenceDownDetectedCount++; _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand()); SystemDateTime.Set(startTime.AddSeconds(_transientPeerTimeout - 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand(), new PingPeerCommand()); SystemDateTime.Set(startTime.AddSeconds(_transientPeerTimeout + 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand(), new PingPeerCommand()); persistenceDownDetectedCount.ShouldEqual(1); } }
public void should_raise_PingMissed_before_a_peer_is_marked_as_timed_out() { SetupPeerRepository(_persistentAlivePeer, _transientAlivePeer0); SetupPeerResponse(_transientAlivePeer0.PeerId, true, true); SetupPeerResponse(_persistentAlivePeer.PeerId, false, false); using (SystemDateTime.PauseTime()) { var missedPings = new List <PeerEvent>(); _detector.PingTimeout += (peer, timestamp) => missedPings.Add(new PeerEvent(peer, timestamp)); var startTime = SystemDateTime.UtcNow; _detector.DetectDeadPeers(); SystemDateTime.Set(startTime.Add(_pingInterval - 1.Second())); _detector.DetectDeadPeers(); missedPings.Count.ShouldEqual(0); SystemDateTime.Set(startTime.Add(_pingInterval + 1.Second())); _detector.DetectDeadPeers(); missedPings.Count.ShouldEqual(1); missedPings.First().PeerId.ShouldEqual(_persistentAlivePeer.PeerId); SystemDateTime.Set(startTime.Add(_pingInterval + _pingInterval + 1.Second())); _detector.DetectDeadPeers(); missedPings.Count.ShouldEqual(2); missedPings.All(evt => evt.PeerId == _persistentAlivePeer.PeerId).ShouldBeTrue(); } }
public void should_timeout_if_a_persistent_service_does_not_respond_in_time() { SetupPeerRepository(_persistentAlivePeer, _transientAlivePeer0); SetupPeerResponse(_transientAlivePeer0.PeerId, true, true); SetupPeerResponse(_persistentAlivePeer.PeerId, false, false); using (SystemDateTime.PauseTime()) { var startTime = SystemDateTime.UtcNow; var firstPingTimestampUtc = startTime; _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand(), new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_transientPeerTimeout - 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand(), new PingPeerCommand()); _bus.ClearMessages(); var retryTimestamp = startTime.AddSeconds(_persistentPeerTimeout - 1); SystemDateTime.Set(retryTimestamp); _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand(), new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_persistentPeerTimeout + 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new MarkPeerAsNotRespondingCommand(_persistentAlivePeer.Peer.Id, firstPingTimestampUtc)); } }
public void should_not_decommission_directory_peer() { SetupPeerRepository(_directoryPeer, _transientAlivePeer0); SetupPeerResponse(_transientAlivePeer0.PeerId, false, false); SetupPeerResponse(_directoryPeer.PeerId, false, false); using (SystemDateTime.PauseTime()) { var startTime = SystemDateTime.UtcNow; var firstPingTimestampUtc = startTime; _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_transientPeerTimeout - 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_transientPeerTimeout + 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new UnregisterPeerCommand(_transientAlivePeer0.Peer, firstPingTimestampUtc)); } }
public void should_not_timeout_if_a_persistent_service_responds_to_the_second_ping() { SetupPeerRepository(_persistentAlivePeer, _transientAlivePeer0); SetupPeerResponse(_transientAlivePeer0.PeerId, true, true); SetupPeerResponse(_persistentAlivePeer.PeerId, false, true); using (SystemDateTime.PauseTime()) { var startTime = SystemDateTime.UtcNow; _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand(), new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_transientPeerTimeout - 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand(), new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_persistentPeerTimeout - 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand(), new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_persistentPeerTimeout + 1)); _detector.DetectDeadPeers(); _bus.ExpectNothing();; } }
public void should_mark_as_not_responding_if_a_transient_peer_in_the_whitelist_does_not_respond_in_time(string peerNotToDecommission) { _peersNotToDecommission = new[] { peerNotToDecommission }; SetupPeerRepository(_transientAlivePeer0); SetupPeerResponse(_transientAlivePeer0.PeerId, false, false); using (SystemDateTime.PauseTime()) { var startTime = SystemDateTime.UtcNow; var firstPingTimestampUtc = startTime; _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_transientPeerTimeout - 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new PingPeerCommand()); _bus.ClearMessages(); SystemDateTime.Set(startTime.AddSeconds(_transientPeerTimeout + 1)); _detector.DetectDeadPeers(); _bus.ExpectExactly(new MarkPeerAsNotRespondingCommand(_transientAlivePeer0.Peer.Id, firstPingTimestampUtc)); } }
public void should_save_entries_with_different_timestamps_in_different_batches() { var persistedEntries = new List <MatcherEntry>(); _storeBatchFunc = entries => persistedEntries.AddRange(entries); _delay = 5.Seconds(); _batchSize = 10; using (SystemDateTime.PauseTime()) { // messages for batch 1 _matcher.EnqueueMessage(_peerId, MessageId.NextId(), new MessageTypeId("Abc.X"), new byte[0]); _matcher.EnqueueMessage(_peerId, MessageId.NextId(), new MessageTypeId("Abc.X"), new byte[0]); SystemDateTime.Set(utcNow: SystemDateTime.UtcNow.Add(4.Seconds())); // message for batch 2 _matcher.EnqueueMessage(_peerId, MessageId.NextId(), new MessageTypeId("Abc.X"), new byte[0]); SystemDateTime.Set(utcNow: SystemDateTime.UtcNow.Add(3.Seconds())); _matcher.Start(); Wait.Until(() => persistedEntries.Count == 2, 500.Milliseconds()); SystemDateTime.Set(utcNow: SystemDateTime.UtcNow.Add(2.Seconds())); Wait.Until(() => persistedEntries.Count == 3, 500.Milliseconds()); } }
public GroupEventsWebhookFactoryTests() { _now = DateTime.UtcNow; SystemDateTime.Set(_now); _factory = new GroupEventsWebhookFactory(); _fixture = new Fixture(); _fixture.Customizations.Add(new UtcRandomDateTimeSequenceGenerator()); }
public static IDisposable PauseIdGenerationAtDate(DateTime utcDatetime) { var systemDatetimeContext = SystemDateTime.Set(utcNow: utcDatetime); var messageIdContext = PauseIdGeneration(); return(new DisposableAction(() => { messageIdContext.Dispose(); systemDatetimeContext.Dispose(); })); }
public void should_set_time_with_fake_local_time() { var fakeNow = new DateTime(1995, 1, 1, 1, 2, 3, 4, DateTimeKind.Local); using (SystemDateTime.Set(fakeNow)) { SystemDateTime.Now.ShouldEqual(fakeNow); SystemDateTime.UtcNow.ShouldEqual(fakeNow.ToUniversalTime()); SystemDateTime.Today.ShouldEqual(fakeNow.Date); } }
public void should_set_time_with_fake_utc_time() { var fakeUtcNow = new DateTime(1995, 1, 1, 1, 2, 3, 4, DateTimeKind.Utc); using (SystemDateTime.Set(null, fakeUtcNow)) { SystemDateTime.Now.ShouldEqual(fakeUtcNow.ToLocalTime()); SystemDateTime.UtcNow.ShouldEqual(fakeUtcNow); SystemDateTime.Today.ShouldEqual(fakeUtcNow.ToLocalTime().Date); } }
public void should_reset_time_when_set() { var fakeNow = new DateTime(1995, 1, 1, 1, 2, 3, 4, DateTimeKind.Local); using (SystemDateTime.Set(fakeNow)) { SystemDateTime.Reset(); SystemDateTime.UtcNow.ShouldBeGreaterThan(fakeNow); SystemDateTime.Now.ShouldBeGreaterThan(fakeNow); } }
public async Task register_persist_state_and_advertise() { using (SystemDateTime.PauseTime()) using (SystemDateTime.Set(SystemDateTime.Now)) { var peerDescriptor = _self.ToPeerDescriptor(false, typeof(FakeCommand)); await _peerDirectory.RegisterAsync(_bus, peerDescriptor.Peer, peerDescriptor.Subscriptions); _bus.ExpectExactly(new PeerStarted(peerDescriptor)); _repositoryMock.Verify(x => x.AddOrUpdatePeer(It.Is <PeerDescriptor>(descriptor => peerDescriptor.DeepCompare(descriptor)))); } }
public void Enroll_Student_AddsEnrollmentWithCreatedDate() { //Arrange var course = new Course(); var student = new Student(); var expectedDate = DateTime.Now; SystemDateTime.Set(expectedDate); //Act course.Enroll(student); var enrollment = course.GetEnrollments().Single(); //Assert Assert.AreEqual(expectedDate, enrollment.Created); }
public async Task unregister_should_persist_state_and_advertise() { using (SystemDateTime.PauseTime()) using (SystemDateTime.Set(SystemDateTime.Now)) { var peerDescriptor = _self.ToPeerDescriptor(true, typeof(FakeCommand)); _repositoryMock.Setup(repo => repo.Get(It.Is <PeerId>(id => peerDescriptor.Peer.Id.Equals(id)))).Returns(peerDescriptor); await _peerDirectory.RegisterAsync(_bus, peerDescriptor.Peer, peerDescriptor.Subscriptions); await _peerDirectory.UnregisterAsync(_bus); _bus.Expect(new PeerStopped(peerDescriptor.Peer)); _repositoryMock.Verify(repo => repo.Get(It.Is <PeerId>(id => peerDescriptor.Peer.Id.Equals(id)))); _repositoryMock.Verify(repo => repo.AddOrUpdatePeer(It.Is <PeerDescriptor>(descriptor => peerDescriptor.DeepCompare(descriptor)))); } }
public async Task should_store_messages_in_different_buckets() { MessageId.ResetLastTimestamp(); var firstTime = DateTime.Now; using (SystemDateTime.Set(firstTime)) using (MessageId.PauseIdGenerationAtDate(firstTime)) { var peerId = new PeerId("Abc.Testing.Target"); var firstMessageId = MessageId.NextId(); await _storage.Write(new[] { MatcherEntry.Message(peerId, firstMessageId, new MessageTypeId("Abc.Message"), new byte[] { 0x01, 0x02, 0x03 }) }); var secondTime = firstTime.AddHours(1); SystemDateTime.Set(secondTime); MessageId.PauseIdGenerationAtDate(secondTime); var secondMessageId = MessageId.NextId(); await _storage.Write(new[] { MatcherEntry.Message(peerId, secondMessageId, new MessageTypeId("Abc.OtherMessage"), new byte[] { 0x04, 0x05, 0x06 }) }); var persistedMessages = DataContext.PersistentMessages.Execute().OrderBy(x => x.UniqueTimestampInTicks).ToList(); // Results are only ordered withing a partition persistedMessages.Count.ShouldEqual(2); persistedMessages.First().ShouldHaveSamePropertiesAs(new PersistentMessage { BucketId = BucketIdHelper.GetBucketId(firstTime), PeerId = peerId.ToString(), IsAcked = false, MessageId = firstMessageId.Value, TransportMessage = new byte[] { 0x01, 0x02, 0x03 }, UniqueTimestampInTicks = firstTime.Ticks }); persistedMessages.Last().ShouldHaveSamePropertiesAs(new PersistentMessage { BucketId = BucketIdHelper.GetBucketId(secondTime), PeerId = peerId.ToString(), IsAcked = false, MessageId = secondMessageId.Value, TransportMessage = new byte[] { 0x04, 0x05, 0x06 }, UniqueTimestampInTicks = secondTime.Ticks }); } }
public void Enroll_Student_AddsEnrollmentWithCreatedDate() { //Arrange var course = new Course(); var service = GetCourseService(course); var student = new Student(); var expectedCreated = DateTime.UtcNow; SystemDateTime.Set(expectedCreated); //Act service.Enroll(student); //Assert var enrollment = service.GetEnrollments().Single(); Assert.AreEqual(expectedCreated, enrollment.Created); }
public void should_use_specified_timestamp_to_remove_dynamic_subscriptions() { var peer = _peer1.ToPeerDescriptor(true); var subscriptionsForType = CreateSubscriptionsForType <FakeCommand>(new BindingKey("X")); _repository.AddOrUpdatePeer(peer); _repository.AddDynamicSubscriptionsForTypes(peer.PeerId, peer.TimestampUtc.Value.AddMilliseconds(1), new[] { subscriptionsForType }); using (SystemDateTime.Set(utcNow: DateTime.UtcNow.AddHours(1))) { _repository.RemoveAllDynamicSubscriptionsForPeer(peer.PeerId, peer.TimestampUtc.Value.AddMilliseconds(2)); } _repository.AddDynamicSubscriptionsForTypes(peer.PeerId, peer.TimestampUtc.Value.AddMilliseconds(3), new[] { subscriptionsForType }); var fetched = _repository.GetPeers().ExpectedSingle(); fetched.Subscriptions.ShouldNotBeEmpty(); }
public void should_not_ping_until_the_ping_interval_elapsed() { var startTime = SystemDateTime.UtcNow; using (SystemDateTime.Set(utcNow: startTime)) { _detector.DetectDeadPeers(); } using (SystemDateTime.Set(startTime + _pingInterval - 1.Second())) { _detector.DetectDeadPeers(); } _bus.ExpectExactly(_transientAlivePeer0.PeerId, new PingPeerCommand()); _bus.ExpectExactly(_transientAlivePeer1.PeerId, new PingPeerCommand()); _bus.ExpectExactly(_persistentAlivePeer.PeerId, new PingPeerCommand()); _bus.ExpectExactly(_debugPersistentAlivePeer.PeerId, new PingPeerCommand()); _bus.ExpectExactly(_debugTransientAlivePeer.PeerId, new PingPeerCommand()); }
public void should_disconnect_peer_socket_of_a_stopped_peer_after_some_time() { var transport1 = CreateAndStartZmqTransport(peerId: "Abc.Testing.1"); var peer1 = new Peer(transport1.PeerId, transport1.InboundEndPoint); var transport2 = CreateAndStartZmqTransport(peerId: "Abc.Testing.2"); var peer2 = new Peer(transport2.PeerId, transport2.InboundEndPoint); transport1.Send(new FakeCommand(0).ToTransportMessage(), new[] { peer2 }); transport2.Send(new FakeCommand(0).ToTransportMessage(), new[] { peer1 }); Wait.Until(() => transport1.OutboundSocketCount == 1, 500.Milliseconds()); Wait.Until(() => transport2.OutboundSocketCount == 1, 500.Milliseconds()); transport2.Stop(); using (SystemDateTime.Set(utcNow: SystemDateTime.UtcNow.Add(30.Seconds()))) { Wait.Until(() => transport1.OutboundSocketCount == 0, 1000.Milliseconds()); } }
public void should_use_transcient_timeout() { _configurationMock.SetupGet(x => x.TransientPeerPingTimeout).Returns(5.Seconds()); _bus.HandlerExecutor = new TestBus.DoNotReplyHandlerExecutor(); _entry.Descriptor.IsPersistent = false; var pingTimestamp = SystemDateTime.UtcNow; _entry.Ping(pingTimestamp); using (SystemDateTime.Set(pingTimestamp.AddSeconds(4))) { _entry.HasReachedTimeout().ShouldBeFalse(); } using (SystemDateTime.Set(pingTimestamp.AddSeconds(6))) { _entry.HasReachedTimeout().ShouldBeTrue(); } }
private List <TransportMessage> InsertMessagesInThePast(DateTime refDateTime, int messageCount = 11) { MessageId.ResetLastTimestamp(); // because it goes back in the past! var refTime = refDateTime.AddHours(-messageCount); var transportMessages = new List <TransportMessage>(); for (var i = 0; i < messageCount; ++i) { TransportMessage transportMessage; using (SystemDateTime.Set(refTime)) { transportMessage = new FakeCommand(i).ToTransportMessage(_anotherPeer); } transportMessages.Add(transportMessage); _insertedMessages.AddRange(transportMessage); refTime = refTime.AddHours(1); } return(transportMessages); }
public void should_wait_for_delay_before_persisting_messages() { _delay = 5.Seconds(); var persistedSignal = new ManualResetEvent(false); _storeBatchFunc = _ => persistedSignal.Set(); using (SystemDateTime.PauseTime()) { _matcher.Start(); _matcher.EnqueueMessage(_peerId, MessageId.NextId(), new MessageTypeId("Abc.X"), new byte[0]); persistedSignal.WaitOne(500.Milliseconds()).ShouldBeFalse(); SystemDateTime.Set(utcNow: SystemDateTime.UtcNow.Add(_delay.GetValueOrDefault())); persistedSignal.WaitOne(600.Milliseconds()).ShouldBeTrue(); } }
public void should_use_debug_timeout() { _configurationMock.SetupGet(x => x.PersistentPeerPingTimeout).Returns(5.Seconds()); _configurationMock.SetupGet(x => x.DebugPeerPingTimeout).Returns(500.Seconds()); _bus.HandlerExecutor = new TestBus.DoNotReplyHandlerExecutor(); _entry.Descriptor.HasDebuggerAttached = true; var pingTimestamp = SystemDateTime.UtcNow; _entry.Ping(pingTimestamp); using (SystemDateTime.Set(pingTimestamp.AddSeconds(15))) { _entry.HasReachedTimeout().ShouldBeFalse(); } using (SystemDateTime.Set(pingTimestamp.AddSeconds(501))) { _entry.HasReachedTimeout().ShouldBeTrue(); } }
public async Task should_reload_state_from_cassandra_on_initialize() { using (SystemDateTime.PauseTime()) { _peerStateRepository.UpdateNonAckMessageCount(new PeerId("PeerId"), 10); await _peerStateRepository.Save(); var oldestNonAckedMessageTimestampCaptured = SystemDateTime.UtcNow - CqlStorage.PersistentMessagesTimeToLive; using (SystemDateTime.Set(utcNow: SystemDateTime.UtcNow.Add(2.Hours()))) { var newRepo = new PeerStateRepository(DataContext); newRepo.Initialize(); var cassandraState = newRepo.ExpectedSingle(); cassandraState.PeerId.ShouldEqual(new PeerId("PeerId")); cassandraState.NonAckedMessageCount.ShouldEqual(10); cassandraState.OldestNonAckedMessageTimestampInTicks.ShouldEqual(oldestNonAckedMessageTimestampCaptured.Ticks); } } }
public void should_terminate_zmq_connection_of_a_forgotten_peer_after_some_time() { var senderTransport = CreateAndStartZmqTransport(); var receiverTransport = CreateAndStartZmqTransport(); var receiverPeer = new Peer(receiverTransport.PeerId, receiverTransport.InboundEndPoint); var message = new FakeCommand(1).ToTransportMessage(); senderTransport.Send(message, new[] { receiverPeer }); Wait.Until(() => senderTransport.OutboundSocketCount == 1, 2.Seconds()); senderTransport.OnPeerUpdated(receiverPeer.Id, PeerUpdateAction.Decommissioned); Thread.Sleep(100); senderTransport.OutboundSocketCount.ShouldEqual(1); using (SystemDateTime.Set(utcNow: SystemDateTime.UtcNow.Add(30.Seconds()))) { Wait.Until(() => senderTransport.OutboundSocketCount == 0, 1.Seconds(), "Socket should be disconnected"); } }
public void should_not_persist_message_and_ack_received_during_delay() { _batchSize = 100; _delay = 2.Seconds(); var signal = new ManualResetEventSlim(); var persistedEntries = new List <MatcherEntry>(); var persistCallCount = 0; _storeBatchFunc = entries => { var callCount = Interlocked.Increment(ref persistCallCount); if (callCount == 1) { persistedEntries.AddRange(entries); signal.Set(); } }; using (SystemDateTime.PauseTime()) { _matcher.Start(); var messageId = MessageId.NextId(); _matcher.EnqueueMessage(_peerId, messageId, new MessageTypeId("Abc.X"), new byte[0]); _matcher.EnqueueMessage(_peerId, MessageId.NextId(), new MessageTypeId("Abc.X"), new byte[0]); _matcher.EnqueueAck(_peerId, messageId); SystemDateTime.Set(utcNow: SystemDateTime.UtcNow.Add(_delay.Value)); var persistCalled = signal.Wait(1.Second()); persistCalled.ShouldBeTrue(); persistedEntries.Count.ShouldEqual(1); persistCallCount.ShouldEqual(1); } }