csoltenborn / GoogleTestAdapter

Visual studio extension that adds support for the C++ testing framework Google Test.
Other
143 stars 100 forks source link

Test discovery fails with collect code coverage enabled if global thread_local smart pointer is in the test code #336

Closed jtl313 closed 2 years ago

jtl313 commented 2 years ago

We suddenly got a problem running our unit tests. After a bit of fiddling with the code I was able to extract a minimal example that display the same kind of problem. It seems that having a global thread_local smart pointer anywhere in the test code makes GTA fail to discover tests if code coverage is also collected. This is the problem code:

#include <gtest/gtest.h>
#include <memory>

namespace
{
    class Foo {};
    const thread_local Foo this_is_no_problem;
    const thread_local auto global_smart_ptr = std::make_unique<Foo>();  // Compiling with this enabled will cause vstest with code coverage enabled to fail.
}

TEST(threadinglocalstorage, test_thread_local)
{
    const thread_local auto local_smart_ptr = std::make_unique<Foo>();  // Compiling with this enabled is fine
    EXPECT_TRUE(true);
}

int main(int argc, char* argv[])
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

If running this code through the following vstest.console.exe mytest.exe /TestAdapterPath:<gta path> /Collect:"Code Coverage" test discovery fails with a message similar to:

[09:37:14.612] Google Test Adapter: Test execution starting...
[09:37:16.858 ERROR] Could not list test cases of executable 'mytest.exe': executing process failed with return code -1073741819
Command executed: 'mytest.exe --gtest_list_tests', working directory: 'x64\Release'
Command produced no output
[09:37:16.860] Found 0 tests in executable mytest.exe
[09:37:16.872] Google Test execution completed, overall duration: 00:00:02.3712331.
[

If I either remove /Collect:"Code Coverage" from the command line, or if I comment out the global_smart_pointer, everything runs just fine.

I have tested with GTA 0.17.1 and 0.18.0 and vstest.console.exe version 16.9.4 and 17.0.0 with the same result. The code is compiled with VS2019

Running mytest.exe --gtest_list_tests from the command line works fine in all situations.

Update: Interestingly the problem seem to only occur when linking statically with gtest. I used "Microsoft.googletest.v140.windesktop.msvcstl.static.rt-static" version="1.8.1.5". So the problem may be with gtest as well. Test code: https://github.com/jtl313/gta-test

csoltenborn commented 2 years ago

Thanks for the great bug report! However, I don't think that GTA is to blame here since it merely runs your executable with .NET's Process framework, but is not involved at all with collecting code coverage information - this is done by vstest.console.exe. I fear that I can't help here.

I would maybe try a different gtest version then the one provided by MS (e.g. add the gtest code to your solution, build it yourself, and link that version), or to talk to the MS Test guys providing vstest.console.exe. One more thing you could try is to use Test Adapter for Google Test (MS' clone of GTA) instead of GTA, but I expect the same behavior from that one.

Let me know if you could solve the problem - might be something for the trouble shooting section of the GTA docs!

csoltenborn commented 2 years ago

I will close this issue since it probably indeed is a VsTest problem, but in case relevant information is added to https://github.com/microsoft/codecoverage/issues/32 maybe you could leave a short notice here - thanks!