public QueueListenerTests()
        {
            CloudQueue queue = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue"));
            Mock<IStorageQueue> mockQueue = new Mock<IStorageQueue>(MockBehavior.Strict);
            mockQueue.Setup(p => p.SdkObject).Returns(queue);

            _mockTriggerExecutor = new Mock<ITriggerExecutor<IStorageQueueMessage>>(MockBehavior.Strict);
            Mock<IDelayStrategy> mockDelayStrategy = new Mock<IDelayStrategy>(MockBehavior.Strict);
            Mock<IBackgroundExceptionDispatcher> mockExceptionDispatcher = new Mock<IBackgroundExceptionDispatcher>(MockBehavior.Strict);
            TextWriter log = new StringWriter();
            Mock<IQueueProcessorFactory> mockQueueProcessorFactory = new Mock<IQueueProcessorFactory>(MockBehavior.Strict);
            JobHostQueuesConfiguration queuesConfig = new JobHostQueuesConfiguration();
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(queue, log, queuesConfig);

            _mockQueueProcessor = new Mock<QueueProcessor>(MockBehavior.Strict, context);
            JobHostQueuesConfiguration queueConfig = new JobHostQueuesConfiguration
            {
                MaxDequeueCount = 5,
                QueueProcessorFactory = mockQueueProcessorFactory.Object
            };

            mockQueueProcessorFactory.Setup(p => p.Create(It.IsAny<QueueProcessorFactoryContext>())).Returns(_mockQueueProcessor.Object);

            _listener = new QueueListener(mockQueue.Object, null, _mockTriggerExecutor.Object, mockDelayStrategy.Object, mockExceptionDispatcher.Object, log, null, queueConfig);

            CloudQueueMessage cloudMessage = new CloudQueueMessage("TestMessage");
            _storageMessage = new StorageQueueMessage(cloudMessage);
        }
        public QueueListenerTests()
        {
            CloudQueue           queue     = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue"));
            Mock <IStorageQueue> mockQueue = new Mock <IStorageQueue>(MockBehavior.Strict);

            mockQueue.Setup(p => p.SdkObject).Returns(queue);

            _mockTriggerExecutor = new Mock <ITriggerExecutor <IStorageQueueMessage> >(MockBehavior.Strict);
            Mock <IDelayStrategy> mockDelayStrategy = new Mock <IDelayStrategy>(MockBehavior.Strict);
            Mock <IBackgroundExceptionDispatcher> mockExceptionDispatcher = new Mock <IBackgroundExceptionDispatcher>(MockBehavior.Strict);
            TestTraceWriter log = new TestTraceWriter(TraceLevel.Verbose);
            Mock <IQueueProcessorFactory> mockQueueProcessorFactory = new Mock <IQueueProcessorFactory>(MockBehavior.Strict);
            JobHostQueuesConfiguration    queuesConfig = new JobHostQueuesConfiguration();
            QueueProcessorFactoryContext  context      = new QueueProcessorFactoryContext(queue, log, queuesConfig);

            _mockQueueProcessor = new Mock <QueueProcessor>(MockBehavior.Strict, context);
            JobHostQueuesConfiguration queueConfig = new JobHostQueuesConfiguration
            {
                MaxDequeueCount       = 5,
                QueueProcessorFactory = mockQueueProcessorFactory.Object
            };

            mockQueueProcessorFactory.Setup(p => p.Create(It.IsAny <QueueProcessorFactoryContext>())).Returns(_mockQueueProcessor.Object);

            _listener = new QueueListener(mockQueue.Object, null, _mockTriggerExecutor.Object, mockDelayStrategy.Object, mockExceptionDispatcher.Object, log, null, queueConfig);

            CloudQueueMessage cloudMessage = new CloudQueueMessage("TestMessage");

            _storageMessage = new StorageQueueMessage(cloudMessage);
        }
        public QueueListenerTests()
        {
            CloudQueue queue = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue"));

            _mockQueue = new Mock <IStorageQueue>(MockBehavior.Strict);
            _mockQueue.Setup(p => p.SdkObject).Returns(queue);

            _mockTriggerExecutor = new Mock <ITriggerExecutor <IStorageQueueMessage> >(MockBehavior.Strict);
            Mock <IWebJobsExceptionHandler> mockExceptionDispatcher = new Mock <IWebJobsExceptionHandler>(MockBehavior.Strict);

            _loggerFactory = new LoggerFactory();
            _loggerFactory.AddProvider(new TestLoggerProvider());
            Mock <IQueueProcessorFactory> mockQueueProcessorFactory = new Mock <IQueueProcessorFactory>(MockBehavior.Strict);
            JobHostQueuesConfiguration    queuesConfig = new JobHostQueuesConfiguration();
            QueueProcessorFactoryContext  context      = new QueueProcessorFactoryContext(queue, _loggerFactory, queuesConfig);

            _mockQueueProcessor = new Mock <QueueProcessor>(MockBehavior.Strict, context);
            JobHostQueuesConfiguration queueConfig = new JobHostQueuesConfiguration
            {
                MaxDequeueCount       = 5,
                QueueProcessorFactory = mockQueueProcessorFactory.Object
            };

            mockQueueProcessorFactory.Setup(p => p.Create(It.IsAny <QueueProcessorFactoryContext>())).Returns(_mockQueueProcessor.Object);

            _listener = new QueueListener(_mockQueue.Object, null, _mockTriggerExecutor.Object, mockExceptionDispatcher.Object, _loggerFactory, null, queueConfig);

            CloudQueueMessage cloudMessage = new CloudQueueMessage("TestMessage");

            _storageMessage = new StorageQueueMessage(cloudMessage);
        }
        public void Constructor_Defaults()
        {
            JobHostQueuesConfiguration config = new JobHostQueuesConfiguration();

            Assert.Equal(16, config.BatchSize);
            Assert.Equal(8, config.NewBatchThreshold);
            Assert.Equal(typeof(DefaultQueueProcessorFactory), config.QueueProcessorFactory.GetType());
            Assert.Equal(QueuePollingIntervals.DefaultMaximum, config.MaxPollingInterval);
        }
        public void VisibilityTimeout_CanGetAndSetValue()
        {
            JobHostQueuesConfiguration config = new JobHostQueuesConfiguration();

            Assert.Equal(TimeSpan.Zero, config.VisibilityTimeout);

            config.VisibilityTimeout = TimeSpan.FromSeconds(30);
            Assert.Equal(TimeSpan.FromSeconds(30), config.VisibilityTimeout);
        }
