单元测试实时/并发软件

2022-09-01 16:05:16

可能的重复:
我应该如何对线程代码进行单元测试?

经典的单元测试基本上只是把x放进去,并期望y出来,然后自动化这个过程。因此,它适用于测试任何不涉及时间的内容。但是,我遇到的大多数非平凡的错误都与时机有关。线程会损坏彼此的数据,或导致死锁。非决定性行为发生 - 在一百万分之一中。困难的东西。

对于多线程并发系统的“单元测试”部分有什么有用的吗?这些测试是如何工作的?难道没有必要长时间运行这种测试的主题,并以某种聪明的方式改变环境,以合理地确信它能正常工作吗?


答案 1

这些天我所做的大部分工作都涉及多线程和/或分布式系统。大多数 bug 都涉及“发生在”类型的错误,其中开发人员(错误地)假设事件 A 将始终发生在事件 B 之前。但是,每运行程序 1000000 次,事件 B 首先发生,这会导致不可预知的行为。

此外,没有任何好的工具来检测计时问题,甚至由争用条件引起的数据损坏。Valgrind工具包中的Helgrind和drd等工具非常适合普通的程序,但它们在诊断大型复杂系统方面并不是很有用。首先,他们经常报告误报(特别是Helglind)。另一方面,在Helglid/drd下运行时很难真正检测到某些错误,因为在Helglrind下运行的程序运行速度几乎慢了1000倍,并且您经常需要运行程序相当长的时间才能重现争用条件。此外,由于在Helglid下运行完全改变了程序的时间,因此可能无法重现某个时间问题。这就是微妙的时间问题;他们几乎是海森堡式的,因为改变程序以检测时序问题可能会掩盖原始问题。

可悲的事实是,人类仍然没有做好充分的准备来处理复杂的并发软件。所以不幸的是,没有简单的方法来对它进行单元测试。特别是对于分布式系统,您应该使用Lamport的发生前图仔细规划程序,以帮助您识别程序中事件的必要顺序。但最终,您无法真正摆脱随机变化输入的暴力单元测试。它还有助于在单元测试期间改变线程上下文切换的频率,例如,运行另一个仅占用CPU周期的后台进程。此外,如果您有权访问集群,则可以并行运行多个单元测试,这可以更快地检测错误并节省大量时间。


答案 2

如果你可以在Linux下运行你的测试,valgrind包含一个名为helgrind的工具,该工具旨在检测使用pthread的程序中的竞争条件和潜在的死锁;在此下运行多线程代码可能会带来一些好处,因为它会报告潜在的错误,即使这些错误实际上并未在该特定测试运行中发生。


推荐