Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 单元测试预期和非预期死锁行为的合理策略_Unit Testing_Language Agnostic_Deadlock_Verification - Fatal编程技术网

Unit testing 单元测试预期和非预期死锁行为的合理策略

Unit testing 单元测试预期和非预期死锁行为的合理策略,unit-testing,language-agnostic,deadlock,verification,Unit Testing,Language Agnostic,Deadlock,Verification,我想知道我应该如何测试一些可以阻止的对象,等待其他参与者。要测试的特定单元是参与者之间的通道,参与者本身是用于测试的模拟装置 验证参与者是否在预期的时间内执行死锁会很好,但这对我来说并不十分重要,因为死锁后发生的事情可以合理地描述为未定义 更重要的是验证参与者定义的交互不会死锁 在这两种情况下,我都不确定最佳测试策略应该是什么。我目前的想法是让测试运行者为每个参与者启动一个线程,休眠一段时间,然后发现子线程是否已返回。在它们没有及时返回的情况下,假设它们已经死锁,并安全地终止线程,测试失败(或者

我想知道我应该如何测试一些可以阻止的对象,等待其他参与者。要测试的特定单元是参与者之间的通道,参与者本身是用于测试的模拟装置

验证参与者是否在预期的时间内执行死锁会很好,但这对我来说并不十分重要,因为死锁后发生的事情可以合理地描述为未定义

更重要的是验证参与者定义的交互不会死锁

在这两种情况下,我都不确定最佳测试策略应该是什么。我目前的想法是让测试运行者为每个参与者启动一个线程,休眠一段时间,然后发现子线程是否已返回。在它们没有及时返回的情况下,假设它们已经死锁,并安全地终止线程,测试失败(或者在预期死锁的情况下成功)

这感觉有点像概率论,因为可能有各种各样的原因(无论多么不可能)导致线程可能需要比预期更长的时间才能完成。有没有其他解决这个问题的好方法

编辑:我相信测试的可靠性会很好,但我不认为我需要它。我在考虑三个层次的测试确定性

  • “实际行为已证明与预期行为匹配”死锁不会发生
  • “实际行为与预期行为匹配”死锁在N个测试中未发生
  • “实际行为与预期行为一致”N在预期期限内完成的测试
第一个当然是一个值得通过的测试,但ShiDoiSi的回答说明了这一点的不切实际。第二个明显弱于第一个,但仍然很硬;如何确定一个流程网络实际上已经死锁?我不确定这比第一个更容易证明(可能更难)


最后一个更像我的想法

对于没有死锁的测试,您可以使用NUnit的TimeoutAttribute的等效项,如果执行时间超过上限,它将中止测试并使测试失败。你可以想出一个好的超时值,例如,如果测试没有在30秒内完成,那么就是出了问题


我不确定(或者我没有遇到过这样的情况)是否会断言死锁已经发生。死锁通常是不可取的。我很难理解如何编写一个失败的单元测试,除非测试块——单元测试通常被认为是快速和无阻塞的。

学术界可能会告诉你(事实上它现在正在告诉你),你应该对一些所谓的模型检查框架()进行忠实的抽象。然后模拟抽象执行(通过所有可能的调度程序交错进行穷举搜索)。当然,诀窍是确保抽象实际上是忠实的。您不再检查程序的实际源代码,而是检查其他语言的源代码

否则,我会想到一些严厉的方法,比如对特定的语言使用(做一些非常类似的事情)。 类似的研究原型也存在于C中,并且在这项业务中使用了专门的工具

您正在研究计算机科学研究中的一个热门话题,对于非平凡/真实系统,无论是穷举测试还是形式验证都不容易适用于真实代码

一种有价值的方法是对代码进行检测,以便它能够检测到死锁,并可能尝试恢复。为了检测死锁,使用一组C宏来跟踪锁的使用情况,并通过该机制进行跟踪。但同样,很少发生的错误也很少被发现


(免责声明:我没有参与上面链接的任何商业工具——我添加它们只是为了让您感觉到所面临问题的难度。)

既然您已经做了足够的抽象来模拟参与者,为什么不进一步抽象线程同步(互斥、信号量等等)?

当您考虑什么构成死锁时,您可以在测试中使用专门的、死锁感知的线程同步器。通过“死锁感知”,我不是说它应该通过使用超时等强力方式检测死锁,而是通过标志、计数器等方式了解导致死锁的情况。它可以检测死锁,同时可选地提供预期的线程同步功能。我的基本意思是,在测试中使用插入指令的线程同步


这太抽象了,说起来容易做起来难。我并没有声称自己成功地做到了这一点。我可能只是在这里傻了。但是,如果您可以只提供一个(不完整的)测试,那么这个问题可能会受到更具体的攻击。

可靠地测试死锁的唯一方法是检测并报告锁定子系统。上次我不得不这么做时,我们构建了一个调试版本,记录了哪些线程持有哪些锁,并在每次lock-get调用中检查潜在的死锁。在一个有很多锁的系统中,它可能是一个重量级的操作,但我们发现它非常有价值,因此我们重新组织了子系统,这样我们就可以在运行时通过开关打开和关闭它,即使在生产构建中也是如此。

这本书有一些关于如何在多线程代码上运行测试的技巧。很抱歉,我不能分享更深刻的东西,但我从未测试过对僵局做出优雅反应的东西。我创建的测试只是为了确保没有死锁。测试无死锁与测试死锁是一样的;即使出现死锁,测试仍必须完成,