220 lines
5.0 KiB
C#
220 lines
5.0 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AMWD.Common.Tests.Extensions
|
|
{
|
|
[TestClass]
|
|
public class ReaderWriterLockSlimExtensionsTest
|
|
{
|
|
[TestMethod]
|
|
public void ShouldEnterReadLock()
|
|
{
|
|
// arrange
|
|
var rwLock = new ReaderWriterLockSlim();
|
|
|
|
// act
|
|
using var disposable = rwLock.GetReadLock();
|
|
|
|
// assert
|
|
Assert.IsNotNull(disposable);
|
|
Assert.IsTrue(rwLock.IsReadLockHeld);
|
|
Assert.IsFalse(rwLock.IsUpgradeableReadLockHeld);
|
|
Assert.IsFalse(rwLock.IsWriteLockHeld);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldEnterUpgradeableReadLock()
|
|
{
|
|
// arrange
|
|
var rwLock = new ReaderWriterLockSlim();
|
|
|
|
// act
|
|
using var disposable = rwLock.GetUpgradeableReadLock();
|
|
|
|
// assert
|
|
Assert.IsNotNull(disposable);
|
|
Assert.IsFalse(rwLock.IsReadLockHeld);
|
|
Assert.IsTrue(rwLock.IsUpgradeableReadLockHeld);
|
|
Assert.IsFalse(rwLock.IsWriteLockHeld);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldAllowWriteLockAfterUpgradableReadLock()
|
|
{
|
|
// arrange
|
|
var rwLockUsing = new ReaderWriterLockSlim();
|
|
var rwLockClassic = new ReaderWriterLockSlim();
|
|
|
|
// act
|
|
using var disposableReadUsing = rwLockUsing.GetUpgradeableReadLock();
|
|
using (rwLockUsing.GetWriteLock())
|
|
{
|
|
// assert
|
|
Assert.IsTrue(rwLockUsing.IsUpgradeableReadLockHeld);
|
|
Assert.IsTrue(rwLockUsing.IsWriteLockHeld);
|
|
}
|
|
// assert
|
|
Assert.IsTrue(rwLockUsing.IsUpgradeableReadLockHeld);
|
|
Assert.IsFalse(rwLockUsing.IsWriteLockHeld);
|
|
|
|
// act
|
|
using (rwLockClassic.GetUpgradeableReadLock())
|
|
{
|
|
rwLockClassic.EnterWriteLock();
|
|
|
|
// assert
|
|
Assert.IsTrue(rwLockClassic.IsUpgradeableReadLockHeld);
|
|
Assert.IsTrue(rwLockClassic.IsWriteLockHeld);
|
|
}
|
|
// assert
|
|
Assert.IsFalse(rwLockClassic.IsUpgradeableReadLockHeld);
|
|
Assert.IsFalse(rwLockClassic.IsWriteLockHeld);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldEnterWriteLock()
|
|
{
|
|
// arrange
|
|
var rwLock = new ReaderWriterLockSlim();
|
|
|
|
// act
|
|
using var disposable = rwLock.GetWriteLock();
|
|
|
|
// assert
|
|
Assert.IsNotNull(disposable);
|
|
Assert.IsFalse(rwLock.IsReadLockHeld);
|
|
Assert.IsFalse(rwLock.IsUpgradeableReadLockHeld);
|
|
Assert.IsTrue(rwLock.IsWriteLockHeld);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldNotAllowWriteLockAfterReadLock()
|
|
{
|
|
// arrange
|
|
var rwLock = new ReaderWriterLockSlim();
|
|
|
|
// act
|
|
using var disposableRead = rwLock.GetReadLock();
|
|
try
|
|
{
|
|
using var disposaleWrite = rwLock.GetWriteLock();
|
|
Assert.Fail();
|
|
}
|
|
catch (LockRecursionException)
|
|
{ }
|
|
|
|
// assert
|
|
Assert.IsNotNull(disposableRead);
|
|
Assert.IsTrue(rwLock.IsReadLockHeld);
|
|
Assert.IsFalse(rwLock.IsUpgradeableReadLockHeld);
|
|
Assert.IsFalse(rwLock.IsWriteLockHeld);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldAllowWriteLockAfterUpgradeableReadLock()
|
|
{
|
|
// arrange
|
|
var rwLock = new ReaderWriterLockSlim();
|
|
|
|
// act
|
|
using var disposableRead = rwLock.GetUpgradeableReadLock();
|
|
using var disposableWrite = rwLock.GetWriteLock();
|
|
|
|
// assert
|
|
Assert.IsNotNull(disposableRead);
|
|
Assert.IsNotNull(disposableWrite);
|
|
Assert.IsFalse(rwLock.IsReadLockHeld);
|
|
Assert.IsTrue(rwLock.IsUpgradeableReadLockHeld);
|
|
Assert.IsTrue(rwLock.IsWriteLockHeld);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldGetTimeoutOnReadLock()
|
|
{
|
|
// arrange
|
|
var rwLock = new ReaderWriterLockSlim();
|
|
bool isTimeout = false;
|
|
|
|
// act
|
|
using var disposableRead = rwLock.GetWriteLock();
|
|
var awaitableTask = Task.Run(() =>
|
|
{
|
|
try
|
|
{
|
|
using var disposableRead = rwLock.GetReadLock(10);
|
|
Assert.Fail();
|
|
}
|
|
catch (TimeoutException)
|
|
{
|
|
isTimeout = true;
|
|
}
|
|
catch (Exception)
|
|
{ /* keep it quiet */ }
|
|
});
|
|
awaitableTask.Wait();
|
|
|
|
// assert
|
|
Assert.IsTrue(isTimeout);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldGetTimeoutOnUpgradeableReadLock()
|
|
{
|
|
// arrange
|
|
var rwLock = new ReaderWriterLockSlim();
|
|
bool isTimeout = false;
|
|
|
|
// act
|
|
using var disposableRead = rwLock.GetWriteLock();
|
|
var awaitableTask = Task.Run(() =>
|
|
{
|
|
try
|
|
{
|
|
using var disposableRead = rwLock.GetUpgradeableReadLock(10);
|
|
Assert.Fail();
|
|
}
|
|
catch (TimeoutException)
|
|
{
|
|
isTimeout = true;
|
|
}
|
|
catch (Exception)
|
|
{ /* keep it quiet */ }
|
|
});
|
|
awaitableTask.Wait();
|
|
|
|
// assert
|
|
Assert.IsTrue(isTimeout);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ShouldGetTimeoutOnWriteLock()
|
|
{
|
|
// arrange
|
|
var rwLock = new ReaderWriterLockSlim();
|
|
bool isTimeout = false;
|
|
|
|
// act
|
|
using var disposableRead = rwLock.GetReadLock();
|
|
var awaitableTask = Task.Run(() =>
|
|
{
|
|
try
|
|
{
|
|
using var disposableRead = rwLock.GetWriteLock(10);
|
|
Assert.Fail();
|
|
}
|
|
catch (TimeoutException)
|
|
{
|
|
isTimeout = true;
|
|
}
|
|
catch (Exception)
|
|
{ /* keep it quiet */ }
|
|
});
|
|
awaitableTask.Wait();
|
|
|
|
// assert
|
|
Assert.IsTrue(isTimeout);
|
|
}
|
|
}
|
|
}
|