我从在Windows上测试GoogleMock (1.8.0版)开始。我想举一个例子,说明它不是线程安全的。在成功地证明了这一点之后,我想证明同样的测试在Linux上运行得很好。然而,这一做法失败了。这不符合我的期望。因为GoogleMock文档说它是或者应该是线程安全的,所以它在Linux上应该是线程安全的。我必须将-pthread添加到链接器命令行以构建可执行文件。这意味着GoogleMock或GoogleTest确实使用了线程。
这是我用于测试的代码:
#include <thread>
#include <vector>
#include "gmock/gmock.h"
class Dummy
{
public:
virtual void SomeMethod(int) {}
};
class DummyMock : public Dummy
{
public:
MOCK_METHOD1(SomeMethod, void(int));
};
using ::testing::Exactly;
constexpr static int nrCallsPerThread = 100 * 1000;
constexpr static int nrThreads = 10;
TEST(SomeTest, Test100)
{
DummyMock dummy;
std::vector<std::thread> threads;
for (int i = 0; i < nrThreads; i++)
{
EXPECT_CALL(dummy, SomeMethod(i)).Times(Exactly(nrCallsPerThread));
threads.emplace_back([&dummy, i]
{
for (int j = 0; j < nrCallsPerThread; j++)
{
dummy.SomeMethod(i);
}
});
}
for (auto& t: threads)
{
t.join();
}
}
int main(int argc, char** argv)
{
testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}问题是,在Linux上,没有公开所有的执行。但是使用--gtest_repeat=100运行可执行文件的命中率接近100%。
在Windows上,如果获得带有Debug Assertion Failed!的Expression: vector iterator not decrementable消息,则使用Visual 2015。
在LinuxUbuntu17.04上,当我从命令行运行Debug构建时,我得到了[ FATAL ] ../googletest-release-1.8.0/googletest/include/gtest/internal/gtest-port.h:1928:: pthread_mutex_lock(&mutex_)failed with error 22。
当在Linux上的调试器中运行时,程序(通常)在gtest-port.h行1100处被中断,这是这个回调堆栈中的第2行:
0 0x5555555a6633 testing::Cardinality::ConservativeUpperBound() const () (??:??)
1 0x5555555a1a13 testing::internal::ExpectationBase::CheckActionCountIfNotDone() const () (??:??)
2 0x555555563f98 testing::internal::TypedExpectation<void (int)>::ShouldHandleArguments(std::tuple<int> const&) const(this=0x5555557f58a0, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1100)
3 0x55555556397d testing::internal::FunctionMockerBase<void (int)>::FindMatchingExpectationLocked(std::tuple<int> const&) const(this=0x7fffffffde38, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1723)
4 0x555555563578 testing::internal::FunctionMockerBase<void (int)>::UntypedFindMatchingExpectation(void const*, void const**, bool*, std::ostream*, std::ostream*)(this=0x7fffffffde38, untyped_args=0x7fffde7fbe14, untyped_action=0x7fffde7fb7d0, is_excessive=0x7fffde7fb7c7, what=0x7fffde7fb900, why=0x7fffde7fba90) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1687)
5 0x5555555a265e testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith(void const*) () (??:??)
6 0x55555555fcba testing::internal::FunctionMockerBase<void (int)>::InvokeWith(std::tuple<int> const&)(this=0x7fffffffde38, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1585)
7 0x55555555f16c testing::internal::FunctionMocker<void (int)>::Invoke(int)(this=0x7fffffffde38, a1=1) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h:101)
8 0x55555555ecb6 DummyMock::SomeMethod(this=0x7fffffffde30, gmock_a1=1) (/home/jos/Programming/ThreadSafeGMock/main.cpp:16)
9 0x55555555d31e SomeTest_Test100_Test::<lambda()>::operator()(void) const(__closure=0x5555557f5478) (/home/jos/Programming/ThreadSafeGMock/main.cpp:36)
10 0x55555555de98 std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()>::_M_invoke<>(std::_Index_tuple<>)(this=0x5555557f5478) (/usr/include/c++/6/functional:1391)
11 0x55555555de22 std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()>::operator()(void)(this=0x5555557f5478) (/usr/include/c++/6/functional:1380)
12 0x55555555ddf2 std::thread::_State_impl<std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()> >::_M_run(void)(this=0x5555557f5470) (/usr/include/c++/6/thread:197)
13 0x7ffff7b0a83f ??() (/usr/lib/x86_64-linux-gnu/libstdc++.so.6:??)
14 0x7ffff76216da start_thread(arg=0x7fffde7fc700) (pthread_create.c:456)
15 0x7ffff735b17f clone() (../sysdeps/unix/sysv/linux/x86_64/clone.S:105)因为它应该是线程安全的,我怀疑我做错了什么。但我看不出是什么。还是我在GoogleTest或GoogleMock中碰到了一个bug?
发布于 2017-06-26 08:03:50
从精美的手册上看:
重要注意: Google要求在调用模拟函数之前设置期望,否则行为就是未定义的。特别是,不能将EXPECT_CALL()的调用和对模拟函数的调用交织在一起。
您的原始代码在我的系统(cygwin)上间歇性地失败,错误22,或者有时没有任何消息/错误代码。这种修改工作得完美无缺:
for (int i = 0; i < nrThreads; i++)
{
EXPECT_CALL(dummy, SomeMethod(i)).Times(Exactly(nrCallsPerThread));
}
std::vector<std::thread> threads;
for (int i = 0; i < nrThreads; i++)
{
threads.emplace_back([&dummy, i] ...https://stackoverflow.com/questions/44750012
复制相似问题