Example #1
0
        public void ExecuteAsync_IfFunctionIdIsNull_Throws()
        {
            // Arrange
            BlobQueueTriggerExecutor product = CreateProductUnderTest();
            var message = CreateMessage("{}");

            // Act
            Task task = product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            ExceptionAssert.ThrowsInvalidOperation(() => task.GetAwaiter().GetResult(), "Invalid function ID.");
        }
Example #2
0
        public void ExecuteAsync_IfMessageIsNotJson_Throws()
        {
            // Arrange
            BlobQueueTriggerExecutor product = CreateProductUnderTest();
            var message = CreateMessage("ThisIsNotValidJson");

            // Act
            Task task = product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            Assert.Throws <JsonReaderException>(() => task.GetAwaiter().GetResult());
        }
        public void ExecuteAsync_IfMessageIsJsonNull_Throws()
        {
            // Arrange
            BlobQueueTriggerExecutor product = CreateProductUnderTest();
            IStorageQueueMessage     message = CreateMessage("null");

            // Act
            Task task = product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            ExceptionAssert.ThrowsInvalidOperation(() => task.GetAwaiter().GetResult(),
                                                   "Invalid blob trigger message.");
        }
        public void ExecuteAsync_IfMessageIsFunctionIdIsNotRegistered_ReturnsSuccessResult()
        {
            // Arrange
            BlobQueueTriggerExecutor product = CreateProductUnderTest();
            IStorageQueueMessage     message = CreateMessage(new BlobTriggerMessage {
                FunctionId = "Missing"
            });

            // Act
            Task <FunctionResult> task = product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            Assert.True(task.Result.Succeeded);
        }
