public void ExecuteAsync_IfLeasedReceiptBecameCompleted_ReleasesLeaseAndReturnsTrue() { // Arrange IStorageBlob blob = CreateBlobReference(); IBlobPathSource input = CreateBlobPath(blob); IBlobETagReader eTagReader = CreateStubETagReader("ETag"); Mock <IBlobReceiptManager> mock = CreateReceiptManagerReferenceMock(); int calls = 0; mock.Setup(m => m.TryReadAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(() => { int call = calls++; return(Task.FromResult(call == 0 ? BlobReceipt.Incomplete : BlobReceipt.Complete)); }); mock.Setup(m => m.TryAcquireLeaseAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult("LeaseId")); mock.Setup(m => m.ReleaseLeaseAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)) .Verifiable(); IBlobReceiptManager receiptManager = mock.Object; ITriggerExecutor <IStorageBlob> product = CreateProductUnderTest(input, eTagReader, receiptManager); // Act Task <bool> task = product.ExecuteAsync(blob, CancellationToken.None); // Assert task.WaitUntilCompleted(); mock.Verify(); Assert.True(task.Result); }
public void ExecuteAsync_IfLeasedReceiptBecameCompleted_ReleasesLeaseAndReturnsSuccessResult() { // Arrange BlobTriggerExecutorContext context = CreateExecutorContext(); IBlobPathSource input = CreateBlobPath(context.Blob); Mock <IBlobReceiptManager> mock = CreateReceiptManagerReferenceMock(); int calls = 0; mock.Setup(m => m.TryReadAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(() => { int call = calls++; return(Task.FromResult(call == 0 ? BlobReceipt.Incomplete : BlobReceipt.Complete)); }); mock.Setup(m => m.TryAcquireLeaseAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult("LeaseId")); mock.Setup(m => m.ReleaseLeaseAsync(It.IsAny <BlockBlobClient>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)) .Verifiable(); IBlobReceiptManager receiptManager = mock.Object; ITriggerExecutor <BlobTriggerExecutorContext> product = CreateProductUnderTest(input, receiptManager); // Act Task <FunctionResult> task = product.ExecuteAsync(context, CancellationToken.None); // Assert task.WaitUntilCompleted(); mock.Verify(); Assert.True(task.Result.Succeeded); }
public void ExecuteAsync_IfTryAcquireLeaseSucceeds_ReadsLatestReceipt() { // Arrange IStorageBlob blob = CreateBlobReference(); IBlobPathSource input = CreateBlobPath(blob); IBlobETagReader eTagReader = CreateStubETagReader("ETag"); Mock <IBlobReceiptManager> mock = CreateReceiptManagerReferenceMock(); int calls = 0; mock.Setup(m => m.TryReadAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(() => { return(Task.FromResult(calls++ == 0 ? BlobReceipt.Incomplete : BlobReceipt.Complete)); }); mock.Setup(m => m.TryAcquireLeaseAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult("LeaseId")); mock.Setup(m => m.ReleaseLeaseAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)); IBlobReceiptManager receiptManager = mock.Object; ITriggerExecutor <IStorageBlob> product = CreateProductUnderTest(input, eTagReader, receiptManager); // Act Task <bool> task = product.ExecuteAsync(blob, CancellationToken.None); // Assert task.GetAwaiter().GetResult(); Assert.Equal(2, calls); }
public void ExecuteAsync_IfIncompleteBlobReceiptExists_TriesToAcquireLease() { // Arrange IStorageBlob blob = CreateBlobReference(); IBlobPathSource input = CreateBlobPath(blob); IBlobETagReader eTagReader = CreateStubETagReader("ETag"); Mock <IBlobReceiptManager> mock = CreateReceiptManagerReferenceMock(); mock.Setup(m => m.TryReadAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(BlobReceipt.Incomplete)); mock.Setup(m => m.TryAcquireLeaseAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult <string>(null)) .Verifiable(); IBlobReceiptManager receiptManager = mock.Object; ITriggerExecutor <IStorageBlob> product = CreateProductUnderTest(input, eTagReader, receiptManager); // Act Task <bool> task = product.ExecuteAsync(blob, CancellationToken.None); // Assert task.GetAwaiter().GetResult(); mock.Verify(); }
public void ExecuteAsync_IfTryCreateReceiptSucceeds_TriesToAcquireLease() { // Arrange BlobTriggerExecutorContext context = CreateExecutorContext(); IBlobPathSource input = CreateBlobPath(context.Blob); Mock <IBlobReceiptManager> mock = CreateReceiptManagerReferenceMock(); mock.Setup(m => m.TryReadAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult <BlobReceipt>(null)); mock.Setup(m => m.TryCreateAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(true)); mock.Setup(m => m.TryAcquireLeaseAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult <string>(null)) .Verifiable(); IBlobReceiptManager receiptManager = mock.Object; ITriggerExecutor <BlobTriggerExecutorContext> product = CreateProductUnderTest(input, receiptManager); // Act Task <FunctionResult> task = product.ExecuteAsync(context, CancellationToken.None); // Assert task.GetAwaiter().GetResult(); mock.Verify(); }
public void ExecuteAsync_IfTryAcquireLeaseSucceeds_ReadsLatestReceipt() { // Arrange BlobTriggerExecutorContext context = CreateExecutorContext(); IBlobPathSource input = CreateBlobPath(context.Blob); Mock <IBlobReceiptManager> mock = CreateReceiptManagerReferenceMock(); int calls = 0; mock.Setup(m => m.TryReadAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(() => { return(Task.FromResult(calls++ == 0 ? BlobReceipt.Incomplete : BlobReceipt.Complete)); }); mock.Setup(m => m.TryAcquireLeaseAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult("LeaseId")); mock.Setup(m => m.ReleaseLeaseAsync(It.IsAny <BlockBlobClient>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)); IBlobReceiptManager receiptManager = mock.Object; ITriggerExecutor <BlobTriggerExecutorContext> product = CreateProductUnderTest(input, receiptManager); // Act Task <FunctionResult> task = product.ExecuteAsync(context, CancellationToken.None); // Assert task.GetAwaiter().GetResult(); Assert.AreEqual(2, calls); }
public void ExecuteAsync_IfCompletedBlobReceiptExists_ReturnsSuccessfulResult() { // Arrange BlobTriggerExecutorContext context = CreateExecutorContext(); IBlobPathSource input = CreateBlobPath(context.Blob); string expectedETag = context.Blob.BlobClient.GetProperties().Value.ETag.ToString(); IBlobReceiptManager receiptManager = CreateCompletedReceiptManager(); ITriggerExecutor <BlobTriggerExecutorContext> product = CreateProductUnderTest(input, receiptManager); // Act Task <FunctionResult> task = product.ExecuteAsync(context, CancellationToken.None); // Assert Assert.True(task.Result.Succeeded); // Validate log is written var logMessage = _loggerProvider.GetAllLogMessages().Single(); Assert.AreEqual("BlobAlreadyProcessed", logMessage.EventId.Name); Assert.AreEqual(LogLevel.Debug, logMessage.Level); Assert.AreEqual(6, logMessage.State.Count()); Assert.AreEqual("FunctionIdLogName", logMessage.GetStateValue <string>("functionName")); Assert.AreEqual(context.Blob.BlobClient.Name, logMessage.GetStateValue <string>("blobName")); Assert.AreEqual(expectedETag, logMessage.GetStateValue <string>("eTag")); Assert.AreEqual(context.PollId, logMessage.GetStateValue <string>("pollId")); Assert.AreEqual(context.TriggerSource, logMessage.GetStateValue <BlobTriggerScanSource>("triggerSource")); Assert.True(!string.IsNullOrWhiteSpace(logMessage.GetStateValue <string>("{OriginalFormat}"))); }
public void ExecuteAsync_IfBlobReceiptDoesNotExist_TriesToCreateReceipt() { // Arrange ICloudBlob blob = CreateBlobReference(); IBlobPathSource input = CreateBlobPath(blob); IBlobETagReader eTagReader = CreateStubETagReader("ETag"); Mock <IBlobReceiptManager> mock = CreateReceiptManagerReferenceMock(); mock.Setup(m => m.TryReadAsync(It.IsAny <CloudBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult <BlobReceipt>(null)); mock.Setup(m => m.TryCreateAsync(It.IsAny <CloudBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(false)) .Verifiable(); IBlobReceiptManager receiptManager = mock.Object; ITriggerExecutor <ICloudBlob> product = CreateProductUnderTest(input, eTagReader, receiptManager); // Act Task <FunctionResult> task = product.ExecuteAsync(blob, CancellationToken.None); // Assert task.GetAwaiter().GetResult(); mock.Verify(); }
public BlobTriggerExecutor(string hostId, string functionId, IBlobPathSource input, IBlobETagReader eTagReader, IBlobReceiptManager receiptManager, IBlobTriggerQueueWriter queueWriter) { _hostId = hostId; _functionId = functionId; _input = input; _queueWriter = queueWriter; _eTagReader = eTagReader; _receiptManager = receiptManager; }
public BlobTriggerExecutor(string hostId, FunctionDescriptor functionDescriptor, IBlobPathSource input, IBlobReceiptManager receiptManager, IBlobTriggerQueueWriter queueWriter, ILogger <BlobListener> logger) { _hostId = hostId; _functionDescriptor = functionDescriptor; _input = input; _queueWriter = queueWriter; _receiptManager = receiptManager; _logger = logger ?? throw new ArgumentNullException(nameof(logger)); }
private BlobTriggerExecutor CreateProductUnderTest(string functionId, IBlobPathSource input, IBlobReceiptManager receiptManager, IBlobTriggerQueueWriter queueWriter) { var descriptor = new FunctionDescriptor { Id = functionId, LogName = functionId + "LogName" }; return(new BlobTriggerExecutor(String.Empty, descriptor, input, receiptManager, queueWriter, _logger)); }
public void ExecuteAsync_IfLeasedIncompleteReceipt_EnqueuesMessageMarksCompletedReleasesLeaseAndReturnsTrue() { // Arrange string expectedFunctionId = "FunctionId"; string expectedETag = "ETag"; IStorageBlob blob = CreateBlobReference("container", "blob"); IBlobPathSource input = CreateBlobPath(blob); IBlobETagReader eTagReader = CreateStubETagReader(expectedETag); Mock <IBlobReceiptManager> managerMock = CreateReceiptManagerReferenceMock(); managerMock .Setup(m => m.TryReadAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(BlobReceipt.Incomplete)); managerMock .Setup(m => m.TryAcquireLeaseAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult("LeaseId")); managerMock .Setup(m => m.MarkCompletedAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)) .Verifiable(); managerMock .Setup(m => m.ReleaseLeaseAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)) .Verifiable(); IBlobReceiptManager receiptManager = managerMock.Object; Mock <IBlobTriggerQueueWriter> queueWriterMock = new Mock <IBlobTriggerQueueWriter>(MockBehavior.Strict); queueWriterMock .Setup(w => w.EnqueueAsync(It.IsAny <BlobTriggerMessage>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)); IBlobTriggerQueueWriter queueWriter = queueWriterMock.Object; ITriggerExecutor <IStorageBlob> product = CreateProductUnderTest(expectedFunctionId, input, eTagReader, receiptManager, queueWriter); // Act Task <bool> task = product.ExecuteAsync(blob, CancellationToken.None); // Assert task.WaitUntilCompleted(); queueWriterMock .Verify( w => w.EnqueueAsync(It.Is <BlobTriggerMessage>(m => m != null && m.FunctionId == expectedFunctionId && m.BlobType == StorageBlobType.BlockBlob && m.BlobName == blob.Name && m.ContainerName == blob.Container.Name && m.ETag == expectedETag), It.IsAny <CancellationToken>()), Times.Once()); managerMock.Verify(); Assert.True(task.Result); }
public void ExecuteAsync_IfCompletedBlobReceiptExists_ReturnsTrue() { // Arrange IStorageBlob blob = CreateBlobReference(); IBlobPathSource input = CreateBlobPath(blob); IBlobETagReader eTagReader = CreateStubETagReader("ETag"); IBlobReceiptManager receiptManager = CreateCompletedReceiptManager(); ITriggerExecutor <IStorageBlob> product = CreateProductUnderTest(input, eTagReader, receiptManager); // Act Task <bool> task = product.ExecuteAsync(blob, CancellationToken.None); // Assert Assert.True(task.Result); }
public void ExecuteAsync_IfEnqueueAsyncThrows_ReleasesLease() { // Arrange IStorageBlob blob = CreateBlobReference(); IBlobPathSource input = CreateBlobPath(blob); IBlobETagReader eTagReader = CreateStubETagReader("ETag"); InvalidOperationException expectedException = new InvalidOperationException(); Mock <IBlobReceiptManager> mock = CreateReceiptManagerReferenceMock(); mock.Setup(m => m.TryReadAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(BlobReceipt.Incomplete)); mock.Setup(m => m.TryAcquireLeaseAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult("LeaseId")); mock.Setup(m => m.ReleaseLeaseAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)) .Verifiable(); IBlobReceiptManager receiptManager = mock.Object; Mock <IBlobTriggerQueueWriter> queueWriterMock = new Mock <IBlobTriggerQueueWriter>(MockBehavior.Strict); queueWriterMock .Setup(w => w.EnqueueAsync(It.IsAny <BlobTriggerMessage>(), It.IsAny <CancellationToken>())) .Throws(expectedException); IBlobTriggerQueueWriter queueWriter = queueWriterMock.Object; ITriggerExecutor <IStorageBlob> product = CreateProductUnderTest(input, eTagReader, receiptManager, queueWriter); // Act Task <bool> task = product.ExecuteAsync(blob, CancellationToken.None); // Assert task.WaitUntilCompleted(); mock.Verify(); InvalidOperationException exception = Assert.Throws <InvalidOperationException>( () => task.GetAwaiter().GetResult()); Assert.Same(expectedException, exception); }
public void ExecuteAsync_IfTryAcquireLeaseFails_ReturnsFailureResult() { // Arrange BlobTriggerExecutorContext context = CreateExecutorContext(); IBlobPathSource input = CreateBlobPath(context.Blob); Mock <IBlobReceiptManager> mock = CreateReceiptManagerReferenceMock(); mock.Setup(m => m.TryReadAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(BlobReceipt.Incomplete)); mock.Setup(m => m.TryAcquireLeaseAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult <string>(null)); IBlobReceiptManager receiptManager = mock.Object; ITriggerExecutor <BlobTriggerExecutorContext> product = CreateProductUnderTest(input, receiptManager); // Act Task <FunctionResult> task = product.ExecuteAsync(context, CancellationToken.None); // Assert Assert.False(task.Result.Succeeded); }
public void ExecuteAsync_IfTryCreateReceiptFails_ReturnsFalse() { // Arrange IStorageBlob blob = CreateBlobReference(); IBlobPathSource input = CreateBlobPath(blob); IBlobETagReader eTagReader = CreateStubETagReader("ETag"); Mock <IBlobReceiptManager> mock = CreateReceiptManagerReferenceMock(); mock.Setup(m => m.TryReadAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult <BlobReceipt>(null)); mock.Setup(m => m.TryCreateAsync(It.IsAny <IStorageBlockBlob>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(false)); IBlobReceiptManager receiptManager = mock.Object; ITriggerExecutor <IStorageBlob> product = CreateProductUnderTest(input, eTagReader, receiptManager); // Act Task <bool> task = product.ExecuteAsync(blob, CancellationToken.None); // Assert Assert.False(task.Result); }
private static BlobTriggerExecutor CreateProductUnderTest(string functionId, IBlobPathSource input, IBlobETagReader eTagReader, IBlobReceiptManager receiptManager, IBlobTriggerQueueWriter queueWriter) { return new BlobTriggerExecutor(String.Empty, functionId, input, eTagReader, receiptManager, queueWriter); }
private static BlobTriggerExecutor CreateProductUnderTest(IBlobPathSource input, IBlobETagReader eTagReader, IBlobReceiptManager receiptManager, IBlobTriggerQueueWriter queueWriter) { return CreateProductUnderTest("FunctionId", input, eTagReader, receiptManager, queueWriter); }
public void ExecuteAsync_IfLeasedIncompleteReceipt_EnqueuesMessageMarksCompletedReleasesLeaseAndReturnsSuccessResult() { // Arrange string expectedFunctionId = "FunctionId"; BlobTriggerExecutorContext context = CreateExecutorContext(); string expectedETag = context.Blob.BlobClient.GetProperties().Value.ETag.ToString(); IBlobPathSource input = CreateBlobPath(context.Blob); Mock <IBlobReceiptManager> managerMock = CreateReceiptManagerReferenceMock(); managerMock .Setup(m => m.TryReadAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(BlobReceipt.Incomplete)); managerMock .Setup(m => m.TryAcquireLeaseAsync(It.IsAny <BlockBlobClient>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult("LeaseId")); managerMock .Setup(m => m.MarkCompletedAsync(It.IsAny <BlockBlobClient>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)) .Verifiable(); managerMock .Setup(m => m.ReleaseLeaseAsync(It.IsAny <BlockBlobClient>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(0)) .Verifiable(); IBlobReceiptManager receiptManager = managerMock.Object; Mock <IBlobTriggerQueueWriter> queueWriterMock = new Mock <IBlobTriggerQueueWriter>(MockBehavior.Strict); queueWriterMock .Setup(w => w.EnqueueAsync(It.IsAny <BlobTriggerMessage>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(("testQueueName", "testMessageId"))); IBlobTriggerQueueWriter queueWriter = queueWriterMock.Object; ITriggerExecutor <BlobTriggerExecutorContext> product = CreateProductUnderTest(expectedFunctionId, input, receiptManager, queueWriter); // Act Task <FunctionResult> task = product.ExecuteAsync(context, CancellationToken.None); // Assert task.WaitUntilCompleted(); queueWriterMock .Verify( w => w.EnqueueAsync(It.Is <BlobTriggerMessage>(m => m != null && m.FunctionId == expectedFunctionId /*&& m.BlobType == StorageBlobType.BlockBlob $$$ */ && m.BlobName == context.Blob.BlobClient.Name && m.ContainerName == context.Blob.BlobClient.BlobContainerName && m.ETag == expectedETag), It.IsAny <CancellationToken>()), Times.Once()); managerMock.Verify(); Assert.True(task.Result.Succeeded); // Validate log is written var logMessage = _loggerProvider.GetAllLogMessages().Single(); Assert.AreEqual("BlobMessageEnqueued", logMessage.EventId.Name); Assert.AreEqual(LogLevel.Debug, logMessage.Level); Assert.AreEqual(7, logMessage.State.Count()); Assert.AreEqual("FunctionIdLogName", logMessage.GetStateValue <string>("functionName")); Assert.AreEqual(context.Blob.BlobClient.Name, logMessage.GetStateValue <string>("blobName")); Assert.AreEqual("testQueueName", logMessage.GetStateValue <string>("queueName")); Assert.AreEqual("testMessageId", logMessage.GetStateValue <string>("messageId")); Assert.AreEqual(context.PollId, logMessage.GetStateValue <string>("pollId")); Assert.AreEqual(context.TriggerSource, logMessage.GetStateValue <BlobTriggerScanSource>("triggerSource")); Assert.True(!string.IsNullOrWhiteSpace(logMessage.GetStateValue <string>("{OriginalFormat}"))); }
private BlobTriggerExecutor CreateProductUnderTest(IBlobPathSource input, IBlobReceiptManager receiptManager) { return(CreateProductUnderTest("FunctionId", input, receiptManager, CreateDummyQueueWriter())); }
private static BlobTriggerExecutor CreateProductUnderTest(string functionId, IBlobPathSource input, IBlobETagReader eTagReader, IBlobReceiptManager receiptManager, IBlobTriggerQueueWriter queueWriter) { return(new BlobTriggerExecutor(String.Empty, functionId, input, eTagReader, receiptManager, queueWriter)); }
private static BlobTriggerExecutor CreateProductUnderTest(IBlobPathSource input, IBlobETagReader eTagReader, IBlobReceiptManager receiptManager, IBlobTriggerQueueWriter queueWriter) { return(CreateProductUnderTest("FunctionId", input, eTagReader, receiptManager, queueWriter)); }