【问题标题】:Testing for a deadlock with nUnit使用 nUnit 测试死锁
【发布时间】:2010-10-03 03:06:18
【问题描述】:

我是单元测试和 nUnit (2.48) 的新手。我想写一个测试方法,失败的情况是它死锁。这可能吗?显然,nUnit 默认情况下不知道该方法应该执行多长时间,所以我是否必须编写代码在单独的线程上完成工作,然后如果它花费的时间超过我定义的时间,则中止它并抛出异常?有没有更好的方法来做到这一点?

谢谢

【问题讨论】:

    标签: c# unit-testing nunit deadlock


    【解决方案1】:

    当然可以通过在另一个线程上运行您的代码并查看它是否及时返回来测试死锁。这是一些(非常基本的)示例代码:

    [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);
        }
    }
    

    我不想说这是“最好的方法”,但我发现它有时很有用。

    【讨论】:

    • 如果加入会在 5001 毫秒之后出现怎么办?
    • 这与停机问题无关。 “及时时尚”条款确保了这一点:-)。这个测试的一个问题是它并没有真正测试死锁,它只运行一个测试线程。死锁通常发生在线程之间的交互中。
    • 当然,这不是一个完美的测试,但它很简单。在 thread.join 中,您指定的时间长度应该足以在没有死锁的情况下运行您的代码。您尚未证明存在死锁,但这对于此类测试可能不是必需的。
    • mendelt - 是的,在 ThreadFunction 中您可能需要创建另一个线程。
    • 啊。我明白你现在在做什么。 ThreadFunction 本身会创建多个导致死锁的线程。然后我们同意。它不会捕获所有死锁,但它可能会捕获一些..
    【解决方案2】:

    这是可能的,但它可能不是最好的做法。单元测试并不真正适合测试并发行为,不幸的是,适合的测试方法并不多。

    NUnit 不对线程做任何事情。您可以编写启动多个线程的测试,然后测试它们的交互。但是这些看起来更像是集成测试而不是单元测试。

    另一个问题是死锁行为通常取决于线程调度的顺序。因此很难编写一个结论性的测试来测试某个死锁问题,因为您无法控制线程调度,这是由操作系统完成。您最终可能会遇到有时在多核处理器上失败但在单核处理器上总是成功的测试。

    【讨论】:

      【解决方案3】:

      死锁检测等价于halting problem,因此目前一般情况下无法解决。

      如果您有特定的问题需要防范,可能会有特定的黑客攻击来获得至少一点安全性。但请注意,这只能是一种黑客行为,而且永远不会 100%。例如,这样的测试可能总是在开发机器上通过,但在生产机器上永远不会通过。

      【讨论】:

        【解决方案4】:

        看看名为“国际象棋”的微软项目。 它旨在找到并发的错误http://research.microsoft.com/en-us/projects/chess/

        【讨论】:

          【解决方案5】:

          要测试死锁,您必须在单元测试中实现状态图并检查当前状态图中的循环。状态图由作为节点的资源和作为边的依赖关系组成。 我不知道这样的事情的实现,但这就是理论。

          单元测试测试数据输入和输出的正确性(主要是为了后面一点),而不是测试应用程序执行流程的正确性。

          Mark Heath 的想法看似合理,但在学术上是错误的。

          【讨论】:

            猜你喜欢
            • 2016-05-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-08-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多