public async Task TryLockAsync_WithContention_NoRetry_DoesNotPollForLease()
        {
            CancellationToken cancellationToken = new CancellationToken();

            _mockStorageBlob.Setup(p => p.UploadTextAsync(string.Empty, null, It.Is <AccessCondition>(q => q.IfNoneMatchETag == "*"), null, null, cancellationToken)).Returns(Task.FromResult(true));

            int count = 0;

            _mockStorageBlob.Setup(p => p.AcquireLeaseAsync(_singletonConfig.LockPeriod, null, cancellationToken))
            .Returns(() =>
            {
                count++;
                return(Task.FromResult <string>(null));
            });

            SingletonAttribute attribute = new SingletonAttribute();

            SingletonManager.SingletonLockHandle lockHandle = (SingletonManager.SingletonLockHandle)
                                                              await _singletonManager.TryLockAsync(TestLockId, TestInstanceId, attribute, cancellationToken, retry : false);

            Assert.Null(lockHandle);
            Assert.Equal(1, count);

            _mockStorageBlob.VerifyAll();
        }
        public async Task TryLockAsync_CreatesBlob_WhenItDoesNotExist()
        {
            CancellationToken cancellationToken = new CancellationToken();
            RequestResult     storageResult     = new RequestResult
            {
                HttpStatusCode = 404
            };
            StorageException storageException = new StorageException(storageResult, null, null);

            int count = 0;

            _mockStorageBlob.Setup(p => p.AcquireLeaseAsync(_singletonConfig.LockPeriod, null, cancellationToken)).Returns(() =>
            {
                if (count++ == 0)
                {
                    throw storageException;
                }
                return(Task.FromResult(TestLeaseId));
            });

            _mockStorageBlob.Setup(p => p.UploadTextAsync(string.Empty, null, null, null, null, cancellationToken)).Returns(Task.FromResult(true));
            _mockStorageBlob.SetupGet(p => p.Metadata).Returns(_mockBlobMetadata);
            _mockStorageBlob.Setup(p => p.SetMetadataAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));
            _mockStorageBlob.Setup(p => p.ReleaseLeaseAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));

            SingletonAttribute attribute = new SingletonAttribute();

            SingletonManager.SingletonLockHandle lockHandle = (SingletonManager.SingletonLockHandle) await _singletonManager.TryLockAsync(TestLockId, TestInstanceId, attribute, cancellationToken);

            Assert.Same(_mockStorageBlob.Object, lockHandle.Blob);
            Assert.Equal(TestLeaseId, lockHandle.LeaseId);
            Assert.Equal(1, _mockStorageBlob.Object.Metadata.Keys.Count);
            Assert.Equal(_mockStorageBlob.Object.Metadata[SingletonManager.FunctionInstanceMetadataKey], TestInstanceId);
        }
        public async Task TryLockAsync_WithContention_PollsForLease()
        {
            CancellationToken cancellationToken = new CancellationToken();

            _mockStorageBlob.SetupGet(p => p.Metadata).Returns(_mockBlobMetadata);
            _mockStorageBlob.Setup(p => p.UploadTextAsync(string.Empty, null, It.Is <AccessCondition>(q => q.IfNoneMatchETag == "*"), null, null, cancellationToken)).Returns(Task.FromResult(true));
            _mockStorageBlob.Setup(p => p.SetMetadataAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));

            int numRetries = 3;
            int count      = 0;

            _mockStorageBlob.Setup(p => p.AcquireLeaseAsync(_singletonConfig.LockPeriod, null, cancellationToken))
            .Returns(() =>
            {
                count++;
                return(Task.FromResult <string>(count > numRetries ? TestLeaseId : null));
            });

            SingletonAttribute attribute = new SingletonAttribute();

            SingletonManager.SingletonLockHandle lockHandle = (SingletonManager.SingletonLockHandle) await _singletonManager.TryLockAsync(TestLockId, TestInstanceId, attribute, cancellationToken);

            Assert.Equal(TestLeaseId, lockHandle.LeaseId);
            Assert.Equal(numRetries, count - 1);
            Assert.NotNull(lockHandle.LeaseRenewalTimer);

            _mockStorageBlob.VerifyAll();
        }
