views:

611

answers:

5

Hello - I'm new to unit testing and nUnit (2.48). I'd like to write a test method where the failure case is that it deadlocks. Is this possible? Obviously nUnit doesn't know by default how long the method should take to execute, so would I have to write code to do the work on a separate thread and then abort it and throw and exception if it took longer than some time I define? Is there a better way to do this?

Thank you

+2  A: 

Well its certainly possible to test for a deadlock by running your code on another thread and seeing if it returns in a timely fashion. Here's some (very basic) example code:

[TestFixture]
public class DeadlockTests
{
    [Test]
    public void TestForDeadlock()
    {
        Thread thread = new Thread(ThreadFunction);
        thread.Start();
        if (!thread.Join(5000))
        {
            Assert.Fail("Deadlock detected");
        }
    }

    private void ThreadFunction()
    {
        // do something that causes a deadlock here
        Thread.Sleep(10000);
    }
}

I wouldn't like to say that this is the "best way", but it is one I have found useful on occasions.

Mark Heath
http://en.wikipedia.org/wiki/Halting_problem
bitschnau
What if the join would come after 5001 ms?
bitschnau
this has nothing to do with the halting problem. The "timely fashion" clause makes sure of that :-). One problem with this test is that it doesnt really test for deadlocks, it only runs one test-thread. Deadlocks usually occur in interaction between threads.
Mendelt
sure, its not a perfect test, but it is simple. In the thread.join, you specify a length of time that should be more than sufficient to run your code if there is no deadlock. You haven't proved that there is a deadlock, but that may not be necessary for this type of test.
Mark Heath
mendelt - yes, in ThreadFunction you are likely to need to create yet another thread.
Mark Heath
Ah. I see what you're doing now. ThreadFunction itself creates multiple threads that cause the deadlock. Then we agree. It won't catch all deadlocks but it might catch some ..
Mendelt
+3  A: 

It is possible but it might not be the best thing to do. Unit tests aren't really suitable for testing concurrency behaviour, unfortunately there aren't many test-methods that are suitable.

NUnit doesnt do anything with threads. You could write tests that start several threads and then test their interaction. But these would start to look more like integration tests than unit tests.

Another problem is that deadlock behaviour usually depends on the order threads are scheduled in. So it would be hard to write a conclusive test to test a certain deadlock issue because you don't have any control over the thread scheduling, this is done by the OS. You could end up with tests that sometimes fail on multicore processors but always succeed on single core processors.

Mendelt
+2  A: 

Take a look at the Microsoft Project called "Chess". It is designed to find concurred bugs http://research.microsoft.com/en-us/projects/chess/

Martin Moser
+2  A: 

Deadlock detection is equivalent to the halting problem, and therefore currently not solvable in the general case.

If you have a specific problem to guard against, there might be specific hacks to get at least a modicum of security. Be aware though, that this can only be a hack and never 100%. For example such a test might always pass on the development machine but never on the production machine.

David Schmitt
+3  A: 

To test for a deadlock, you must implement a state graph and a check for cycles in your current state graph in the unit test. The state graph consists of the ressources as nodes and the dependencies as edges. I have no idea of the implementation of such a thing, but thats the theory.

A unit test tests for the correctness of the in and output of data (mainly for the later point) and not for the correctness of the execution flow of your application.

Mark Heath's idea seems reasonable, but is academically wrong.

bitschnau