Reputation: 1540
How do I test if a function blocks indefinitely in a particular situation?
[Test]
public void BlockingTest()
{
blockingFunction(); // this function halts execution indefinitely
Assert.Fail("Execution not halted.");
}
Supposing blockingFunction()
is a function waiting for something to happen, that should block execution until a particular event occurs, and the test supposes this event to never occurr.
EDIT: what I'm actually looking for is an elegant solution, possibly without having to explicitly wait a hardcoded time before reporting success.
Posting my current situation for reference:
[Test]
public void BlockTest() {
BytesStream bs = new BytesStream();
bs.Write(new byte[] { 1, 2 }, 0, 2);
var buff2 = new byte[2];
bs.Read(buff2, 0, 2);
bool dataWritten = false;
new Thread(() => {
for(int i=0; i<100; i++)
Thread.Sleep(0); // ensure the parent thread execute next line
dataWritten = true;
bs.Write(new byte[] { 3, 4 }, 0, 2);
}).Start();
Assert.AreNotEqual(0, bs.Read(buff2, 0, 2), "#1");
if(!dataWritten)
Assert.Fail("#2");
Assert.AreEqual(new byte[] { 3, 4 }, buff2, "#3");
}
Upvotes: 0
Views: 757
Reputation: 6220
One idea if you have a trigger that should wake up the call:
In thread a:
In thread b:
Upvotes: 0
Reputation: 203829
How do I test if a function blocks indefinitely in a particular situation?
This is called the Halting Problem. It is provably impossible to solve.
Upvotes: 3
Reputation: 4165
You have already answered your question. Your test method will wait an indefinite amount of time and fail should the blockingFunction
return any sooner. Just let it run and fix the code should it ever fail.
Now to answer the real problem here: what do you really want to test?
Is it actually a requirement that the blockingFunction
blocks execution? I'd presume that if it would consume queue items without blocking execution, it'd be even better – but your fictional test would fail then.
In other words: I assume it's not important that your blockingFunction
blocks, you should test business logic and not technical behavior, unless there is an actual use case.
Like if your consumer were to terminate if no item would be generated within t
seconds, then you could wait for t
seconds and fail if it returned any sooner.
If you wanted to test whether your consumer "wakes up" after being idle for a while, you could wait for n
seconds and then generate an item. Fail it the consumer does something earlier, and fail if it doesn't consume after you generate your item.
Only you can truly answer this question, for we don't know what you actually want to test here. I hope I managed to spell that out in a helpful way.
Upvotes: 0
Reputation: 1258
Maybe let your function execute by a Threadpool object and see if it returns within a specified timespan, like this:
[Test]
public void BlockingTest()
{
AutoResetEvent ev = new AutoResetEvent(false);
BlockingFunctionHelper(ev);
// specify time out in ms, thus here: wait 1 s
Assert.IsTrue(ev.WaitOne(1000), "Execution not halted.");
ev.Dispose();
}
private void BlockingFunctionHelper(AutoResetEvent ev)
{
ThreadPool.QueueUserWorkItem((e) =>
{
BlockingFunction(); // this function halts execution indefinitely
((AutoResetEvent) e).Set();
}, ev);
}
Upvotes: 1