示例#4
0
        public async Task ReleaseAsync_InvokesSingletonManager_WithExpectedValues()
        {
            CancellationToken  cancellationToken = new CancellationToken();
            SingletonAttribute attribute         = new SingletonAttribute();

            SingletonManager.SingletonLockHandle handle = new SingletonManager.SingletonLockHandle();

            Mock <SingletonManager> mockSingletonManager = new Mock <SingletonManager>(MockBehavior.Strict);

            mockSingletonManager.Setup(p => p.LockAsync(TestLockId, TestInstanceId, attribute, cancellationToken)).ReturnsAsync(handle);
            mockSingletonManager.Setup(p => p.ReleaseLockAsync(handle, cancellationToken)).Returns(Task.FromResult(true));

            SingletonLock singletonLock = new SingletonLock(TestLockId, TestInstanceId, attribute, mockSingletonManager.Object);

            Assert.False(singletonLock.IsHeld);
            await singletonLock.AcquireAsync(cancellationToken);

            Assert.True(singletonLock.IsHeld);
            await singletonLock.ReleaseAsync(cancellationToken);

            Assert.False(singletonLock.IsHeld);

            Assert.NotNull(singletonLock.AcquireStartTime);
            Assert.NotNull(singletonLock.AcquireEndTime);
            Assert.NotNull(singletonLock.ReleaseTime);
        }
        public async Task TryLockAsync_CreatesBlobLease_WithAutoRenewal()
        {
            CancellationToken cancellationToken = new CancellationToken();

            _mockStorageBlob.SetupGet(p => p.Metadata).Returns(_mockBlobMetadata);
            _mockStorageBlob.Setup(p => p.AcquireLeaseAsync(_singletonConfig.LockPeriod, null, cancellationToken)).ReturnsAsync(TestLeaseId);
            _mockStorageBlob.Setup(p => p.SetMetadataAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));
            _mockStorageBlob.Setup(p => p.ReleaseLeaseAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));

            int renewCount = 0;

            _mockStorageBlob.Setup(p => p.RenewLeaseAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, It.IsAny <CancellationToken>()))
            .Callback <AccessCondition, BlobRequestOptions, OperationContext, CancellationToken>(
                (mockAccessCondition, mockOptions, mockContext, mockCancellationToken) =>
            {
                renewCount++;
            }).Returns(Task.FromResult(true));

            SingletonAttribute attribute = new SingletonAttribute();

            SingletonManager.SingletonLockHandle lockHandle = (SingletonManager.SingletonLockHandle) await _singletonManager.TryLockAsync(TestLockId, TestInstanceId, attribute, cancellationToken);

            Assert.Same(_mockStorageBlob.Object, lockHandle.Blob);
            Assert.Equal(TestLeaseId, lockHandle.LeaseId);
            Assert.Equal(1, _mockStorageBlob.Object.Metadata.Keys.Count);
            Assert.Equal(_mockStorageBlob.Object.Metadata[SingletonManager.FunctionInstanceMetadataKey], TestInstanceId);

            // wait for enough time that we expect some lease renewals to occur
            int duration             = 2000;
            int expectedRenewalCount = (int)(duration / (_singletonConfig.LockPeriod.TotalMilliseconds / 2)) - 1;
            await Task.Delay(duration);

            Assert.Equal(expectedRenewalCount, renewCount);

            // now release the lock and verify no more renewals
            await _singletonManager.ReleaseLockAsync(lockHandle, cancellationToken);

            // verify the traces
            Assert.Equal(1, _trace.Traces.Count(p => p.ToString().Contains("Verbose Singleton lock acquired (testid)")));
            Assert.Equal(1, _trace.Traces.Count(p => p.ToString().Contains("Verbose Singleton lock released (testid)")));

            // verify the logger
            TestLogger logger = _loggerProvider.CreatedLoggers.Single() as TestLogger;

            Assert.Equal(LogCategories.Singleton, logger.Category);
            Assert.Equal(2, logger.LogMessages.Count);
            Assert.NotNull(logger.LogMessages.Single(m => m.Level == Extensions.Logging.LogLevel.Debug && m.FormattedMessage == "Singleton lock acquired (testid)"));
            Assert.NotNull(logger.LogMessages.Single(m => m.Level == Extensions.Logging.LogLevel.Debug && m.FormattedMessage == "Singleton lock released (testid)"));

            renewCount = 0;
            await Task.Delay(1000);

            Assert.Equal(0, renewCount);

            _mockStorageBlob.VerifyAll();
        }
        public async Task StartAsync_StartsListener_WhenLockAcquired()
        {
            CancellationToken cancellationToken = new CancellationToken();
            SingletonManager.SingletonLockHandle lockHandle = new SingletonManager.SingletonLockHandle();
            _mockSingletonManager.Setup(p => p.TryLockAsync(_lockId, null, _attribute, cancellationToken)).ReturnsAsync(lockHandle);
            _mockInnerListener.Setup(p => p.StartAsync(cancellationToken)).Returns(Task.FromResult(true));

            await _listener.StartAsync(cancellationToken);

            _mockSingletonManager.VerifyAll();
            _mockInnerListener.VerifyAll();
        }