Esempio n. 6
0
        public QueueProcessorTests(TestFixture fixture)
        {
            _queue       = fixture.Queue;
            _poisonQueue = fixture.PoisonQueue;

            _queuesConfig = new JobHostQueuesConfiguration();
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, _queuesConfig);

            _processor = new QueueProcessor(context);
        }
        public void Constructor_Defaults()
        {
            // Arrange
            JobHostQueuesConfiguration config = new JobHostQueuesConfiguration();

            // Act & Assert
            Assert.Equal(16, config.BatchSize);
            Assert.Equal(8, config.NewBatchThreshold);
            Assert.Equal(typeof(DefaultQueueProcessorFactory), config.QueueProcessorFactory.GetType());
            Assert.Equal(QueuePollingIntervals.DefaultMaximum, config.MaxPollingInterval);
        }
        public QueueProcessorTests(TestFixture fixture)
        {
            _trace       = new TestTraceWriter(TraceLevel.Verbose);
            _queue       = fixture.Queue;
            _poisonQueue = fixture.PoisonQueue;

            _queuesConfig = new JobHostQueuesConfiguration();
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, _trace, null, _queuesConfig);

            _processor = new QueueProcessor(context);
        }
Esempio n. 9
0
        public async Task UpdatedQueueMessage_RetainsOriginalProperties()
        {
            TraceWriter trace       = new TestTraceWriter(TraceLevel.Verbose);
            CloudQueue  queue       = Fixture.CreateNewQueue();
            CloudQueue  poisonQueue = Fixture.CreateNewQueue();

            JobHostQueuesConfiguration queuesConfig = new JobHostQueuesConfiguration {
                MaxDequeueCount = 2
            };

            StorageQueue storageQueue       = new StorageQueue(new StorageQueueClient(Fixture.QueueClient), queue);
            StorageQueue storagePoisonQueue = new StorageQueue(new StorageQueueClient(Fixture.QueueClient), poisonQueue);
            Mock <ITriggerExecutor <IStorageQueueMessage> > mockTriggerExecutor = new Mock <ITriggerExecutor <IStorageQueueMessage> >(MockBehavior.Strict);

            string            messageContent = Guid.NewGuid().ToString();
            CloudQueueMessage message        = new CloudQueueMessage(messageContent);
            await queue.AddMessageAsync(message, null, null, null, null, CancellationToken.None);

            CloudQueueMessage messageFromCloud = await queue.GetMessageAsync();

            QueueListener listener = new QueueListener(storageQueue, storagePoisonQueue, mockTriggerExecutor.Object, new WebJobsExceptionHandler(), trace,
                                                       null, null, queuesConfig);

            mockTriggerExecutor
            .Setup(m => m.ExecuteAsync(It.IsAny <IStorageQueueMessage>(), CancellationToken.None))
            .ReturnsAsync(new FunctionResult(false));

            await listener.ProcessMessageAsync(new StorageQueueMessage(messageFromCloud), TimeSpan.FromMinutes(10), CancellationToken.None);

            // pull the message and process it again (to have it go through the poison queue flow)
            messageFromCloud = await queue.GetMessageAsync();

            Assert.Equal(2, messageFromCloud.DequeueCount);

            await listener.ProcessMessageAsync(new StorageQueueMessage(messageFromCloud), TimeSpan.FromMinutes(10), CancellationToken.None);

            // Make sure the message was processed and deleted.
            await queue.FetchAttributesAsync();

            Assert.Equal(0, queue.ApproximateMessageCount);

            // The Listener has inserted a message to the poison queue.
            await poisonQueue.FetchAttributesAsync();

            Assert.Equal(1, poisonQueue.ApproximateMessageCount);

            mockTriggerExecutor.Verify(m => m.ExecuteAsync(It.IsAny <IStorageQueueMessage>(), CancellationToken.None), Times.Exactly(2));
        }
        public void NewBatchThreshold_CanSetAndGetValue()
        {
            JobHostQueuesConfiguration config = new JobHostQueuesConfiguration();

            // Unless explicitly set, NewBatchThreshold will be computed based
            // on the current BatchSize
            config.BatchSize = 20;
            Assert.Equal(10, config.NewBatchThreshold);
            config.BatchSize = 32;
            Assert.Equal(16, config.NewBatchThreshold);

            // Once set, the set value holds
            config.NewBatchThreshold = 1000;
            Assert.Equal(1000, config.NewBatchThreshold);
            config.BatchSize = 8;
            Assert.Equal(1000, config.NewBatchThreshold);
        }
        public void Constructor_DefaultsValues()
        {
            CloudQueue queue = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue"));
            CloudQueue poisonQueue = new CloudQueue(new Uri("https://test.queue.core.windows.net/poisonqueue"));
            TextWriter log = new StringWriter();
            JobHostQueuesConfiguration queuesConfig = new JobHostQueuesConfiguration();

            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(queue, log, queuesConfig, poisonQueue);

            Assert.Same(queue, context.Queue);
            Assert.Same(log, context.Log);
            Assert.Same(poisonQueue, context.PoisonQueue);

            Assert.Equal(queuesConfig.BatchSize, context.BatchSize);
            Assert.Equal(queuesConfig.NewBatchThreshold, context.NewBatchThreshold);
            Assert.Equal(queuesConfig.MaxDequeueCount, context.MaxDequeueCount);
        }
        public void Constructor_DefaultsValues()
        {
            CloudQueue                 queue        = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue"));
            CloudQueue                 poisonQueue  = new CloudQueue(new Uri("https://test.queue.core.windows.net/poisonqueue"));
            TestTraceWriter            log          = new TestTraceWriter(TraceLevel.Verbose);
            JobHostQueuesConfiguration queuesConfig = new JobHostQueuesConfiguration();

            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(queue, log, queuesConfig, poisonQueue);

            Assert.Same(queue, context.Queue);
            Assert.Same(log, context.Trace);
            Assert.Same(poisonQueue, context.PoisonQueue);

            Assert.Equal(queuesConfig.BatchSize, context.BatchSize);
            Assert.Equal(queuesConfig.NewBatchThreshold, context.NewBatchThreshold);
            Assert.Equal(queuesConfig.MaxDequeueCount, context.MaxDequeueCount);
        }
        public void NewBatchThreshold_CanSetAndGetValue()
        {
            // Arrange
            JobHostQueuesConfiguration config = new JobHostQueuesConfiguration();

            // Unless explicitly set, NewBatchThreshold will be computed based
            // on the current BatchSize
            config.BatchSize = 20;
            Assert.Equal(10, config.NewBatchThreshold);
            config.BatchSize = 32;
            Assert.Equal(16, config.NewBatchThreshold);

            // Once set, the set value holds
            config.NewBatchThreshold = 1000;
            Assert.Equal(1000, config.NewBatchThreshold);
            config.BatchSize = 8;
            Assert.Equal(1000, config.NewBatchThreshold);
        }
        public void Constructor_DefaultsValues()
        {
            var config = new JobHostQueuesConfiguration
            {
                BatchSize          = 32,
                MaxDequeueCount    = 2,
                NewBatchThreshold  = 100,
                VisibilityTimeout  = TimeSpan.FromSeconds(30),
                MaxPollingInterval = TimeSpan.FromSeconds(15)
            };
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, _trace, null, config);
            QueueProcessor localProcessor        = new QueueProcessor(context);

            Assert.Equal(config.BatchSize, localProcessor.BatchSize);
            Assert.Equal(config.MaxDequeueCount, localProcessor.MaxDequeueCount);
            Assert.Equal(config.NewBatchThreshold, localProcessor.NewBatchThreshold);
            Assert.Equal(config.VisibilityTimeout, localProcessor.VisibilityTimeout);
            Assert.Equal(config.MaxPollingInterval, localProcessor.MaxPollingInterval);
        }
        public void Constructor_DefaultsValues()
        {
            CloudQueue     queue         = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue"));
            CloudQueue     poisonQueue   = new CloudQueue(new Uri("https://test.queue.core.windows.net/poisonqueue"));
            ILoggerFactory loggerFactory = new LoggerFactory();

            loggerFactory.AddProvider(new TestLoggerProvider());
            JobHostQueuesConfiguration queuesConfig = new JobHostQueuesConfiguration();

            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(queue, loggerFactory, queuesConfig, poisonQueue);

            Assert.Same(queue, context.Queue);
            Assert.Same(poisonQueue, context.PoisonQueue);
            Assert.NotNull(context.Logger);

            Assert.Equal(queuesConfig.BatchSize, context.BatchSize);
            Assert.Equal(queuesConfig.NewBatchThreshold, context.NewBatchThreshold);
            Assert.Equal(queuesConfig.MaxDequeueCount, context.MaxDequeueCount);
            Assert.Equal(queuesConfig.MaxPollingInterval, context.MaxPollingInterval);
        }
        public async Task CompleteProcessingMessageAsync_Failure_AppliesVisibilityTimeout()
        {
            var queuesConfig = new JobHostQueuesConfiguration
            {
                // configure a non-zero visibility timeout
                VisibilityTimeout = TimeSpan.FromMinutes(5)
            };
            QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, _trace, null, queuesConfig, _poisonQueue);
            QueueProcessor localProcessor        = new QueueProcessor(context);

            string            messageContent = Guid.NewGuid().ToString();
            CloudQueueMessage message        = new CloudQueueMessage(messageContent);
            await _queue.AddMessageAsync(message, CancellationToken.None);

            var functionResult = new FunctionResult(false);

            message = await _queue.GetMessageAsync();

            await localProcessor.CompleteProcessingMessageAsync(message, functionResult, CancellationToken.None);

            var delta = message.NextVisibleTime - DateTime.UtcNow;

            Assert.True(delta.Value.TotalMinutes > 4);
        }
        public void CreateQueueProcessor_CreatesProcessorCorrectly()
        {
            CloudQueue      poisonQueue = null;
            TestTraceWriter log         = new TestTraceWriter(TraceLevel.Verbose);
            bool            poisonMessageHandlerInvoked             = false;
            EventHandler    poisonMessageEventHandler               = (sender, e) => { poisonMessageHandlerInvoked = true; };
            Mock <IQueueProcessorFactory> mockQueueProcessorFactory = new Mock <IQueueProcessorFactory>(MockBehavior.Strict);
            JobHostQueuesConfiguration    queueConfig               = new JobHostQueuesConfiguration
            {
                MaxDequeueCount       = 7,
                QueueProcessorFactory = mockQueueProcessorFactory.Object
            };
            QueueProcessor expectedQueueProcessor  = null;
            bool           processorFactoryInvoked = false;

            // create for a host queue - don't expect custom factory to be invoked
            CloudQueue     queue          = new CloudQueue(new Uri(string.Format("https://test.queue.core.windows.net/{0}", HostQueueNames.GetHostQueueName("12345"))));
            QueueProcessor queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, log, queueConfig, poisonMessageEventHandler);

            Assert.False(processorFactoryInvoked);
            Assert.NotSame(expectedQueueProcessor, queueProcessor);
            queueProcessor.OnMessageAddedToPoisonQueue(new EventArgs());
            Assert.True(poisonMessageHandlerInvoked);

            QueueProcessorFactoryContext processorFactoryContext = null;

            mockQueueProcessorFactory.Setup(p => p.Create(It.IsAny <QueueProcessorFactoryContext>()))
            .Callback <QueueProcessorFactoryContext>((mockProcessorContext) =>
            {
                processorFactoryInvoked = true;

                Assert.Same(queue, mockProcessorContext.Queue);
                Assert.Same(poisonQueue, mockProcessorContext.PoisonQueue);
                Assert.Equal(queueConfig.MaxDequeueCount, mockProcessorContext.MaxDequeueCount);
                Assert.Same(log, mockProcessorContext.Trace);

                processorFactoryContext = mockProcessorContext;
            })
            .Returns(() =>
            {
                expectedQueueProcessor = new QueueProcessor(processorFactoryContext);
                return(expectedQueueProcessor);
            });

            // when storage host is "localhost" we invoke the processor factory even for
            // host queues (this enables local test mocking)
            processorFactoryInvoked = false;
            queue          = new CloudQueue(new Uri(string.Format("https://localhost/{0}", HostQueueNames.GetHostQueueName("12345"))));
            queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, log, queueConfig, poisonMessageEventHandler);
            Assert.True(processorFactoryInvoked);
            Assert.Same(expectedQueueProcessor, queueProcessor);

            // create for application queue - expect processor factory to be invoked
            poisonMessageHandlerInvoked = false;
            processorFactoryInvoked     = false;
            queue          = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue"));
            queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, log, queueConfig, poisonMessageEventHandler);
            Assert.True(processorFactoryInvoked);
            Assert.Same(expectedQueueProcessor, queueProcessor);
            queueProcessor.OnMessageAddedToPoisonQueue(new EventArgs());
            Assert.True(poisonMessageHandlerInvoked);

            // if poison message watcher not specified, event not subscribed to
            poisonMessageHandlerInvoked = false;
            processorFactoryInvoked     = false;
            queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, log, queueConfig, null);
            Assert.True(processorFactoryInvoked);
            Assert.Same(expectedQueueProcessor, queueProcessor);
            queueProcessor.OnMessageAddedToPoisonQueue(new EventArgs());
            Assert.False(poisonMessageHandlerInvoked);
        }
        public void CreateQueueProcessor_CreatesProcessorCorrectly()
        {
            CloudQueue poisonQueue = null;
            TextWriter log = new StringWriter();
            bool poisonMessageHandlerInvoked = false;
            EventHandler poisonMessageEventHandler = (sender, e) => { poisonMessageHandlerInvoked = true; };
            Mock<IQueueProcessorFactory> mockQueueProcessorFactory = new Mock<IQueueProcessorFactory>(MockBehavior.Strict);
            JobHostQueuesConfiguration queueConfig = new JobHostQueuesConfiguration
            {
                MaxDequeueCount = 7,
                QueueProcessorFactory = mockQueueProcessorFactory.Object
            };
            QueueProcessor expectedQueueProcessor = null;
            bool processorFactoryInvoked = false;

            // create for a host queue - don't expect custom factory to be invoked
            CloudQueue queue = new CloudQueue(new Uri(string.Format("https://test.queue.core.windows.net/{0}", HostQueueNames.GetHostQueueName("12345"))));
            QueueProcessor queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, log, queueConfig, poisonMessageEventHandler);
            Assert.False(processorFactoryInvoked);
            Assert.NotSame(expectedQueueProcessor, queueProcessor);
            queueProcessor.OnMessageAddedToPoisonQueue(new EventArgs());
            Assert.True(poisonMessageHandlerInvoked);

            QueueProcessorFactoryContext processorFactoryContext = null;
            mockQueueProcessorFactory.Setup(p => p.Create(It.IsAny<QueueProcessorFactoryContext>()))
                .Callback<QueueProcessorFactoryContext>((mockProcessorContext) =>
                {
                    processorFactoryInvoked = true;

                    Assert.Same(queue, mockProcessorContext.Queue);
                    Assert.Same(poisonQueue, mockProcessorContext.PoisonQueue);
                    Assert.Equal(queueConfig.MaxDequeueCount, mockProcessorContext.MaxDequeueCount);
                    Assert.Same(log, mockProcessorContext.Log);

                    processorFactoryContext = mockProcessorContext;
                })
                .Returns(() => 
                {
                    expectedQueueProcessor = new QueueProcessor(processorFactoryContext);
                    return expectedQueueProcessor;
                });

            // when storage host is "localhost" we invoke the processor factory even for
            // host queues (this enables local test mocking)
            processorFactoryInvoked = false;
            queue = new CloudQueue(new Uri(string.Format("https://localhost/{0}", HostQueueNames.GetHostQueueName("12345"))));
            queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, log, queueConfig, poisonMessageEventHandler);
            Assert.True(processorFactoryInvoked);
            Assert.Same(expectedQueueProcessor, queueProcessor);

            // create for application queue - expect processor factory to be invoked
            poisonMessageHandlerInvoked = false;
            processorFactoryInvoked = false;
            queue = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue"));
            queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, log, queueConfig, poisonMessageEventHandler);
            Assert.True(processorFactoryInvoked);
            Assert.Same(expectedQueueProcessor, queueProcessor);
            queueProcessor.OnMessageAddedToPoisonQueue(new EventArgs());
            Assert.True(poisonMessageHandlerInvoked);

            // if poison message watcher not specified, event not subscribed to
            poisonMessageHandlerInvoked = false;
            processorFactoryInvoked = false;
            queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, log, queueConfig, null);
            Assert.True(processorFactoryInvoked);
            Assert.Same(expectedQueueProcessor, queueProcessor);
            queueProcessor.OnMessageAddedToPoisonQueue(new EventArgs());
            Assert.False(poisonMessageHandlerInvoked);
        }