Пример #1
0
        public async Task ShouldNotPublishToPoisonQueueWhenMessageIsHandled()
        {
            var handled = false;

            var context = MockPartitionContext.CreateWithNoopCheckpoint("1");

            var events = new[] { new EventData() };

            var resovler = new MockMessageHandlerResolver(
                (body, headers) =>
            {
                handled = true;
                return(Task.FromResult <object>(null));
            });

            var poisonHandler = (MockPoisonMessageHandler)DependencyResolverFactory
                                .GetResolver()
                                .GetService(typeof(IPoisonMessageHandler));

            var processor = new EventProcessor(resovler, new MockCircuitBreaker(), 1, "test", Mock.Of <IDispatcherInstrumentationPublisher>());

            await processor.ProcessEventsAsync(context, events);

            Assert.True(handled);
            Assert.False(
                poisonHandler.Messages.Any(),
                String.Format("Expected poison handler to have no messages; count = {0}",
                              poisonHandler.Messages.Count()));
        }
Пример #2
0
        public async Task ShouldProcessMessagesConcurrently()
        {
            const int Concurrency  = 4;
            const int MessageCount = 4;
            const int MsPerMessage = 300;

            var context = MockPartitionContext.CreateWithNoopCheckpoint("1");

            var events = Enumerable
                         .Range(0, MessageCount)
                         .Select(id => new EventData())
                         .ToArray();

            var resovler = new MockMessageHandlerResolver(
                async(body, headers) => { await Task.Delay(TimeSpan.FromMilliseconds(MsPerMessage)); });

            var processor = new EventProcessor(resovler, new MockCircuitBreaker(), Concurrency, "test", Mock.Of <IDispatcherInstrumentationPublisher>());

            var sw = Stopwatch.StartNew();
            await processor.ProcessEventsAsync(context, events);

            sw.Stop();

            Assert.True(sw.Elapsed < TimeSpan.FromMilliseconds(MsPerMessage * MessageCount));
            Assert.True(sw.Elapsed >= TimeSpan.FromMilliseconds(MsPerMessage));
        }
Пример #3
0
        public async Task ShouldPublishToPoisonQueueWhenHandlerThrows()
        {
            var context = MockPartitionContext.CreateWithNoopCheckpoint("1");

            var attemptedToResolveHandler = false;

            var events = new[] { new EventData() };

            var resolver = new MockMessageHandlerResolver(
                async(body, headers) =>
            {
                attemptedToResolveHandler = true;
                await Task.Yield();
                throw new Exception("This message was bad.");
            });

            var poisonHandler = (MockPoisonMessageHandler)DependencyResolverFactory
                                .GetResolver()
                                .GetService(typeof(IPoisonMessageHandler));

            var processor = new EventProcessor(resolver, new MockCircuitBreaker(), 1, "test", Mock.Of <IDispatcherInstrumentationPublisher>());

            await processor.ProcessEventsAsync(context, events);

            Assert.True(attemptedToResolveHandler);
            Assert.True(
                poisonHandler.Messages.Any(),
                String.Format("Expected poison handler to have messages; count = {0}",
                              poisonHandler.Messages.Count()));
        }
        public async Task WhenCachedBlocksHitTripLevel_ThenStallsUntilWriteOperationSucceeds()
        {
            var blocks = new List <IList <BlockData> >();
            Action <IReadOnlyCollection <BlockData>, CancellationToken> saveBlocks = (d, ct) => blocks.Add(d.ToList());

            var failWrite = true;

            _writerMock
            .Setup(w => w.WriteAsync(It.IsAny <IReadOnlyCollection <BlockData> >(), It.IsAny <CancellationToken>()))
            .Returns(() => TaskHelpers.CreateCompletedTask(!Volatile.Read(ref failWrite)))
            .Callback(saveBlocks);

            var context = MockPartitionContext.CreateWithNoopCheckpoint("0");

            await _processor.OpenAsync(context);

            // first N requests fail but go through (the first batch will not fill a frame so it won't result in a write operation)
            for (int i = 0; i < CircuitBreakerStallLevel + 1; i++)
            {
                var  batch       = new[] { CreateEventData((byte)('a' + i), MaxBlockSize - 200 - i), };
                Task processTask = _processor.ProcessEventsAsync(context, batch);

                await AssertExt.CompletesBeforeTimeoutAsync(processTask, TimeoutInterval);
            }

            // N+1th stalls and waits for cached frames to be flushed
            {
                var  batch       = new[] { CreateEventData((byte)('a' + CircuitBreakerStallLevel + 2), 10), };
                Task processTask = _processor.ProcessEventsAsync(context, batch);

                await AssertExt.DoesNotCompleteBeforeTimeoutAsync(processTask, TimeoutInterval);

                // let the write operation through
                Volatile.Write(ref failWrite, false);

                await AssertExt.CompletesBeforeTimeoutAsync(processTask, TimeoutInterval);

                // check the stalled entries were written
                var bufferedBlocks = blocks.Last();
                Assert.Equal(CircuitBreakerStallLevel, bufferedBlocks.Count);
                for (int i = 0; i < CircuitBreakerStallLevel; i++)
                {
                    var lines = GetPayloadsFromBlock(bufferedBlocks[i]);

                    Assert.Equal(1, lines.Length);
                    Assert.Equal(
                        new string((char)('a' + i), MaxBlockSize - 200 - i),
                        lines[0]);
                }
            }
        }