示例#7
0
        public async Task StartAsync_StartsListener_WhenLockAcquired()
        {
            CancellationToken cancellationToken = new CancellationToken();

            SingletonManager.SingletonLockHandle lockHandle = new SingletonManager.SingletonLockHandle();
            _mockSingletonManager.Setup(p => p.TryLockAsync(_lockId, null, _attribute, cancellationToken)).ReturnsAsync(lockHandle);
            _mockInnerListener.Setup(p => p.StartAsync(cancellationToken)).Returns(Task.FromResult(true));

            await _listener.StartAsync(cancellationToken);

            _mockSingletonManager.VerifyAll();
            _mockInnerListener.VerifyAll();
        }
        public async Task TryLockAsync_CreatesBlobLease_WithAutoRenewal()
        {
            CancellationToken cancellationToken = new CancellationToken();

            _mockStorageBlob.SetupGet(p => p.Metadata).Returns(_mockBlobMetadata);
            _mockStorageBlob.Setup(p => p.UploadTextAsync(string.Empty, null, It.Is <AccessCondition>(q => q.IfNoneMatchETag == "*"), null, null, cancellationToken)).Returns(Task.FromResult(true));
            _mockStorageBlob.Setup(p => p.AcquireLeaseAsync(_singletonConfig.LockPeriod, null, cancellationToken)).ReturnsAsync(TestLeaseId);
            _mockStorageBlob.Setup(p => p.SetMetadataAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));
            _mockStorageBlob.Setup(p => p.ReleaseLeaseAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));

            int renewCount = 0;

            _mockStorageBlob.Setup(p => p.RenewLeaseAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, It.IsAny <CancellationToken>()))
            .Callback <AccessCondition, BlobRequestOptions, OperationContext, CancellationToken>(
                (mockAccessCondition, mockOptions, mockContext, mockCancellationToken) =>
            {
                renewCount++;
            }).Returns(Task.FromResult(true));

            SingletonAttribute attribute = new SingletonAttribute();

            SingletonManager.SingletonLockHandle lockHandle = (SingletonManager.SingletonLockHandle) await _singletonManager.TryLockAsync(TestLockId, TestInstanceId, attribute, cancellationToken);

            Assert.Same(_mockStorageBlob.Object, lockHandle.Blob);
            Assert.Equal(TestLeaseId, lockHandle.LeaseId);
            Assert.Equal(1, _mockStorageBlob.Object.Metadata.Keys.Count);
            Assert.Equal(_mockStorageBlob.Object.Metadata[SingletonManager.FunctionInstanceMetadataKey], TestInstanceId);

            // wait for enough time that we expect some lease renewals to occur
            int duration             = 2000;
            int expectedRenewalCount = (int)(duration / (_singletonConfig.LockPeriod.TotalMilliseconds / 2)) - 1;
            await Task.Delay(duration);

            Assert.Equal(expectedRenewalCount, renewCount);

            // now release the lock and verify no more renewals
            await _singletonManager.ReleaseLockAsync(lockHandle, cancellationToken);

            // verify the traces
            Assert.Equal(1, _trace.Traces.Count(p => p.Contains("Verbose WebJobs.Execution Waiting for Singleton lock (testid)")));
            Assert.Equal(1, _trace.Traces.Count(p => p.Contains("Verbose WebJobs.Execution Singleton lock acquired (testid)")));
            Assert.Equal(renewCount, _trace.Traces.Count(p => p.Contains("Renewing Singleton lock (testid)")));
            Assert.Equal(1, _trace.Traces.Count(p => p.Contains("Verbose WebJobs.Execution Singleton lock released (testid)")));

            renewCount = 0;
            await Task.Delay(1000);

            Assert.Equal(0, renewCount);

            _mockStorageBlob.VerifyAll();
        }
        public async Task TryAcquireLock_WhenLockAcquired_StopsLockTimerAndStartsListener()
        {
            _listener.LockTimer = new System.Timers.Timer
            {
                Interval = 30 * 1000
            };
            _listener.LockTimer.Start();

            SingletonManager.SingletonLockHandle lockHandle = new SingletonManager.SingletonLockHandle();
            _mockSingletonManager.Setup(p => p.TryLockAsync(_lockId, null, _attribute, CancellationToken.None, false))
            .ReturnsAsync(lockHandle);

            _mockInnerListener.Setup(p => p.StartAsync(CancellationToken.None)).Returns(Task.FromResult(true));

            await _listener.TryAcquireLock();

            Assert.Null(_listener.LockTimer);
        }
        public async Task AquireAsync_InvokesSingletonManager_WithExpectedValues()
        {
            CancellationToken cancellationToken = new CancellationToken();
            SingletonAttribute attribute = new SingletonAttribute();
            SingletonManager.SingletonLockHandle handle = new SingletonManager.SingletonLockHandle();

            Mock<SingletonManager> mockSingletonManager = new Mock<SingletonManager>(MockBehavior.Strict);
            mockSingletonManager.Setup(p => p.LockAsync(TestLockId, TestInstanceId, attribute, cancellationToken)).ReturnsAsync(handle);

            SingletonLock singletonLock = new SingletonLock(TestLockId, TestInstanceId, attribute, mockSingletonManager.Object);

            Assert.False(singletonLock.IsHeld);
            await singletonLock.AcquireAsync(cancellationToken);

            Assert.NotNull(singletonLock.AcquireStartTime);
            Assert.NotNull(singletonLock.AcquireEndTime);
            Assert.True(singletonLock.IsHeld);
        }
        public async Task ReleaseLockAsync_StopsRenewalTimerAndReleasesLease()
        {
            CancellationToken cancellationToken = new CancellationToken();

            Mock <ITaskSeriesTimer> mockRenewalTimer = new Mock <ITaskSeriesTimer>(MockBehavior.Strict);

            mockRenewalTimer.Setup(p => p.StopAsync(cancellationToken)).Returns(Task.FromResult(true));

            _mockStorageBlob.Setup(p => p.ReleaseLeaseAsync(It.Is <AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));

            SingletonManager.SingletonLockHandle handle = new SingletonManager.SingletonLockHandle
            {
                Blob              = _mockStorageBlob.Object,
                LeaseId           = TestLeaseId,
                LeaseRenewalTimer = mockRenewalTimer.Object
            };

            await _singletonManager.ReleaseLockAsync(handle, cancellationToken);

            mockRenewalTimer.VerifyAll();
        }
        public async Task StartAsync_DefaultsAcquisitionTimeout()
        {
            int expectedTimeoutSeconds = (int)_config.LockPeriod.TotalSeconds;
            CancellationToken cancellationToken = new CancellationToken();
            SingletonManager.SingletonLockHandle lockHandle = new SingletonManager.SingletonLockHandle();
            _mockSingletonManager.Setup(p => p.TryLockAsync(_lockId, null, _attribute, cancellationToken))
                .Callback<string, string, SingletonAttribute, CancellationToken>(
                    (mockLockId, mockInstanceId, mockAttribute, mockCancellationToken) => 
                    {
                        Assert.Equal(expectedTimeoutSeconds, mockAttribute.LockAcquisitionTimeout);
                    }) 
                .ReturnsAsync(lockHandle);
            _mockInnerListener.Setup(p => p.StartAsync(cancellationToken)).Returns(Task.FromResult(true));

            Assert.Null(_attribute.LockAcquisitionTimeout);
            await _listener.StartAsync(cancellationToken);
            Assert.Equal(expectedTimeoutSeconds, _attribute.LockAcquisitionTimeout);

            _mockSingletonManager.VerifyAll();
            _mockInnerListener.VerifyAll();
        }
