public void Test_acquire_lock_with_timeout_works() { /* * This test flow goes something like: * 1. acquire firstLock * 2. Start a new thread that immediately returns and waits for a while * 3. Try to acquire second lock, but be patient and wait for up to 20 secs while retrying * 4. thread unlocks first lock after 700 ms * 5. thread waits 500 ms * 6. now we expect the second call to acquire to have succeeded, assert that this is true */ SqlServerDistributedAppLock firstLock = null; SqlServerDistributedAppLock secondLock = null; var lockName = "some-other-lock"; var locker = new SqlServerDistributedAppLockProvider(_connectionFactory); firstLock = (SqlServerDistributedAppLock)locker.Acquire(lockName, TimeSpan.FromSeconds(1)); Assert.True(firstLock.WasAcquiredInstantly); var threadStarted = false; // Create task to dispose of lock at some point Task.Factory.StartNew(() => { threadStarted = true; // Wait 700 ms to allow the main thread to start acquiring second lock var timeStart = DateTime.UtcNow; while (DateTime.UtcNow.Subtract(timeStart).TotalMilliseconds < 700) { // Do nothing } // release the first lock firstLock.Dispose(); // wait and the new lock should be acquired Task.Delay(TimeSpan.FromMilliseconds(500)); Assert.Equal(lockName, secondLock.Name); Assert.True(secondLock.IsActive); Assert.False(secondLock.WasAcquiredInstantly); Assert.True(secondLock.TimeUsedToAcquire.Ticks > 0); secondLock.Dispose(); }); // Thread creation can take some time // This waits for the thread to be created SpinWait.SpinUntil(() => threadStarted); // this second lock now enters retry mode secondLock = (SqlServerDistributedAppLock)locker.Acquire(lockName, TimeSpan.FromSeconds(20)); }
public void Test_that_is_acquired_is_false_when_disposed() { var provider = new SqlServerDistributedAppLockProvider(_connectionFactory); var theLock = provider.Acquire("this-is-my-lock"); theLock.Dispose(); Assert.False(theLock.IsActive); }
public void Acquire_sync_also_works() { const string lockName = "my-lock"; var locker = new SqlServerDistributedAppLockProvider(_connectionFactory); using (locker.Acquire(lockName)) { // mutual exclusion scope here } }
public void Cannot_acquire_lock_twice() { const string lockName = "second-lock"; var locker = new SqlServerDistributedAppLockProvider(_connectionFactory); using (locker.Acquire(lockName, TimeSpan.FromSeconds(1))) { var ex = Assert.Throws <DistributedAppLockException>(() => { // we have to create a new connection here as taking the lock twice via the same connection is OK var otherLocker = new SqlServerDistributedAppLockProvider(() => { var conn = new SqlConnection(_connectionString); conn.Open(); return(conn); }); return(otherLocker.Acquire(lockName)); }); Assert.Equal(DistributedAppLockExceptionReason.LockAlreadyAcquired, ex.Reason); } }