예제 #1
0
        public async Task ProcessEvents_MultipleDispatch_CheckpointsCorrectly(int batchCheckpointFrequency, int expected)
        {
            var partitionContext = EventHubTests.GetPartitionContext();
            var options          = new EventHubOptions
            {
                BatchCheckpointFrequency = batchCheckpointFrequency
            };

            var processor = new Mock <EventProcessorHost>(MockBehavior.Strict);

            processor.Setup(p => p.CheckpointAsync(partitionContext.PartitionId, It.IsAny <EventData>(), It.IsAny <CancellationToken>())).Returns(Task.CompletedTask);
            partitionContext.ProcessorHost = processor.Object;

            var loggerMock = new Mock <ILogger>();
            var executor   = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);

            executor.Setup(p => p.TryExecuteAsync(It.IsAny <TriggeredFunctionData>(), It.IsAny <CancellationToken>())).ReturnsAsync(new FunctionResult(true));
            var eventProcessor = new EventHubListener.EventProcessor(options, executor.Object, loggerMock.Object, false);

            for (int i = 0; i < 100; i++)
            {
                List <EventData> events = new List <EventData>()
                {
                    new EventData(new byte[0]), new EventData(new byte[0]), new EventData(new byte[0])
                };
                await eventProcessor.ProcessEventsAsync(partitionContext, events);
            }

            processor.Verify(
                p => p.CheckpointAsync(partitionContext.PartitionId, It.IsAny <EventData>(), It.IsAny <CancellationToken>()),
                Times.Exactly(expected));
        }
예제 #2
0
        public async Task ProcessEvents_SingleDispatch_CheckpointsCorrectly(int batchCheckpointFrequency, int expected)
        {
            var partitionContext = EventHubTests.GetPartitionContext();
            var checkpoints      = 0;
            var options          = new EventHubOptions
            {
                BatchCheckpointFrequency = batchCheckpointFrequency
            };
            var checkpointer = new Mock <EventHubListener.ICheckpointer>(MockBehavior.Strict);

            checkpointer.Setup(p => p.CheckpointAsync(partitionContext)).Callback <PartitionContext>(c =>
            {
                checkpoints++;
            }).Returns(Task.CompletedTask);
            var loggerMock = new Mock <ILogger>();
            var executor   = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);

            executor.Setup(p => p.TryExecuteAsync(It.IsAny <TriggeredFunctionData>(), It.IsAny <CancellationToken>())).ReturnsAsync(new FunctionResult(true));
            var eventProcessor = new EventHubListener.EventProcessor(options, executor.Object, loggerMock.Object, true, checkpointer.Object);

            for (int i = 0; i < 100; i++)
            {
                List <EventData> events = new List <EventData>()
                {
                    new EventData(new byte[0])
                };
                await eventProcessor.ProcessEventsAsync(partitionContext, events);
            }

            Assert.Equal(expected, checkpoints);
        }
예제 #3
0
        public async Task ProcessErrorsAsync_RebalancingExceptions_LoggedAsInformation()
        {
            var partitionContext = EventHubTests.GetPartitionContext(partitionId: "123", eventHubPath: "abc", owner: "def");
            var options          = new EventHubOptions();
            var executor         = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);
            var testLogger       = new TestLogger("Test");
            var eventProcessor   = new EventHubListener.EventProcessor(options, executor.Object, testLogger, true);

            var disconnectedEx = new EventHubsException(true, "My ReceiverDisconnectedException!", EventHubsException.FailureReason.ConsumerDisconnected);

            await eventProcessor.ProcessErrorAsync(partitionContext, disconnectedEx);

            var msg = testLogger.GetLogMessages().Single();

            StringAssert.IsMatch("Processing error \\(Partition Id: '123', Owner: '[\\w\\d-]+', EventHubPath: 'abc'\\). An exception of type 'EventHubsException' was thrown. This exception type is typically a result of Event Hub processor rebalancing or a transient error and can be safely ignored.", msg.FormattedMessage);
            Assert.NotNull(msg.Exception);
            Assert.AreEqual(LogLevel.Information, msg.Level);

            testLogger.ClearLogMessages();

            var leaseLostEx = new EventHubsException(true, "My LeaseLostException!", EventHubsException.FailureReason.ConsumerDisconnected);

            await eventProcessor.ProcessErrorAsync(partitionContext, leaseLostEx);

            msg = testLogger.GetLogMessages().Single();
            StringAssert.IsMatch("Processing error \\(Partition Id: '123', Owner: '[\\w\\d-]+', EventHubPath: 'abc'\\). An exception of type 'EventHubsException' was thrown. This exception type is typically a result of Event Hub processor rebalancing or a transient error and can be safely ignored.", msg.FormattedMessage);
            Assert.NotNull(msg.Exception);
            Assert.AreEqual(LogLevel.Information, msg.Level);
        }
