背景(如果不感兴趣,请跳到下面的问题)
我有一个运行在三个状态的模拟器:
>单线程启动(I / O ok)
>多线程内存cpu限制仿真阶段(I / O不好)
>后仿真,后连接单线程阶段(I / O ok)
有没有搞错!在标准测试期间,cpu使用率从100%下降到20%,总运行时间比正常(130秒vs 4.2秒)大约30倍.
当Callgrind没有显示任何可疑的时候,我的头嗡嗡嗡嗡嗡嗡嗡嗡嗡嗡…..,
沮丧的,我在一个运行期间走进了服务器房间,注意到讨厌的磨砂声,后来验证是由于写入到/proc/PID/fd的MysqL套接字!原来,第二阶段深层的几层MysqL代码正在引起问题.
得到教训
>意外的I / O可能是致命的实时应用程序
>单元测试还不够:我也需要基准测试
修复我将在ReadAllowed()和WriteAllowed()上引入线程本地存储的IOSentinels和asserts(),以确保第2阶段线程永远不会执行任何IO.
题
任何人都有运气与googletest附加/编写基准框架?
不幸的是,我所有的googletests都通过了这个时刻.如果我走了一会儿,回来,没有注意到运行时间,这将是一个灾难性的承诺,可能更难修复.
如果运行需要> 2或3次最后一个运行时,我希望googletest失败:最后一部分是棘手的,因为非常快速的运行,系统状态可能会导致一段时间,但仍然可以.但是对于长时间的模拟运行/测试,我并不希望运行时间会发生很大变化(> 50%是不寻常的).
我可以在这里提出建议,但是,如果系统突然变得缓慢,即使所有的输出似乎都可以,那么使用低维护检查可以使用自动化测试,这将是很明显的.
解决方法
不是那么简单
const clock_t t0 = clock(); // or gettimeofday or whatever int res = yourFunction(); const clock_t t1 = clock(); const double elapsedSec = (t1 - t0) / (double)CLOCKS_PER_SEC; EXPECT_EQ(EXPECTED,res); EXPECT_GT(10.0,elapsedSec);
在这里,您需要根据您的任务手动更改10.0.
当然,你可以进一步去
double prev = -1; { ifstream ifs("/var/tmp/time_record.txt"); ifs >> prev; } if (prev < 0) prev = DEFAULT_VALUE; ... EXPECT_GT(2 * prev,elapsedSec); { ofstream ofs("/var/tmp/time_record.txt"); ofs << elapsedSec << endl; }
但是我想这个额外的复杂性真的可以证明是正当的…