public async Task SendAsyncTransformsSimpleEvents()
        {
            var sourceEvents = new[]
            {
                new EventData(Encoding.UTF8.GetBytes("FirstValue")),
                new EventData(Encoding.UTF8.GetBytes("Second")),
                new EventData(new byte[] { 0x11, 0x22, 0x33 })
            };

            var options  = new SendOptions();
            var mock     = new ObservableSenderMock(new ClientMock(), null);
            var producer = new TrackOneEventHubProducer(_ => mock, Mock.Of <EventHubRetryPolicy>());

            await producer.SendAsync(sourceEvents, options, CancellationToken.None);

            Assert.That(mock.SendCalledWithParameters, Is.Not.Null, "The Send request should have been delegated.");

            var sentEvents = mock.SendCalledWithParameters.Events.ToArray();

            Assert.That(sentEvents.Length, Is.EqualTo(sourceEvents.Length), "The number of events sent should match the number of source events.");

            // The events should not only be structurally equivalent, the ordering of them should be preserved.  Compare the
            // sequence in order and validate that the events in each position are equivalent.

            for (var index = 0; index < sentEvents.Length; ++index)
            {
                Assert.That(TrackOneComparer.IsEventDataEquivalent(sentEvents[index], sourceEvents[index]), Is.True, $"The sequence of events sent should match; they differ at index: { index }");
            }
        }