Example #5
0
        public void GetMonitor_ReturnsSharedMonitor()
        {
            var queueListener           = new QueueListener();
            var watcherMock             = new Mock <IBlobWrittenWatcher>(MockBehavior.Strict);
            var executor                = new BlobQueueTriggerExecutor(watcherMock.Object, NullLogger <BlobListener> .Instance);
            var sharedBlobQueueListener = new SharedBlobQueueListener(queueListener, executor);
            var sharedListenerMock      = new Mock <ISharedListener>(MockBehavior.Strict);
            var blobListener1           = new BlobListener(sharedBlobQueueListener);
            var blobListener2           = new BlobListener(sharedBlobQueueListener);

            var monitor1 = blobListener1.GetMonitor();
            var monitor2 = blobListener1.GetMonitor();

            Assert.AreSame(monitor1, monitor2);
            Assert.AreSame(monitor1, queueListener);
        }
        public void ExecuteAsync_IfBlobHasBeenDeleted_ReturnsSuccessResult()
        {
            // Arrange
            string                   functionId = "FunctionId";
            IBlobETagReader          eTagReader = CreateStubETagReader(null);
            BlobQueueTriggerExecutor product    = CreateProductUnderTest(eTagReader);

            product.Register(functionId, CreateDummyTriggeredFunctionExecutor());

            IStorageQueueMessage message = CreateMessage(functionId, "OriginalETag");

            // Act
            Task <FunctionResult> task = product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            Assert.True(task.Result.Succeeded);
        }
        public async Task ExecuteAsync_IfBlobIsUnchanged_CallsInnerExecutor()
        {
            // Arrange
            var    account          = new FakeAccount();
            string functionId       = "FunctionId";
            string matchingETag     = "ETag";
            Guid   expectedParentId = Guid.NewGuid();
            var    message          = CreateMessage(functionId, matchingETag);

            SetEtag(account, TestContainerName, TestBlobName, matchingETag);

            IBlobCausalityReader causalityReader = CreateStubCausalityReader(expectedParentId);

            FunctionResult expectedResult          = new FunctionResult(true);
            Mock <ITriggeredFunctionExecutor> mock = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);

            mock.Setup(e => e.TryExecuteAsync(It.IsAny <TriggeredFunctionData>(), It.IsAny <CancellationToken>()))
            .Callback <TriggeredFunctionData, CancellationToken>(
                (mockInput, mockCancellationToken) =>
            {
                Assert.Equal(expectedParentId, mockInput.ParentId);

                var resultBlob = (ICloudBlob)mockInput.TriggerValue;
                Assert.Equal(TestBlobName, resultBlob.Name);
            })
            .ReturnsAsync(expectedResult)
            .Verifiable();

            ITriggeredFunctionExecutor innerExecutor = mock.Object;
            BlobQueueTriggerExecutor   product       = CreateProductUnderTest(causalityReader);

            BlobQueueRegistration registration = new BlobQueueRegistration
            {
                BlobClient = account.CreateCloudBlobClient(),
                Executor   = innerExecutor
            };

            product.Register(functionId, registration);

            // Act
            FunctionResult result = await product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            Assert.Same(expectedResult, result);
            mock.Verify();
        }
        public void ExecuteAsync_IfInnerExecutorFails_ReturnsFalse()
        {
            // Arrange
            string                   functionId      = "FunctionId";
            string                   matchingETag    = "ETag";
            IBlobETagReader          eTagReader      = CreateStubETagReader(matchingETag);
            IBlobCausalityReader     causalityReader = CreateStubCausalityReader();
            IFunctionExecutor        innerExecutor   = CreateStubInnerExecutor(CreateDummyDelayedException());
            BlobQueueTriggerExecutor product         = CreateProductUnderTest(eTagReader, causalityReader, innerExecutor);

            product.Register(functionId, CreateFakeInstanceFactory());

            IStorageQueueMessage message = CreateMessage(functionId, matchingETag);

            // Act
            Task <bool> task = product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            Assert.False(task.Result);
        }
        public void ExecuteAsync_IfMessageIsFunctionIdIsRegistered_GetsETag(BlobType expectedBlobType)
        {
            // Arrange
            string expectedContainerName = "container";
            string expectedBlobName      = TestBlobName;
            string functionId            = "FunctionId";
            Mock <IBlobETagReader> mock  = new Mock <IBlobETagReader>(MockBehavior.Strict);

            mock.Setup(r => r.GetETagAsync(It.Is <IStorageBlob>(b => b.BlobType == (StorageBlobType)expectedBlobType &&
                                                                b.Name == expectedBlobName && b.Container.Name == expectedContainerName),
                                           It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult("ETag"))
            .Verifiable();
            IBlobETagReader          eTagReader = mock.Object;
            BlobQueueTriggerExecutor product    = CreateProductUnderTest(eTagReader);

            BlobQueueRegistration registration = new BlobQueueRegistration
            {
                BlobClient = CreateClient(),
                Executor   = CreateDummyTriggeredFunctionExecutor()
            };

            product.Register(functionId, registration);

            BlobTriggerMessage triggerMessage = new BlobTriggerMessage
            {
                FunctionId    = functionId,
                BlobType      = (StorageBlobType)expectedBlobType,
                ContainerName = expectedContainerName,
                BlobName      = expectedBlobName,
                ETag          = "OriginalETag"
            };
            IStorageQueueMessage message = CreateMessage(triggerMessage);

            // Act
            Task task = product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            task.WaitUntilCompleted();
            mock.Verify();
        }
        public void ExecuteAsync_IfInnerExecutorFails_ReturnsFailureResult()
        {
            // Arrange
            var account = new FakeAccount();

            string functionId   = "FunctionId";
            string matchingETag = "ETag";

            SetEtag(account, TestContainerName, TestBlobName, matchingETag);

            IBlobCausalityReader causalityReader = CreateStubCausalityReader();

            FunctionResult expectedResult          = new FunctionResult(false);
            Mock <ITriggeredFunctionExecutor> mock = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);

            mock.Setup(e => e.TryExecuteAsync(
                           It.IsAny <TriggeredFunctionData>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(expectedResult)
            .Verifiable();

            BlobQueueTriggerExecutor product = CreateProductUnderTest(causalityReader);

            ITriggeredFunctionExecutor innerExecutor = mock.Object;
            BlobQueueRegistration      registration  = new BlobQueueRegistration
            {
                BlobClient = account.CreateCloudBlobClient(),
                Executor   = innerExecutor
            };

            product.Register(functionId, registration);

            var message = CreateMessage(functionId, matchingETag);

            // Act
            Task <FunctionResult> task = product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            Assert.False(task.Result.Succeeded);
        }
        public async Task ExecuteAsync_IfBlobIsUnchanged_CallsInnerExecutor()
        {
            // Arrange
            string functionId                    = "FunctionId";
            string matchingETag                  = "ETag";
            Guid   expectedParentId              = Guid.NewGuid();
            IStorageQueueMessage message         = CreateMessage(functionId, matchingETag);
            IBlobETagReader      eTagReader      = CreateStubETagReader(matchingETag);
            IBlobCausalityReader causalityReader = CreateStubCausalityReader(expectedParentId);

            FunctionResult expectedResult          = new FunctionResult(true);
            Mock <ITriggeredFunctionExecutor> mock = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);

            mock.Setup(e => e.TryExecuteAsync(It.IsAny <TriggeredFunctionData>(), It.IsAny <CancellationToken>()))
            .Callback <TriggeredFunctionData, CancellationToken>(
                (mockInput, mockCancellationToken) =>
            {
                Assert.Equal(expectedParentId, mockInput.ParentId);

                StorageBlockBlob resultBlob = (StorageBlockBlob)mockInput.TriggerValue;
                Assert.Equal(TestBlobName, resultBlob.Name);
            })
            .ReturnsAsync(expectedResult)
            .Verifiable();

            ITriggeredFunctionExecutor innerExecutor = mock.Object;
            BlobQueueTriggerExecutor   product       = CreateProductUnderTest(eTagReader, causalityReader);

            product.Register(functionId, innerExecutor);

            // Act
            FunctionResult result = await product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            Assert.Same(expectedResult, result);
            mock.Verify();
        }
        public void ExecuteAsync_IfBlobHasChanged_NotifiesWatcherAndReturnsSuccessResult()
        {
            // Arrange
            string                     functionId = "FunctionId";
            IBlobETagReader            eTagReader = CreateStubETagReader("NewETag");
            Mock <IBlobWrittenWatcher> mock       = new Mock <IBlobWrittenWatcher>(MockBehavior.Strict);

            mock.Setup(w => w.Notify(It.IsAny <IStorageBlob>()))
            .Verifiable();
            IBlobWrittenWatcher      blobWrittenWatcher = mock.Object;
            BlobQueueTriggerExecutor product            = CreateProductUnderTest(eTagReader, blobWrittenWatcher);

            product.Register(functionId, CreateDummyTriggeredFunctionExecutor());

            IStorageQueueMessage message = CreateMessage(functionId, "OriginalETag");

            // Act
            Task <FunctionResult> task = product.ExecuteAsync(message, CancellationToken.None);

            // Assert
            task.WaitUntilCompleted();
            mock.Verify();
            Assert.True(task.Result.Succeeded);
        }
 public SharedBlobQueueListener(IListener listener, BlobQueueTriggerExecutor executor)
 {
     _listener = listener;
     _executor = executor;
 }