Пример #5
0
        public async Task WhenIncomingMessagesFailToFillABlock_ThenDoesNotWrite()
        {
            var context = MockPartitionContext.CreateWithNoopCheckpoint("0");
            await _processor.OpenAsync(context);

            await _processor.ProcessEventsAsync(
                context,
                new[]
            {
                CreateEventData((byte)'a', 100),
                CreateEventData((byte)'b', 200),
                CreateEventData((byte)'c', 300),
            });

            _writerMock.Verify(
                w => w.WriteAsync(It.IsAny <IReadOnlyCollection <BlockData> >(), It.IsAny <CancellationToken>()),
                Times.Never());
        }
        public async Task ProcessEventsAsyncSendsEventDataToWriter()
        {
            var context = MockPartitionContext.CreateWithNoopCheckpoint("0");
            await _processor.OpenAsync(context);

            var eventData = new EventData(Encoding.UTF8.GetBytes("{ \"property1\": \"value1\"}"));

            var eventDataArray = new[]
            {
                eventData
            };

            await _processor.ProcessEventsAsync(context, eventDataArray);

            _writerMock.Verify(
                w => w.WriteAsync(It.Is <List <EventData> >(p => p.Contains(eventData)), It.IsAny <CancellationToken>()),
                Times.Once);
        }
        public async Task BuildingIdPropertyPopulatedFromLookupService()
        {
            _lookupServiceMock.Setup(service => service.GetBuildingId("123")).Returns(() => "456");
            var context = MockPartitionContext.CreateWithNoopCheckpoint("0");
            await _processor.OpenAsync(context);

            var eventData = new EventData(Encoding.UTF8.GetBytes("{ \"DeviceId\": \"123\"}"));

            var eventDataArray = new[]
            {
                eventData
            };

            await _processor.ProcessEventsAsync(context, eventDataArray);

            _writerMock.Verify(
                w => w.WriteAsync(It.Is <List <EventData> >(p => p.First().Properties["BuildingId"] as string == "456"), It.IsAny <CancellationToken>()),
                Times.Once);
        }
        public async Task WhenCachedBlocksRemainBelowTripLevel_ThenDoesNotStall()
        {
            var blocks = new List <IList <BlockData> >();
            Action <IReadOnlyCollection <BlockData>, CancellationToken> saveBlocks = (d, ct) => blocks.Add(d.ToList());

            _writerMock
            .Setup(w => w.WriteAsync(It.IsAny <IReadOnlyCollection <BlockData> >(), It.IsAny <CancellationToken>()))
            .Returns(() => TaskHelpers.CreateCompletedTask(false))
            .Callback(saveBlocks);

            var context = MockPartitionContext.CreateWithNoopCheckpoint("0");

            await _processor.OpenAsync(context);

            for (int i = 0; i < CircuitBreakerStallLevel; i++)
            {
                var  batch       = new[] { CreateEventData((byte)('a' + i), MaxBlockSize - 200 - i), };
                Task processTask = _processor.ProcessEventsAsync(context, batch);

                await AssertExt.CompletesBeforeTimeoutAsync(processTask, TimeoutInterval);
            }
        }