public void ExecuteAsync_IfBlobHasChanged_NotifiesWatcherAndReturnsSuccessResult() { // Arrange string functionId = "FunctionId"; string eTag = TouchBlob(TestContainerName, TestBlobName); Mock <IBlobWrittenWatcher> mock = new Mock <IBlobWrittenWatcher>(MockBehavior.Strict); mock.Setup(w => w.Notify(It.IsAny <BlobWithContainer <BlobBaseClient> >())) .Verifiable(); IBlobWrittenWatcher blobWrittenWatcher = mock.Object; BlobQueueTriggerExecutor product = CreateProductUnderTest(null, blobWrittenWatcher); BlobQueueRegistration registration = new BlobQueueRegistration { BlobServiceClient = _blobServiceClient, Executor = CreateDummyTriggeredFunctionExecutor() }; product.Register(functionId, registration); var message = CreateMessage(functionId, "OriginalETag"); // Act Task <FunctionResult> task = product.ExecuteAsync(message, CancellationToken.None); // Assert task.WaitUntilCompleted(); mock.Verify(); Assert.True(task.Result.Succeeded); }
public void ExecuteAsync_IfInnerExecutorFails_ReturnsFailureResult() { // Arrange string functionId = "FunctionId"; string matchingETag = TouchBlob(TestContainerName, TestBlobName); 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 { BlobServiceClient = _blobServiceClient, 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 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); product.Register(functionId, CreateDummyTriggeredFunctionExecutor()); 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_IfBlobHasBeenDeleted_ReturnsSuccessResult() { // Arrange string functionId = "FunctionId"; // by default, Blob doesn't exist in the fake account, so it's as if it were deleted. BlobQueueTriggerExecutor product = CreateProductUnderTest(); BlobQueueRegistration registration = new BlobQueueRegistration { BlobServiceClient = _blobServiceClient, Executor = CreateDummyTriggeredFunctionExecutor() }; product.Register(functionId, registration); var message = CreateMessage(functionId, "OriginalETag"); // Act Task <FunctionResult> task = product.ExecuteAsync(message, CancellationToken.None); // Assert Assert.True(task.Result.Succeeded); // Validate log is written var logMessage = _loggerProvider.GetAllLogMessages().Single(); Assert.AreEqual("BlobNotFound", logMessage.EventId.Name); Assert.AreEqual(LogLevel.Debug, logMessage.Level); Assert.AreEqual(3, logMessage.State.Count()); Assert.AreEqual(TestBlobName, logMessage.GetStateValue <string>("blobName")); Assert.AreEqual(TestQueueMessageId, logMessage.GetStateValue <string>("queueMessageId")); Assert.True(!string.IsNullOrWhiteSpace(logMessage.GetStateValue <string>("{OriginalFormat}"))); }
public void ExecuteAsync_IfBlobIsUnchanged_CallsInnerExecutor() { // Arrange string functionId = "FunctionId"; string matchingETag = "ETag"; Guid expectedParentId = Guid.NewGuid(); IBlobETagReader eTagReader = CreateStubETagReader(matchingETag); IBlobCausalityReader causalityReader = CreateStubCausalityReader(expectedParentId); Mock <IFunctionExecutor> mock = new Mock <IFunctionExecutor>(MockBehavior.Strict); mock.Setup(e => e.TryExecuteAsync(It.Is <IFunctionInstance>(f => f.ParentId == expectedParentId), It.IsAny <CancellationToken>())) .Returns(Task.FromResult <IDelayedException>(null)) .Verifiable(); IFunctionExecutor innerExecutor = mock.Object; 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 task.WaitUntilCompleted(); mock.Verify(); }
public void ExecuteAsync_IfInnerExecutorFails_ReturnsFailureResult() { // Arrange string functionId = "FunctionId"; string matchingETag = "ETag"; IBlobETagReader eTagReader = CreateStubETagReader(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(eTagReader, causalityReader); ITriggeredFunctionExecutor innerExecutor = mock.Object; product.Register(functionId, innerExecutor); IStorageQueueMessage message = CreateMessage(functionId, matchingETag); // Act Task <FunctionResult> task = product.ExecuteAsync(message, CancellationToken.None); // Assert Assert.False(task.Result.Succeeded); }
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); BlobQueueRegistration registration = new BlobQueueRegistration { BlobClient = CreateClient(), Executor = CreateDummyTriggeredFunctionExecutor() }; product.Register(functionId, registration); 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 void ExecuteAsync_IfBlobHasBeenDeleted_ReturnsSuccessResult() { // Arrange var account = new FakeAccount(); string functionId = "FunctionId"; // by default, Blob doesn't exist in the fake account, so it's as if it were deleted. BlobQueueTriggerExecutor product = CreateProductUnderTest(); BlobQueueRegistration registration = new BlobQueueRegistration { BlobClient = account.CreateCloudBlobClient(), Executor = CreateDummyTriggeredFunctionExecutor() }; product.Register(functionId, registration); var message = CreateMessage(functionId, "OriginalETag"); // Act Task <FunctionResult> task = product.ExecuteAsync(message, CancellationToken.None); // Assert Assert.True(task.Result.Succeeded); }
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_IfInnerExecutorSucceeds_ReturnsSuccessResult() { // Arrange var account = new FakeAccount(); string functionId = "FunctionId"; string matchingETag = "ETag"; SetEtag(account, TestContainerName, TestBlobName, matchingETag); IBlobCausalityReader causalityReader = CreateStubCausalityReader(); FunctionResult expectedResult = new FunctionResult(true); 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.Same(expectedResult, task.Result); }
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(); }