public void TryAddDoesNotAcceptAnEventBiggerThanTheMaximumSize() { var maximumSize = 50; var batchEnvelopeSize = 0; var options = new CreateBatchOptions { MaximumSizeInBytes = maximumSize }; var mockEnvelope = new Mock <AmqpMessage>(); var mockEvent = new Mock <AmqpMessage>(); var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object, CreateMessageFromEventHandler = (_e, _p) => mockEvent.Object }; mockEnvelope .Setup(message => message.SerializedMessageSize) .Returns(batchEnvelopeSize); mockEvent .Setup(message => message.SerializedMessageSize) .Returns(maximumSize); var batch = new AmqpEventBatch(mockConverter, options); Assert.That(batch.TryAdd(new EventData(new byte[0])), Is.False, "An event of the maximum size is too large due to the reserved overhead."); }
public void TryAddAcceptsAnEventSmallerThanTheMaximumSize() { var maximumSize = 50; var eventMessageSize = 40; var options = new CreateBatchOptions { MaximumSizeInBytes = maximumSize }; var mockEnvelope = new Mock <AmqpMessage>(); var mockEvent = new Mock <AmqpMessage>(); var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object, CreateMessageFromEventHandler = (_e, _p) => mockEvent.Object }; mockEnvelope .Setup(message => message.SerializedMessageSize) .Returns(0); mockEvent .Setup(message => message.SerializedMessageSize) .Returns(eventMessageSize); var batch = new AmqpEventBatch(mockConverter, options); Assert.That(batch.TryAdd(new EventData(new byte[0])), Is.True); }
public void TryAddSetsTheCount() { var currentIndex = -1; var options = new BatchOptions { MaximumizeInBytes = 5000 }; var eventMessages = new AmqpMessage[5]; var mockEnvelope = new Mock <AmqpMessage>(); var mockConverter = new InjectableMockConverter(); mockConverter.CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object; mockConverter.CreateMessageFromEventHandler = (_e, _p) => eventMessages[++currentIndex]; mockEnvelope .Setup(message => message.SerializedMessageSize) .Returns(0); for (var index = 0; index < eventMessages.Length; ++index) { eventMessages[index] = AmqpMessage.Create(new Data { Value = new ArraySegment <byte>(new byte[] { 0x66 }) }); } // Add the messages to the batch; all should be accepted. var batch = new AmqpEventBatch(mockConverter, options); for (var index = 0; index < eventMessages.Length; ++index) { Assert.That(batch.TryAdd(new EventData(new byte[0])), Is.True, $"The addition for index: { index } should fit and be accepted."); } Assert.That(batch.Count, Is.EqualTo(eventMessages.Length), "The count should have been set when the batch was updated."); }
public void TryAddAcceptEventsUntilTheMaximumSizeIsReached() { var currentIndex = -1; var maximumSize = 50; var options = new CreateBatchOptions { MaximumSizeInBytes = maximumSize }; var eventMessages = new AmqpMessage[5]; var mockEnvelope = new Mock <AmqpMessage>(); var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object, CreateMessageFromEventHandler = (_e, _p) => eventMessages[++currentIndex] }; mockEnvelope .Setup(message => message.SerializedMessageSize) .Returns(0); // Fill the set of messages with ones that should fit, reserving the last spot // for one that will deterministically be rejected. for (var index = 0; index < eventMessages.Length; ++index) { var size = (index == eventMessages.Length - 1) ? maximumSize : (maximumSize / eventMessages.Length) - 8; var message = new Mock <AmqpMessage>(); message.Setup(msg => msg.SerializedMessageSize).Returns(size); eventMessages[index] = message.Object; } var batch = new AmqpEventBatch(mockConverter, options); for (var index = 0; index < eventMessages.Length; ++index) { if (index == eventMessages.Length - 1) { Assert.That(batch.TryAdd(new EventData(new byte[0])), Is.False, "The final addition should not fit in the available space."); } else { Assert.That(batch.TryAdd(new EventData(new byte[0])), Is.True, $"The addition for index: { index } should fit and be accepted."); } } }
public void TryAddValidatesTheEvent() { var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => Mock.Of <AmqpMessage>() }; var batch = new AmqpEventBatch(mockConverter, new CreateBatchOptions { MaximumSizeInBytes = 25 }); Assert.That(() => batch.TryAdd(null), Throws.ArgumentNullException); }
public void TryAddValidatesNotDisposed() { var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => Mock.Of <AmqpMessage>() }; var batch = new AmqpEventBatch(mockConverter, new CreateBatchOptions { MaximumSizeInBytes = 25 }); batch.Dispose(); Assert.That(() => batch.TryAdd(new EventData(new byte[0])), Throws.InstanceOf <ObjectDisposedException>()); }
public void AsEnumerableReturnsTheEvents() { var currentIndex = -1; var maximumSize = 5000; var options = new CreateBatchOptions { MaximumSizeInBytes = maximumSize }; var eventMessages = new AmqpMessage[5]; var batchEvents = new EventData[5]; var mockEnvelope = new Mock <AmqpMessage>(); var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object, CreateMessageFromEventHandler = (_e, _p) => eventMessages[++currentIndex] }; mockEnvelope .Setup(message => message.SerializedMessageSize) .Returns(0); for (var index = 0; index < eventMessages.Length; ++index) { var message = new Mock <AmqpMessage>(); message.Setup(msg => msg.SerializedMessageSize).Returns(50); eventMessages[index] = message.Object; } var batch = new AmqpEventBatch(mockConverter, options); for (var index = 0; index < eventMessages.Length; ++index) { batchEvents[index] = new EventData(new byte[0]); batch.TryAdd(batchEvents[index]); } IEnumerable <EventData> batchEnumerable = batch.AsEnumerable <EventData>(); Assert.That(batchEnumerable, Is.Not.Null, "The batch enumerable should have been populated."); var batchEnumerableList = batchEnumerable.ToList(); Assert.That(batchEnumerableList.Count, Is.EqualTo(batch.Count), "The wrong number of events was in the enumerable."); for (var index = 0; index < batchEvents.Length; ++index) { Assert.That(batchEnumerableList.Contains(batchEvents[index]), $"The event at index: { index } was not in the enumerable."); } }
public void TryAddHonorStatefulFeatures(byte activeFeatures) { var maximumSize = 50; var batchEnvelopeSize = 0; var capturedSequence = default(int?); var capturedGroupId = default(long?); var capturedOwnerLevel = default(short?); var options = new CreateBatchOptions { MaximumSizeInBytes = maximumSize }; var mockEnvelope = new Mock <AmqpMessage>(); var mockEvent = new Mock <AmqpMessage>(); var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object, CreateMessageFromEventHandler = (_e, _p) => { capturedSequence = _e.PendingPublishSequenceNumber; capturedGroupId = _e.PendingProducerGroupId; capturedOwnerLevel = _e.PendingProducerOwnerLevel; return(mockEvent.Object); } }; mockEnvelope .Setup(message => message.SerializedMessageSize) .Returns(batchEnvelopeSize); mockEvent .Setup(message => message.SerializedMessageSize) .Returns(maximumSize); var batch = new AmqpEventBatch(mockConverter, options, (TransportProducerFeatures)activeFeatures); batch.TryAdd(EventGenerator.CreateEvents(1).Single()); NullConstraint generateConstraint() => ((TransportProducerFeatures)activeFeatures == TransportProducerFeatures.None) ? Is.Null : Is.Not.Null; Assert.That(capturedSequence, generateConstraint(), "The sequence was not set as expected."); Assert.That(capturedGroupId, generateConstraint(), "The group identifier was not set as expected."); Assert.That(capturedOwnerLevel, generateConstraint(), "The owner level was not set as expected."); }
public void DisposeCleansUpBatchMessages() { var currentIndex = -1; var options = new CreateBatchOptions { MaximumSizeInBytes = 5000 }; var eventMessages = new AmqpMessage[5]; var mockEnvelope = new Mock <AmqpMessage>(); var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object, CreateMessageFromEventHandler = (_e, _p) => eventMessages[++currentIndex] }; mockEnvelope .Setup(message => message.SerializedMessageSize) .Returns(0); for (var index = 0; index < eventMessages.Length; ++index) { eventMessages[index] = AmqpMessage.Create(new Data { Value = new ArraySegment <byte>(new byte[] { 0x66 }) }); } // Add the messages to the batch; all should be accepted. var batch = new AmqpEventBatch(mockConverter, options); for (var index = 0; index < eventMessages.Length; ++index) { Assert.That(batch.TryAdd(new EventData(new byte[0])), Is.True, $"The addition for index: { index } should fit and be accepted."); } // Dispose the batch and verify that each message has also been disposed. batch.Dispose(); for (var index = 0; index < eventMessages.Length; ++index) { Assert.That(() => eventMessages[index].ThrowIfDisposed(), Throws.InstanceOf <ObjectDisposedException>(), $"The message at index: { index } should have been disposed."); } }
public void TryAddHonorsTheMeasureSequenceNumber(bool measureSequenceNumber) { var maximumSize = 50; var batchEnvelopeSize = 0; var capturedSequence = default(int?); var options = new CreateBatchOptions { MaximumSizeInBytes = maximumSize }; var mockEnvelope = new Mock <AmqpMessage>(); var mockEvent = new Mock <AmqpMessage>(); var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object, CreateMessageFromEventHandler = (_e, _p) => { capturedSequence = _e.PendingPublishSequenceNumber; return(mockEvent.Object); } }; mockEnvelope .Setup(message => message.SerializedMessageSize) .Returns(batchEnvelopeSize); mockEvent .Setup(message => message.SerializedMessageSize) .Returns(maximumSize); var batch = new AmqpEventBatch(mockConverter, options, measureSequenceNumber); batch.TryAdd(EventGenerator.CreateEvents(1).Single()); var expectationConstraint = (measureSequenceNumber) ? Is.Not.Null : Is.Null; Assert.That(capturedSequence, expectationConstraint); }
public void TryAddResetsPublishingState() { var maximumSize = 50; var batchEnvelopeSize = 0; var capturedEvent = default(EventData); var options = new CreateBatchOptions { MaximumSizeInBytes = maximumSize }; var mockEnvelope = new Mock <AmqpMessage>(); var mockEvent = new Mock <AmqpMessage>(); var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object, CreateMessageFromEventHandler = (_e, _p) => { capturedEvent = _e; return(mockEvent.Object); } }; mockEnvelope .Setup(message => message.SerializedMessageSize) .Returns(batchEnvelopeSize); mockEvent .Setup(message => message.SerializedMessageSize) .Returns(maximumSize); var batch = new AmqpEventBatch(mockConverter, options, TransportProducerFeatures.IdempotentPublishing); batch.TryAdd(EventGenerator.CreateEvents(1).Single()); Assert.That(capturedEvent.PublishedSequenceNumber, Is.Null, "The final sequence should not have been set."); Assert.That(capturedEvent.PendingPublishSequenceNumber, Is.Null, "The pending sequence was not cleared."); Assert.That(capturedEvent.PendingProducerGroupId, Is.Null, "The group identifier was not cleared."); Assert.That(capturedEvent.PendingProducerOwnerLevel, Is.Null, "The owner level was not cleared."); }
public void TryAddRemovesTheMeasureSequenceNumber() { var maximumSize = 50; var batchEnvelopeSize = 0; var capturedEvent = default(EventData); var options = new CreateBatchOptions { MaximumSizeInBytes = maximumSize }; var mockEnvelope = new Mock <AmqpMessage>(); var mockEvent = new Mock <AmqpMessage>(); var mockConverter = new InjectableMockConverter { CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object, CreateMessageFromEventHandler = (_e, _p) => { capturedEvent = _e; return(mockEvent.Object); } }; mockEnvelope .Setup(message => message.SerializedMessageSize) .Returns(batchEnvelopeSize); mockEvent .Setup(message => message.SerializedMessageSize) .Returns(maximumSize); var batch = new AmqpEventBatch(mockConverter, options, true); batch.TryAdd(EventGenerator.CreateEvents(1).Single()); Assert.That(capturedEvent.PublishedSequenceNumber, Is.Null); }