예제 #4
0
        public async Task ProcessEvents_Failure_Checkpoints()
        {
            var partitionContext = EventHubTests.GetPartitionContext();
            var options          = new EventHubOptions();
            var checkpointer     = new Mock <EventHubListener.ICheckpointer>(MockBehavior.Strict);

            checkpointer.Setup(p => p.CheckpointAsync(partitionContext)).Returns(Task.CompletedTask);

            List <EventData>      events  = new List <EventData>();
            List <FunctionResult> results = new List <FunctionResult>();

            for (int i = 0; i < 10; i++)
            {
                events.Add(new EventData(new byte[0]));
                var succeeded = i > 7 ? false : true;
                results.Add(new FunctionResult(succeeded));
            }

            var executor  = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);
            int execution = 0;

            executor.Setup(p => p.TryExecuteAsync(It.IsAny <TriggeredFunctionData>(), It.IsAny <CancellationToken>())).ReturnsAsync(() =>
            {
                var result = results[execution++];
                return(result);
            });

            var loggerMock = new Mock <ILogger>();

            var eventProcessor = new EventHubListener.EventProcessor(options, executor.Object, loggerMock.Object, true, checkpointer.Object);

            await eventProcessor.ProcessEventsAsync(partitionContext, events);

            checkpointer.Verify(p => p.CheckpointAsync(partitionContext), Times.Once);
        }
        public async Task ProcessEvents_CancellationToken_CancelsExecution()
        {
            var partitionContext = EventHubTests.GetPartitionContext();
            var options          = new EventHubOptions();
            var processor        = new Mock <EventProcessorHost>(MockBehavior.Strict);

            processor.Setup(p => p.CheckpointAsync(partitionContext.PartitionId, It.IsAny <EventData>(), It.IsAny <CancellationToken>())).Returns(Task.CompletedTask);
            partitionContext.ProcessorHost = processor.Object;

            var loggerMock = new Mock <ILogger>();
            var executor   = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);

            executor.Setup(p => p.TryExecuteAsync(It.IsAny <TriggeredFunctionData>(), It.IsAny <CancellationToken>()))
            .Callback <TriggeredFunctionData, CancellationToken>(async(TriggeredFunctionData triggeredFunctionData, CancellationToken cancellationToken) =>
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    await Task.Delay(100);
                }
            })
            .ReturnsAsync(new FunctionResult(true));
            var eventProcessor      = new EventHubListener.EventProcessor(options, executor.Object, loggerMock.Object, true);
            List <EventData> events = new List <EventData>()
            {
                new EventData(new byte[0])
            };
            CancellationTokenSource source = new CancellationTokenSource();

            // Start another thread to cancel execution
            _ = Task.Run(async() =>
            {
                await Task.Delay(500);
            });
            await eventProcessor.ProcessEventsAsync(partitionContext, events, source.Token);
        }
예제 #6
0
        public async Task CloseAsync_Shutdown_DoesNotCheckpoint()
        {
            var partitionContext = EventHubTests.GetPartitionContext();
            var options          = new EventHubOptions();
            var checkpointer     = new Mock <EventHubListener.ICheckpointer>(MockBehavior.Strict);
            var executor         = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);
            var loggerMock       = new Mock <ILogger>();
            var eventProcessor   = new EventHubListener.EventProcessor(options, executor.Object, loggerMock.Object, true, checkpointer.Object);

            await eventProcessor.CloseAsync(partitionContext, CloseReason.Shutdown);

            checkpointer.Verify(p => p.CheckpointAsync(partitionContext), Times.Never);
        }