示例#13
0
        public async Task StartAsync_DefaultsAcquisitionTimeout()
        {
            int expectedTimeoutSeconds          = (int)_config.LockPeriod.TotalSeconds;
            CancellationToken cancellationToken = new CancellationToken();

            SingletonManager.SingletonLockHandle lockHandle = new SingletonManager.SingletonLockHandle();
            _mockSingletonManager.Setup(p => p.TryLockAsync(_lockId, null, _attribute, cancellationToken))
            .Callback <string, string, SingletonAttribute, CancellationToken>(
                (mockLockId, mockInstanceId, mockAttribute, mockCancellationToken) =>
            {
                Assert.Equal(expectedTimeoutSeconds, mockAttribute.LockAcquisitionTimeout);
            })
            .ReturnsAsync(lockHandle);
            _mockInnerListener.Setup(p => p.StartAsync(cancellationToken)).Returns(Task.FromResult(true));

            Assert.Null(_attribute.LockAcquisitionTimeout);
            await _listener.StartAsync(cancellationToken);

            Assert.Equal(expectedTimeoutSeconds, _attribute.LockAcquisitionTimeout);

            _mockSingletonManager.VerifyAll();
            _mockInnerListener.VerifyAll();
        }
        public async Task TryAcquireLock_WhenLockAcquired_StopsLockTimerAndStartsListener()
        {
            _listener.LockTimer = new System.Timers.Timer
            {
                Interval = 30 * 1000
            };
            _listener.LockTimer.Start();

            SingletonManager.SingletonLockHandle lockHandle = new SingletonManager.SingletonLockHandle();
            _mockSingletonManager.Setup(p => p.TryLockAsync(_lockId, null, _attribute, CancellationToken.None, false))
                .ReturnsAsync(lockHandle);

            _mockInnerListener.Setup(p => p.StartAsync(CancellationToken.None)).Returns(Task.FromResult(true));

            await _listener.TryAcquireLock();

            Assert.Null(_listener.LockTimer);
        }
        public async Task ReleaseLockAsync_StopsRenewalTimerAndReleasesLease()
        {
            CancellationToken cancellationToken = new CancellationToken();

            Mock<ITaskSeriesTimer> mockRenewalTimer = new Mock<ITaskSeriesTimer>(MockBehavior.Strict);
            mockRenewalTimer.Setup(p => p.StopAsync(cancellationToken)).Returns(Task.FromResult(true));

            _mockStorageBlob.Setup(p => p.ReleaseLeaseAsync(It.Is<AccessCondition>(q => q.LeaseId == TestLeaseId), null, null, cancellationToken)).Returns(Task.FromResult(true));

            SingletonManager.SingletonLockHandle handle = new SingletonManager.SingletonLockHandle
            {
                Blob = _mockStorageBlob.Object,
                LeaseId = TestLeaseId,
                LeaseRenewalTimer = mockRenewalTimer.Object
            };

            await _singletonManager.ReleaseLockAsync(handle, cancellationToken);

            mockRenewalTimer.VerifyAll();
        }