Beispiel #2
0
        public async Task SenderIsConstructedCorrectly()
        {
            var partition = "123";
            var mock      = new ObservableSenderMock(new ClientMock(), partition);
            var sender    = new TrackOneEventSender(() => mock);

            // Invoke an operation to force the sender to be lazily instantiated.  Otherwise,
            // construction does not happen.

            await sender.SendAsync(new[] { new EventData(new byte[] { 0x12, 0x22 }) }, new EventBatchingOptions(), default);

            Assert.That(mock.ConstructedWithPartition, Is.EqualTo(partition));
        }
        public async Task SendAsyncForwardsThePartitionHashKey(string expectedHashKey)
        {
            var options = new SendOptions {
                PartitionKey = expectedHashKey
            };
            var mock     = new ObservableSenderMock(new ClientMock(), null);
            var producer = new TrackOneEventHubProducer(_ => mock, Mock.Of <EventHubRetryPolicy>());

            await producer.SendAsync(new[] { new EventData(new byte[] { 0x43 }) }, options, CancellationToken.None);

            Assert.That(mock.SendCalledWithParameters, Is.Not.Null, "The Send request should have been delegated.");

            (_, var actualHashKey) = mock.SendCalledWithParameters;
            Assert.That(actualHashKey, Is.EqualTo(expectedHashKey), "The partition hash key should have been forwarded.");
        }
        public async Task SendAsyncTransformsEventBatches()
        {
            var messages = new[]
            {
                AmqpMessage.Create(new Data {
                    Value = new ArraySegment <byte>(new byte[] { 0x11 })
                }),
                AmqpMessage.Create(new Data {
                    Value = new ArraySegment <byte>(new byte[] { 0x22 })
                }),
                AmqpMessage.Create(new Data {
                    Value = new ArraySegment <byte>(new byte[] { 0x33 })
                }),
            };

            var options = new BatchOptions {
                MaximumizeInBytes = 30
            };
            var transportBatch = new TransportBatchMock {
                Messages = messages
            };
            var batch    = new EventDataBatch(transportBatch, options);
            var mock     = new ObservableSenderMock(new ClientMock(), null);
            var producer = new TrackOneEventHubProducer(_ => mock, Mock.Of <EventHubRetryPolicy>());

            await producer.SendAsync(batch, CancellationToken.None);

            Assert.That(mock.SendCalledWithParameters, Is.Not.Null, "The Send request should have been delegated.");

            var sentEvents = mock.SendCalledWithParameters.Events.ToArray();

            Assert.That(sentEvents.Length, Is.EqualTo(messages.Length), "The number of events sent should match the number of source events.");
            Assert.That(sentEvents.Where(evt => evt.AmqpMessage == null).Any(), Is.False, "The events should have had an AMQP message populated at transform.");

            var sentMessages = sentEvents.Select(evt => evt.AmqpMessage).ToList();

            for (var index = 0; index < messages.Length; ++index)
            {
                Assert.That(sentMessages.Contains(messages[index]), $"The message at index: { index } was not part of the set that was sent.");
            }

            foreach (var message in messages)
            {
                message.Dispose();
            }
        }
        public async Task ProducerIsConstructedCorrectly()
        {
            var partition   = "123";
            var retryPolicy = Mock.Of <EventHubRetryPolicy>();
            var mock        = new ObservableSenderMock(new ClientMock(), partition);
            var producer    = new TrackOneEventHubProducer(_ => mock, retryPolicy);

            // Invoke an operation to force the producer to be lazily instantiated.  Otherwise,
            // construction does not happen.

            await producer.SendAsync(new[] { new EventData(new byte[] { 0x12, 0x22 }) }, new SendOptions(), default);

            Assert.That(mock.ConstructedWithPartition, Is.EqualTo(partition));

            var producerRetry = GetRetryPolicy(producer);

            Assert.That(producerRetry, Is.SameAs(retryPolicy), "The producer retry instance should match.");
        }
        public async Task SendAsyncTransformsComplexEvents()
        {
            var sourceEvents = new[]
            {
                new EventData(Encoding.UTF8.GetBytes("FirstValue")),
                new EventData(Encoding.UTF8.GetBytes("Second")),
                new EventData(new byte[] { 0x11, 0x22, 0x33 })
            };

            for (var index = 0; index < sourceEvents.Length; ++index)
            {
                sourceEvents[index].Properties["type"]      = typeof(TrackOneEventHubProducer).Name;
                sourceEvents[index].Properties["arbitrary"] = index;
            }

            var options  = new SendOptions();
            var mock     = new ObservableSenderMock(new ClientMock(), null);
            var producer = new TrackOneEventHubProducer(_ => mock, Mock.Of <EventHubRetryPolicy>());

            await producer.SendAsync(sourceEvents, options, CancellationToken.None);

            Assert.That(mock.SendCalledWithParameters, Is.Not.Null, "The Send request should have been delegated.");

            var sentEvents = mock.SendCalledWithParameters.Events.ToArray();

            Assert.That(sentEvents.Length, Is.EqualTo(sourceEvents.Length), "The number of events sent should match the number of source events.");

            // The events should not only be structurally equivalent, the ordering of them should be preserved.  Compare the
            // sequence in order and validate that the events in each position are equivalent.

            for (var index = 0; index < sentEvents.Length; ++index)
            {
                // If the system properties for the sent events was null, then normalize it to an empty
                // instance because the source event does not allow null.

                sentEvents[index].SystemProperties = sentEvents[index].SystemProperties ?? new TrackOne.EventData.SystemPropertiesCollection();
                Assert.That(TrackOneComparer.IsEventDataEquivalent(sentEvents[index], sourceEvents[index]), Is.True, $"The sequence of events sent should match; they differ at index: { index }");
            }
        }
        public async Task SendAsyncForwardsThePartitionHashKeyForBatches()
        {
            var messages = new[]
            {
                AmqpMessage.Create(new Data {
                    Value = new ArraySegment <byte>(new byte[] { 0x11 })
                }),
                AmqpMessage.Create(new Data {
                    Value = new ArraySegment <byte>(new byte[] { 0x22 })
                }),
                AmqpMessage.Create(new Data {
                    Value = new ArraySegment <byte>(new byte[] { 0x33 })
                }),
            };

            var expectedHashKey = "TestKEy";
            var options         = new BatchOptions {
                MaximumizeInBytes = 30, PartitionKey = expectedHashKey
            };
            var transportBatch = new TransportBatchMock {
                Messages = messages
            };
            var batch    = new EventDataBatch(transportBatch, options);
            var mock     = new ObservableSenderMock(new ClientMock(), null);
            var producer = new TrackOneEventHubProducer(_ => mock, Mock.Of <EventHubRetryPolicy>());

            await producer.SendAsync(batch, CancellationToken.None);

            Assert.That(mock.SendCalledWithParameters, Is.Not.Null, "The Send request should have been delegated.");

            (_, var actualHashKey) = mock.SendCalledWithParameters;
            Assert.That(actualHashKey, Is.EqualTo(expectedHashKey), "The partition hash key should have been forwarded.");

            foreach (var message in messages)
            {
                message.Dispose();
            }
        }
        public async Task CloseAsyncDoesNotDelegateIfTheSenderWasNotCreated()
        {
            var mock     = new ObservableSenderMock(new ClientMock(), null);
            var producer = new TrackOneEventHubProducer(_ => mock, Mock.Of <EventHubRetryPolicy>());

            await producer.CloseAsync(default);
Beispiel #9
0
        public async Task CloseAsyncDoesNotDelegateIfTheSenderWasNotCreated()
        {
            var mock   = new ObservableSenderMock(new ClientMock(), null);
            var sender = new TrackOneEventSender(() => mock);

            await sender.CloseAsync(default);