예제 #7
0
        public async Task ProcessErrorsAsync_LoggedAsError()
        {
            var partitionContext = EventHubTests.GetPartitionContext(partitionId: "123", eventHubPath: "abc", owner: "def");
            var options          = new EventHubOptions();
            var executor         = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);
            var testLogger       = new TestLogger("Test");
            var eventProcessor   = new EventHubListener.EventProcessor(options, executor.Object, testLogger, true);

            var ex = new InvalidOperationException("My InvalidOperationException!");

            await eventProcessor.ProcessErrorAsync(partitionContext, ex);

            var msg = testLogger.GetLogMessages().Single();

            StringAssert.IsMatch("Processing error \\(Partition Id: '123', Owner: '[\\w\\d-]+', EventHubPath: 'abc'\\).", msg.FormattedMessage);
            Assert.IsInstanceOf <InvalidOperationException>(msg.Exception);
            Assert.AreEqual(LogLevel.Error, msg.Level);
        }
        public async Task ProcessErrorsAsync_LoggedAsError()
        {
            var partitionContext = EventHubTests.GetPartitionContext(partitionId: "123", eventHubPath: "abc", owner: "def");
            var options          = new EventHubOptions();
            var checkpointer     = new Mock <EventHubListener.ICheckpointer>(MockBehavior.Strict);
            var executor         = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);
            var testLogger       = new TestLogger("Test");
            var eventProcessor   = new EventHubListener.EventProcessor(options, executor.Object, testLogger, true, checkpointer.Object);

            var ex = new InvalidOperationException("My InvalidOperationException!");

            await eventProcessor.ProcessErrorAsync(partitionContext, ex);

            var msg = testLogger.GetLogMessages().Single();

            Assert.Equal("Error processing event from Partition Id: '123', Owner: 'def', EventHubPath: 'abc'", msg.FormattedMessage);
            Assert.IsType <InvalidOperationException>(msg.Exception);
            Assert.Equal(LogLevel.Error, msg.Level);
        }
예제 #9
0
        public async Task CloseAsync_Shutdown_DoesNotCheckpoint()
        {
            var partitionContext = EventHubTests.GetPartitionContext();
            var options          = new EventHubOptions();

            var processor = new Mock <EventProcessorHost>(MockBehavior.Strict);

            processor.Setup(p => p.CheckpointAsync(partitionContext.PartitionId, It.IsAny <EventData>(), It.IsAny <CancellationToken>())).Returns(Task.CompletedTask);
            partitionContext.ProcessorHost = processor.Object;

            var executor       = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);
            var loggerMock     = new Mock <ILogger>();
            var eventProcessor = new EventHubListener.EventProcessor(options, executor.Object, loggerMock.Object, true);

            await eventProcessor.CloseAsync(partitionContext, ProcessingStoppedReason.Shutdown);

            processor.Verify(
                p => p.CheckpointAsync(partitionContext.PartitionId, It.IsAny <EventData>(), It.IsAny <CancellationToken>()),
                Times.Never);
        }
예제 #10
0
        public async Task ProcessErrorsAsync_RebalancingExceptions_LoggedAsInformation()
        {
            var partitionContext = EventHubTests.GetPartitionContext(partitionId: "123", eventHubPath: "abc", owner: "def");
            var options          = new EventHubOptions();
            var checkpointer     = new Mock <EventHubListener.ICheckpointer>(MockBehavior.Strict);
            var executor         = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);
            var testLogger       = new TestLogger("Test");
            var eventProcessor   = new EventHubListener.EventProcessor(options, executor.Object, testLogger, true, checkpointer.Object);

            // ctor is private
            var constructor = typeof(ReceiverDisconnectedException)
                              .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, null);
            ReceiverDisconnectedException disconnectedEx = (ReceiverDisconnectedException)constructor.Invoke(new[] { "My ReceiverDisconnectedException!" });

            await eventProcessor.ProcessErrorAsync(partitionContext, disconnectedEx);

            var msg = testLogger.GetLogMessages().Single();

            Assert.Equal("Processing error (Partition Id: '123', Owner: 'def', EventHubPath: 'abc'). An exception of type 'ReceiverDisconnectedException' was thrown. This exception type is typically a result of Event Hub processor rebalancing or a transient error and can be safely ignored.", msg.FormattedMessage);
            Assert.NotNull(msg.Exception);
            Assert.Equal(LogLevel.Information, msg.Level);

            testLogger.ClearLogMessages();

            // ctor is private
            constructor = typeof(LeaseLostException)
                          .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(Exception) }, null);
            LeaseLostException leaseLostEx = (LeaseLostException)constructor.Invoke(new object[] { "My LeaseLostException!", new Exception() });

            await eventProcessor.ProcessErrorAsync(partitionContext, leaseLostEx);

            msg = testLogger.GetLogMessages().Single();
            Assert.Equal("Processing error (Partition Id: '123', Owner: 'def', EventHubPath: 'abc'). An exception of type 'LeaseLostException' was thrown. This exception type is typically a result of Event Hub processor rebalancing or a transient error and can be safely ignored.", msg.FormattedMessage);
            Assert.NotNull(msg.Exception);
            Assert.Equal(LogLevel.Information, msg.Level);
        }