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);
        }
示例#3
0
        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.");
            }
        }
示例#8
0
        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.");
            }
        }
示例#10
0
        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);
        }
示例#11
0
        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.");
        }
示例#12
0
        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);
        }