Exemple #1
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 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 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 ConstructorSetsTheMaximumSize()
        {
            var maximumSize = 9943;
            var options     = new CreateBatchOptions {
                MaximumSizeInBytes = maximumSize
            };

            var mockConverter = new InjectableMockConverter
            {
                CreateBatchFromEventsHandler = (_e, _p) => Mock.Of <AmqpMessage>()
            };

            var batch = new AmqpEventBatch(mockConverter, options);

            Assert.That(batch.MaximumSizeInBytes, Is.EqualTo(maximumSize));
        }
        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.");
                }
            }
        }
Exemple #9
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.");
        }
Exemple #10
0
        public void ConstructorInitializesTheSizeToABatchEnvelope()
        {
            var batchEnvelopeSize = 767;
            var mockMessage       = new Mock <AmqpMessage>();
            var mockConverter     = new InjectableMockConverter();

            mockConverter.CreateBatchFromEventsHandler = (_e, _p) => mockMessage.Object;

            mockMessage
            .Setup(message => message.SerializedMessageSize)
            .Returns(batchEnvelopeSize);

            var batch = new AmqpEventBatch(mockConverter, new BatchOptions {
                MaximumizeInBytes = 27
            });

            Assert.That(batch.SizeInBytes, Is.EqualTo(batchEnvelopeSize));
        }
Exemple #11
0
        public void AsEnumerableValidatesTheTypeParameter()
        {
            var options = new BatchOptions {
                MaximumizeInBytes = 5000
            };
            var mockEnvelope  = new Mock <AmqpMessage>();
            var mockConverter = new InjectableMockConverter();

            mockConverter.CreateBatchFromEventsHandler = (_e, _p) => mockEnvelope.Object;

            mockEnvelope
            .Setup(message => message.SerializedMessageSize)
            .Returns(0);

            var batch = new AmqpEventBatch(mockConverter, options);

            Assert.That(() => batch.AsEnumerable <EventData>(), Throws.InstanceOf <FormatException>());
        }
        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.");
            }
        }
Exemple #13
0
        public void DisposeClearsTheSize()
        {
            var mockMessage   = new Mock <AmqpMessage>();
            var mockConverter = new InjectableMockConverter();

            mockConverter.CreateBatchFromEventsHandler = (_e, _p) => mockMessage.Object;

            mockMessage
            .Setup(message => message.SerializedMessageSize)
            .Returns(9959);

            var batch = new AmqpEventBatch(mockConverter, new BatchOptions {
                MaximumizeInBytes = 99
            });

            batch.Dispose();

            Assert.That(batch.SizeInBytes, Is.EqualTo(0));
        }
Exemple #14
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);
        }
Exemple #15
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.");
        }
Exemple #16
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);
        }
 /// <summary>
 ///   Gets set of batch options that a <see cref="AmqpEventBatch" /> is using
 ///   by accessing its private field.
 /// </summary>
 ///
 /// <param name="batch">The batch to retrieve the source policy from.</param>
 ///
 /// <returns>The batch options.</returns>
 ///
 private static CreateBatchOptions GetEventBatchOptions(AmqpEventBatch batch) =>
 (CreateBatchOptions)
 typeof(AmqpEventBatch)
 .GetProperty("Options", BindingFlags.Instance | BindingFlags.NonPublic)
 .GetValue(batch);
Exemple #18
0
 /// <summary>
 ///   Reads the size reserved for AMQP message overhead in a batch using its private field.
 /// </summary>
 ///
 /// <param name="instance">The instance to consider.</param>
 ///
 /// <returns>The reserved size of the batch.</returns>
 ///
 private static long GetReservedSize(AmqpEventBatch instance) =>
 (long)
 typeof(AmqpEventBatch)
 .GetField("ReservedSize", BindingFlags.Instance | BindingFlags.NonPublic)
 .GetValue(instance);