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); }
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); }
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); }