How can you simulate/stress test about 100 users accessing a given shared resource (e.g. Database) in a c# unit test?
Assuming you're accessing real DB you're in the scope of integration tests. The simplest way is to access the resource from multiple threads. For example:
[Test]
public void SimpleStressTest()
{
bool wasExceptionThrown = false;
var threads = new Thread[100];
for(int i = 0; i < 100; i++)
{
threads[i] =
new Thread(new ThreadStart((Action)(() =>
{
try
{
AccessDB();
}
catch(Exception)
{
wasExceptionThrown = true;
}
})));
}
for(int i = 0; i < 100; i++)
{
threads[i].Start();
}
for(int i = 0; i < 100; i++)
{
threads[i].Join();
}
Assert.That(wasExceptionThrown, Is.False);
}
This test is not deterministic since you can't control the threads flow. If you want to make sure, for example, that 100 connections can be opened at the same time, you can place a hook in the logic of AccessDB()
which will force it to wait before it closes the connection to the DB.
For example, instead of the previous thread action:
try
{
AccessDB(sychObject);
}
catch(Exception)
{
wasExceptionThrown = true;
}
After starting all the threads make sure you have 100 threads waiting on the sychObject
and only then release it and join the threads. The same can be achieved by making the logic of CloseConnection()
(for example) virtual and write the test against an inheriting class the waits in CloseConnection()
. For example:
public class DataBase
{
public void AccessDB()
{
// Do logic here before closing connection
CloseConnection();
}
protected virtual void CloseConnection()
{
// Real Logic to close connection
}
}
public class FakeDataBase : DataBase
{
ManualResetEvent sychObject;
public FakeDataBase(ManualResetEvent sychObject)
{
this.sychObject = sychObject;
}
override protected void CloseConnection()
{
sychObject.WaitOne();
base.CloseConnection();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With