单元测试、死锁和争用条件
本文关键字:争用条件 死锁 单元测试 | 更新日期: 2023-09-27 17:47:21
关于如何为可能容易受到死锁和竞争条件影响的代码编写可重复的单元测试的任何建议?
现在我倾向于跳过单元测试并专注于压力测试。问题是您可以运行 5 次压力测试并看到五种不同的结果。
编辑:我知道这可能只是一个梦想,但如果有一种方法可以控制单个线程并使它们一次执行一条指令,那么我可能会到达某个地方。
看看TypeMock Racer(它处于测试阶段)
编辑:实际上是阿尔法
http://www.typemock.com/Typemock_software_development_tools.html
通常可以通过使用 ManualResetEvent 之类的东西来强制预见的竞争条件和死锁,以使每个线程在释放之前进入预期状态 - 即让线程 A 拥有锁并等待信号......获取线程 B 以请求锁等...
但是 - 您通常可以编写这样的测试来调查可疑的错误,以证明它何时被修复并且它不会重新出现。您通常会围绕竞争条件进行设计(但要尽可能实用地测试它们)。
您可以通过查看锁操作的顺序来编写一个检测潜在死锁的锁类。 我们通过拥有一个线程上下文来做到这一点,所有锁在获取时都会注册该上下文(可以使其成为仅 DEBUG 选项)。
这个想法是创建一个图形,其中节点表示锁,A 和 B 之间的有向边表示"获取锁 B 时持有锁 A"。 让您的程序使用正常负载运行,然后在图形中检查周期。 循环意味着即使您的代码没有命中它,也可能存在死锁。
认为寻找竞争条件真的属于单元测试的范畴。根据定义,或多或少,测试竞争条件的唯一方法是伪随机。除非你愿意努力正式证明你的锁定策略的正确性,否则你将不得不做一些压力测试。
您仍然需要编写单元测试,以验证算法的正确性,而不是锁定策略。
对多线程代码进行压力测试时,您需要在以下条件下进行测试:每个线程有一个 CPU,有多个线程共享 CPU,以及 CPU 多于线程(如果可能)。
想不出一个好的自动化方法,但我最接近的是编写一个可以"暴露"死锁的单元测试,除了单元测试之外,还使用断点。 我只是添加了一些关于在何处添加断点的说明。这涉及一些手动工作,但有了它们,您始终可以公开最糟糕情况的线程计划。
也许有人已经找到了自动化此类功能的好方法?我可以想象自动运行调试器,在特定行中断一个线程,让另一个线程运行直到特定条件,然后断言单元测试。
我之前在代码中使用了由请求中的某些参数触发的人为延迟。例如,一个请求告诉服务器在两次写入之间延迟写入,而另一个请求在两次写入之间没有延迟地执行写入。
Mark Bessey写道,这仅用于创建重现,而不适用于发现问题。
你试过Corensic Jinx吗?