Reland: Optimize Google Test process startup
Google Test performs hidden test registration during process startup. For test binaries that contain a large number of tests, this registration can be costly. In this CL, we reduce the overhead of registration via several tactics: - Treat CodeLocation and FilePath as value types, using std::move to pass them around. - Reduce string copies in various places by either passing std::string values via std::move, or passing const-refs to std::string instances. - Use std::to_string to stringify an int in DefaultParamName rather than a std::stringstream. - Pull some std::string instances out of nested loops in ParameterizedTestSuiteInfo::RegisterTests so as to reuse some allocations, and replace stringstream with ordinary string appends. - Use std::unordered_map in UnitTestImpl::GetTestSuite and ParameterizedTestSuiteRegistry::GetTestSuitePatternHolder to spend a little memory to turn O(N) lookups into constant time lookpus. - Use range-based for loops in a few places. - Use emplace-ish methods to add to containers where appropriate. All together, these changes reduce the overall runtime of a series of 50 death tests in a single Chromium test executable by ~38% due to the fact that the registration costs are paid in every death test's child process. PiperOrigin-RevId: 613833210 Change-Id: I51a262a770edff98ffa1e3b60c4d78a8308f9a9f
This commit is contained in:
parent
31993dfa6b
commit
e1a38bc370
@ -607,7 +607,7 @@ class GTEST_API_ TestInfo {
|
|||||||
friend class internal::UnitTestImpl;
|
friend class internal::UnitTestImpl;
|
||||||
friend class internal::StreamingListenerTest;
|
friend class internal::StreamingListenerTest;
|
||||||
friend TestInfo* internal::MakeAndRegisterTestInfo(
|
friend TestInfo* internal::MakeAndRegisterTestInfo(
|
||||||
const char* test_suite_name, const char* name, const char* type_param,
|
std::string test_suite_name, const char* name, const char* type_param,
|
||||||
const char* value_param, internal::CodeLocation code_location,
|
const char* value_param, internal::CodeLocation code_location,
|
||||||
internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
|
internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
|
||||||
internal::TearDownTestSuiteFunc tear_down_tc,
|
internal::TearDownTestSuiteFunc tear_down_tc,
|
||||||
@ -615,7 +615,7 @@ class GTEST_API_ TestInfo {
|
|||||||
|
|
||||||
// Constructs a TestInfo object. The newly constructed instance assumes
|
// Constructs a TestInfo object. The newly constructed instance assumes
|
||||||
// ownership of the factory object.
|
// ownership of the factory object.
|
||||||
TestInfo(const std::string& test_suite_name, const std::string& name,
|
TestInfo(std::string test_suite_name, std::string name,
|
||||||
const char* a_type_param, // NULL if not a type-parameterized test
|
const char* a_type_param, // NULL if not a type-parameterized test
|
||||||
const char* a_value_param, // NULL if not a value-parameterized test
|
const char* a_value_param, // NULL if not a value-parameterized test
|
||||||
internal::CodeLocation a_code_location,
|
internal::CodeLocation a_code_location,
|
||||||
@ -683,7 +683,7 @@ class GTEST_API_ TestSuite {
|
|||||||
// this is not a type-parameterized test.
|
// this is not a type-parameterized test.
|
||||||
// set_up_tc: pointer to the function that sets up the test suite
|
// set_up_tc: pointer to the function that sets up the test suite
|
||||||
// tear_down_tc: pointer to the function that tears down the test suite
|
// tear_down_tc: pointer to the function that tears down the test suite
|
||||||
TestSuite(const char* name, const char* a_type_param,
|
TestSuite(const std::string& name, const char* a_type_param,
|
||||||
internal::SetUpTestSuiteFunc set_up_tc,
|
internal::SetUpTestSuiteFunc set_up_tc,
|
||||||
internal::TearDownTestSuiteFunc tear_down_tc);
|
internal::TearDownTestSuiteFunc tear_down_tc);
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
#include "gtest/internal/gtest-string.h"
|
#include "gtest/internal/gtest-string.h"
|
||||||
@ -70,8 +71,9 @@ class GTEST_API_ FilePath {
|
|||||||
public:
|
public:
|
||||||
FilePath() : pathname_("") {}
|
FilePath() : pathname_("") {}
|
||||||
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
|
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
|
||||||
|
FilePath(FilePath&& rhs) : pathname_(std::move(rhs.pathname_)) {}
|
||||||
|
|
||||||
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
|
explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) {
|
||||||
Normalize();
|
Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +81,10 @@ class GTEST_API_ FilePath {
|
|||||||
Set(rhs);
|
Set(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
FilePath& operator=(FilePath&& rhs) {
|
||||||
|
pathname_ = std::move(rhs.pathname_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
|
void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
|
||||||
|
|
||||||
|
@ -474,8 +474,8 @@ using SetUpTestSuiteFunc = void (*)();
|
|||||||
using TearDownTestSuiteFunc = void (*)();
|
using TearDownTestSuiteFunc = void (*)();
|
||||||
|
|
||||||
struct CodeLocation {
|
struct CodeLocation {
|
||||||
CodeLocation(const std::string& a_file, int a_line)
|
CodeLocation(std::string a_file, int a_line)
|
||||||
: file(a_file), line(a_line) {}
|
: file(std::move(a_file)), line(a_line) {}
|
||||||
|
|
||||||
std::string file;
|
std::string file;
|
||||||
int line;
|
int line;
|
||||||
@ -564,7 +564,7 @@ struct SuiteApiResolver : T {
|
|||||||
// The newly created TestInfo instance will assume
|
// The newly created TestInfo instance will assume
|
||||||
// ownership of the factory object.
|
// ownership of the factory object.
|
||||||
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
|
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
|
||||||
const char* test_suite_name, const char* name, const char* type_param,
|
std::string test_suite_name, const char* name, const char* type_param,
|
||||||
const char* value_param, CodeLocation code_location,
|
const char* value_param, CodeLocation code_location,
|
||||||
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
||||||
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
|
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
|
||||||
@ -595,8 +595,7 @@ class GTEST_API_ TypedTestSuitePState {
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
posix::Abort();
|
posix::Abort();
|
||||||
}
|
}
|
||||||
registered_tests_.insert(
|
registered_tests_.emplace(test_name, CodeLocation(file, line));
|
||||||
::std::make_pair(test_name, CodeLocation(file, line)));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,7 +699,7 @@ class TypeParameterizedTest {
|
|||||||
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
|
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
|
||||||
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
// Types). Valid values for 'index' are [0, N - 1] where N is the
|
||||||
// length of Types.
|
// length of Types.
|
||||||
static bool Register(const char* prefix, const CodeLocation& code_location,
|
static bool Register(const char* prefix, CodeLocation code_location,
|
||||||
const char* case_name, const char* test_names, int index,
|
const char* case_name, const char* test_names, int index,
|
||||||
const std::vector<std::string>& type_names =
|
const std::vector<std::string>& type_names =
|
||||||
GenerateNames<DefaultNameGenerator, Types>()) {
|
GenerateNames<DefaultNameGenerator, Types>()) {
|
||||||
@ -712,8 +711,7 @@ class TypeParameterizedTest {
|
|||||||
// list.
|
// list.
|
||||||
MakeAndRegisterTestInfo(
|
MakeAndRegisterTestInfo(
|
||||||
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
|
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
|
||||||
"/" + type_names[static_cast<size_t>(index)])
|
"/" + type_names[static_cast<size_t>(index)]),
|
||||||
.c_str(),
|
|
||||||
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
|
||||||
GetTypeName<Type>().c_str(),
|
GetTypeName<Type>().c_str(),
|
||||||
nullptr, // No value parameter.
|
nullptr, // No value parameter.
|
||||||
@ -725,13 +723,9 @@ class TypeParameterizedTest {
|
|||||||
new TestFactoryImpl<TestClass>);
|
new TestFactoryImpl<TestClass>);
|
||||||
|
|
||||||
// Next, recurses (at compile time) with the tail of the type list.
|
// Next, recurses (at compile time) with the tail of the type list.
|
||||||
return TypeParameterizedTest<Fixture, TestSel,
|
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>::
|
||||||
typename Types::Tail>::Register(prefix,
|
Register(prefix, std::move(code_location), case_name, test_names,
|
||||||
code_location,
|
index + 1, type_names);
|
||||||
case_name,
|
|
||||||
test_names,
|
|
||||||
index + 1,
|
|
||||||
type_names);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -739,7 +733,7 @@ class TypeParameterizedTest {
|
|||||||
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
template <GTEST_TEMPLATE_ Fixture, class TestSel>
|
||||||
class TypeParameterizedTest<Fixture, TestSel, internal::None> {
|
class TypeParameterizedTest<Fixture, TestSel, internal::None> {
|
||||||
public:
|
public:
|
||||||
static bool Register(const char* /*prefix*/, const CodeLocation&,
|
static bool Register(const char* /*prefix*/, CodeLocation,
|
||||||
const char* /*case_name*/, const char* /*test_names*/,
|
const char* /*case_name*/, const char* /*test_names*/,
|
||||||
int /*index*/,
|
int /*index*/,
|
||||||
const std::vector<std::string>& =
|
const std::vector<std::string>& =
|
||||||
@ -786,7 +780,8 @@ class TypeParameterizedTestSuite {
|
|||||||
|
|
||||||
// Next, recurses (at compile time) with the tail of the test list.
|
// Next, recurses (at compile time) with the tail of the test list.
|
||||||
return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
|
return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
|
||||||
Types>::Register(prefix, code_location,
|
Types>::Register(prefix,
|
||||||
|
std::move(code_location),
|
||||||
state, case_name,
|
state, case_name,
|
||||||
SkipComma(test_names),
|
SkipComma(test_names),
|
||||||
type_names);
|
type_names);
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ namespace internal {
|
|||||||
// TEST_P macro is used to define two tests with the same name
|
// TEST_P macro is used to define two tests with the same name
|
||||||
// but in different namespaces.
|
// but in different namespaces.
|
||||||
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
|
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
|
||||||
CodeLocation code_location);
|
const CodeLocation& code_location);
|
||||||
|
|
||||||
template <typename>
|
template <typename>
|
||||||
class ParamGeneratorInterface;
|
class ParamGeneratorInterface;
|
||||||
@ -379,9 +380,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
|||||||
// integer test parameter index.
|
// integer test parameter index.
|
||||||
template <class ParamType>
|
template <class ParamType>
|
||||||
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
|
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
|
||||||
Message name_stream;
|
return std::to_string(info.index);
|
||||||
name_stream << info.index;
|
|
||||||
return name_stream.GetString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = int>
|
template <typename T = int>
|
||||||
@ -513,9 +512,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
|
||||||
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
|
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
|
||||||
|
|
||||||
explicit ParameterizedTestSuiteInfo(const char* name,
|
explicit ParameterizedTestSuiteInfo(std::string name,
|
||||||
CodeLocation code_location)
|
CodeLocation code_location)
|
||||||
: test_suite_name_(name), code_location_(code_location) {}
|
: test_suite_name_(std::move(name)),
|
||||||
|
code_location_(std::move(code_location)) {}
|
||||||
|
|
||||||
// Test suite base name for display purposes.
|
// Test suite base name for display purposes.
|
||||||
const std::string& GetTestSuiteName() const override {
|
const std::string& GetTestSuiteName() const override {
|
||||||
@ -529,20 +529,21 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
// prefix). test_base_name is the name of an individual test without
|
// prefix). test_base_name is the name of an individual test without
|
||||||
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
||||||
// test suite base name and DoBar is test base name.
|
// test suite base name and DoBar is test base name.
|
||||||
void AddTestPattern(const char* test_suite_name, const char* test_base_name,
|
void AddTestPattern(const char*,
|
||||||
|
const char* test_base_name,
|
||||||
TestMetaFactoryBase<ParamType>* meta_factory,
|
TestMetaFactoryBase<ParamType>* meta_factory,
|
||||||
CodeLocation code_location) {
|
CodeLocation code_location) {
|
||||||
tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo(
|
tests_.emplace_back(
|
||||||
test_suite_name, test_base_name, meta_factory, code_location)));
|
new TestInfo(test_base_name, meta_factory, std::move(code_location)));
|
||||||
}
|
}
|
||||||
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
|
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
|
||||||
// about a generator.
|
// about a generator.
|
||||||
int AddTestSuiteInstantiation(const std::string& instantiation_name,
|
int AddTestSuiteInstantiation(std::string instantiation_name,
|
||||||
GeneratorCreationFunc* func,
|
GeneratorCreationFunc* func,
|
||||||
ParamNameGeneratorFunc* name_func,
|
ParamNameGeneratorFunc* name_func,
|
||||||
const char* file, int line) {
|
const char* file, int line) {
|
||||||
instantiations_.push_back(
|
instantiations_.emplace_back(std::move(instantiation_name), func, name_func,
|
||||||
InstantiationInfo(instantiation_name, func, name_func, file, line));
|
file, line);
|
||||||
return 0; // Return value used only to run this method in namespace scope.
|
return 0; // Return value used only to run this method in namespace scope.
|
||||||
}
|
}
|
||||||
// UnitTest class invokes this method to register tests in this test suite
|
// UnitTest class invokes this method to register tests in this test suite
|
||||||
@ -553,34 +554,31 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
void RegisterTests() override {
|
void RegisterTests() override {
|
||||||
bool generated_instantiations = false;
|
bool generated_instantiations = false;
|
||||||
|
|
||||||
for (typename TestInfoContainer::iterator test_it = tests_.begin();
|
std::string test_suite_name;
|
||||||
test_it != tests_.end(); ++test_it) {
|
std::string test_name;
|
||||||
std::shared_ptr<TestInfo> test_info = *test_it;
|
for (const std::shared_ptr<TestInfo>& test_info : tests_) {
|
||||||
for (typename InstantiationContainer::iterator gen_it =
|
for (const InstantiationInfo& instantiation : instantiations_) {
|
||||||
instantiations_.begin();
|
const std::string& instantiation_name = instantiation.name;
|
||||||
gen_it != instantiations_.end(); ++gen_it) {
|
ParamGenerator<ParamType> generator((*instantiation.generator)());
|
||||||
const std::string& instantiation_name = gen_it->name;
|
ParamNameGeneratorFunc* name_func = instantiation.name_func;
|
||||||
ParamGenerator<ParamType> generator((*gen_it->generator)());
|
const char* file = instantiation.file;
|
||||||
ParamNameGeneratorFunc* name_func = gen_it->name_func;
|
int line = instantiation.line;
|
||||||
const char* file = gen_it->file;
|
|
||||||
int line = gen_it->line;
|
|
||||||
|
|
||||||
std::string test_suite_name;
|
|
||||||
if (!instantiation_name.empty())
|
if (!instantiation_name.empty())
|
||||||
test_suite_name = instantiation_name + "/";
|
test_suite_name = instantiation_name + "/";
|
||||||
test_suite_name += test_info->test_suite_base_name;
|
else
|
||||||
|
test_suite_name.clear();
|
||||||
|
test_suite_name += test_suite_name_;
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
std::set<std::string> test_param_names;
|
std::set<std::string> test_param_names;
|
||||||
for (typename ParamGenerator<ParamType>::iterator param_it =
|
for (const auto& param : generator) {
|
||||||
generator.begin();
|
|
||||||
param_it != generator.end(); ++param_it, ++i) {
|
|
||||||
generated_instantiations = true;
|
generated_instantiations = true;
|
||||||
|
|
||||||
Message test_name_stream;
|
test_name.clear();
|
||||||
|
|
||||||
std::string param_name =
|
std::string param_name =
|
||||||
name_func(TestParamInfo<ParamType>(*param_it, i));
|
name_func(TestParamInfo<ParamType>(param, i));
|
||||||
|
|
||||||
GTEST_CHECK_(IsValidParamName(param_name))
|
GTEST_CHECK_(IsValidParamName(param_name))
|
||||||
<< "Parameterized test name '" << param_name
|
<< "Parameterized test name '" << param_name
|
||||||
@ -592,23 +590,25 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
<< "Duplicate parameterized test name '" << param_name << "', in "
|
<< "Duplicate parameterized test name '" << param_name << "', in "
|
||||||
<< file << " line " << line << std::endl;
|
<< file << " line " << line << std::endl;
|
||||||
|
|
||||||
test_param_names.insert(param_name);
|
|
||||||
|
|
||||||
if (!test_info->test_base_name.empty()) {
|
if (!test_info->test_base_name.empty()) {
|
||||||
test_name_stream << test_info->test_base_name << "/";
|
test_name.append(test_info->test_base_name).append("/");
|
||||||
}
|
}
|
||||||
test_name_stream << param_name;
|
test_name += param_name;
|
||||||
|
|
||||||
|
test_param_names.insert(std::move(param_name));
|
||||||
|
|
||||||
MakeAndRegisterTestInfo(
|
MakeAndRegisterTestInfo(
|
||||||
test_suite_name.c_str(), test_name_stream.GetString().c_str(),
|
test_suite_name, test_name.c_str(),
|
||||||
nullptr, // No type parameter.
|
nullptr, // No type parameter.
|
||||||
PrintToString(*param_it).c_str(), test_info->code_location,
|
PrintToString(param).c_str(), test_info->code_location,
|
||||||
GetTestSuiteTypeId(),
|
GetTestSuiteTypeId(),
|
||||||
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
|
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
|
||||||
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
|
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
|
||||||
test_info->test_meta_factory->CreateTestFactory(*param_it));
|
test_info->test_meta_factory->CreateTestFactory(param));
|
||||||
} // for param_it
|
++i;
|
||||||
} // for gen_it
|
} // for param
|
||||||
} // for test_it
|
} // for instantiation
|
||||||
|
} // for test_info
|
||||||
|
|
||||||
if (!generated_instantiations) {
|
if (!generated_instantiations) {
|
||||||
// There are no generaotrs, or they all generate nothing ...
|
// There are no generaotrs, or they all generate nothing ...
|
||||||
@ -621,15 +621,13 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
// LocalTestInfo structure keeps information about a single test registered
|
// LocalTestInfo structure keeps information about a single test registered
|
||||||
// with TEST_P macro.
|
// with TEST_P macro.
|
||||||
struct TestInfo {
|
struct TestInfo {
|
||||||
TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
|
TestInfo(const char* a_test_base_name,
|
||||||
TestMetaFactoryBase<ParamType>* a_test_meta_factory,
|
TestMetaFactoryBase<ParamType>* a_test_meta_factory,
|
||||||
CodeLocation a_code_location)
|
CodeLocation a_code_location)
|
||||||
: test_suite_base_name(a_test_suite_base_name),
|
: test_base_name(a_test_base_name),
|
||||||
test_base_name(a_test_base_name),
|
|
||||||
test_meta_factory(a_test_meta_factory),
|
test_meta_factory(a_test_meta_factory),
|
||||||
code_location(a_code_location) {}
|
code_location(std::move(a_code_location)) {}
|
||||||
|
|
||||||
const std::string test_suite_base_name;
|
|
||||||
const std::string test_base_name;
|
const std::string test_base_name;
|
||||||
const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
|
const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
|
||||||
const CodeLocation code_location;
|
const CodeLocation code_location;
|
||||||
@ -639,11 +637,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
|
|||||||
// <Instantiation name, Sequence generator creation function,
|
// <Instantiation name, Sequence generator creation function,
|
||||||
// Name generator function, Source file, Source line>
|
// Name generator function, Source file, Source line>
|
||||||
struct InstantiationInfo {
|
struct InstantiationInfo {
|
||||||
InstantiationInfo(const std::string& name_in,
|
InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in,
|
||||||
GeneratorCreationFunc* generator_in,
|
|
||||||
ParamNameGeneratorFunc* name_func_in, const char* file_in,
|
ParamNameGeneratorFunc* name_func_in, const char* file_in,
|
||||||
int line_in)
|
int line_in)
|
||||||
: name(name_in),
|
: name(std::move(name_in)),
|
||||||
generator(generator_in),
|
generator(generator_in),
|
||||||
name_func(name_func_in),
|
name_func(name_func_in),
|
||||||
file(file_in),
|
file(file_in),
|
||||||
@ -704,29 +701,32 @@ class ParameterizedTestSuiteRegistry {
|
|||||||
// tests and instantiations of a particular test suite.
|
// tests and instantiations of a particular test suite.
|
||||||
template <class TestSuite>
|
template <class TestSuite>
|
||||||
ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
|
ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
|
||||||
const char* test_suite_name, CodeLocation code_location) {
|
std::string test_suite_name, CodeLocation code_location) {
|
||||||
ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
|
ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
|
||||||
for (auto& test_suite_info : test_suite_infos_) {
|
|
||||||
if (test_suite_info->GetTestSuiteName() == test_suite_name) {
|
auto item_it = suite_name_to_info_index_.find(test_suite_name);
|
||||||
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
if (item_it != suite_name_to_info_index_.end()) {
|
||||||
// Complain about incorrect usage of Google Test facilities
|
auto* test_suite_info = test_suite_infos_[item_it->second];
|
||||||
// and terminate the program since we cannot guaranty correct
|
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
|
||||||
// test suite setup and tear-down in this case.
|
// Complain about incorrect usage of Google Test facilities
|
||||||
ReportInvalidTestSuiteType(test_suite_name, code_location);
|
// and terminate the program since we cannot guaranty correct
|
||||||
posix::Abort();
|
// test suite setup and tear-down in this case.
|
||||||
} else {
|
ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location);
|
||||||
// At this point we are sure that the object we found is of the same
|
posix::Abort();
|
||||||
// type we are looking for, so we downcast it to that type
|
} else {
|
||||||
// without further checks.
|
// At this point we are sure that the object we found is of the same
|
||||||
typed_test_info = CheckedDowncastToActualType<
|
// type we are looking for, so we downcast it to that type
|
||||||
ParameterizedTestSuiteInfo<TestSuite>>(test_suite_info);
|
// without further checks.
|
||||||
}
|
typed_test_info =
|
||||||
break;
|
CheckedDowncastToActualType<ParameterizedTestSuiteInfo<TestSuite>>(
|
||||||
|
test_suite_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typed_test_info == nullptr) {
|
if (typed_test_info == nullptr) {
|
||||||
typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
|
typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
|
||||||
test_suite_name, code_location);
|
test_suite_name, std::move(code_location));
|
||||||
|
suite_name_to_info_index_.emplace(std::move(test_suite_name),
|
||||||
|
test_suite_infos_.size());
|
||||||
test_suite_infos_.push_back(typed_test_info);
|
test_suite_infos_.push_back(typed_test_info);
|
||||||
}
|
}
|
||||||
return typed_test_info;
|
return typed_test_info;
|
||||||
@ -740,8 +740,9 @@ class ParameterizedTestSuiteRegistry {
|
|||||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
template <class TestCase>
|
template <class TestCase>
|
||||||
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
|
||||||
const char* test_case_name, CodeLocation code_location) {
|
std::string test_case_name, CodeLocation code_location) {
|
||||||
return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
|
return GetTestSuitePatternHolder<TestCase>(std::move(test_case_name),
|
||||||
|
std::move(code_location));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
@ -750,6 +751,7 @@ class ParameterizedTestSuiteRegistry {
|
|||||||
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
|
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
|
||||||
|
|
||||||
TestSuiteInfoContainer test_suite_infos_;
|
TestSuiteInfoContainer test_suite_infos_;
|
||||||
|
::std::unordered_map<std::string, size_t> suite_name_to_info_index_;
|
||||||
|
|
||||||
ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
|
ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
|
||||||
delete;
|
delete;
|
||||||
@ -776,7 +778,7 @@ class TypeParameterizedTestSuiteRegistry {
|
|||||||
private:
|
private:
|
||||||
struct TypeParameterizedTestSuiteInfo {
|
struct TypeParameterizedTestSuiteInfo {
|
||||||
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
|
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
|
||||||
: code_location(c), instantiated(false) {}
|
: code_location(std::move(c)), instantiated(false) {}
|
||||||
|
|
||||||
CodeLocation code_location;
|
CodeLocation code_location;
|
||||||
bool instantiated;
|
bool instantiated;
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
@ -649,13 +650,15 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
// this is not a typed or a type-parameterized test.
|
// this is not a typed or a type-parameterized test.
|
||||||
// set_up_tc: pointer to the function that sets up the test suite
|
// set_up_tc: pointer to the function that sets up the test suite
|
||||||
// tear_down_tc: pointer to the function that tears down the test suite
|
// tear_down_tc: pointer to the function that tears down the test suite
|
||||||
TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param,
|
TestSuite* GetTestSuite(const std::string& test_suite_name,
|
||||||
|
const char* type_param,
|
||||||
internal::SetUpTestSuiteFunc set_up_tc,
|
internal::SetUpTestSuiteFunc set_up_tc,
|
||||||
internal::TearDownTestSuiteFunc tear_down_tc);
|
internal::TearDownTestSuiteFunc tear_down_tc);
|
||||||
|
|
||||||
// Legacy API is deprecated but still available
|
// Legacy API is deprecated but still available
|
||||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||||
TestCase* GetTestCase(const char* test_case_name, const char* type_param,
|
TestCase* GetTestCase(const std::string& test_case_name,
|
||||||
|
const char* type_param,
|
||||||
internal::SetUpTestSuiteFunc set_up_tc,
|
internal::SetUpTestSuiteFunc set_up_tc,
|
||||||
internal::TearDownTestSuiteFunc tear_down_tc) {
|
internal::TearDownTestSuiteFunc tear_down_tc) {
|
||||||
return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
|
return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
|
||||||
@ -681,13 +684,13 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
// AddTestInfo(), which is called to register a TEST or TEST_F
|
// AddTestInfo(), which is called to register a TEST or TEST_F
|
||||||
// before main() is reached.
|
// before main() is reached.
|
||||||
if (original_working_dir_.IsEmpty()) {
|
if (original_working_dir_.IsEmpty()) {
|
||||||
original_working_dir_.Set(FilePath::GetCurrentDir());
|
original_working_dir_ = FilePath::GetCurrentDir();
|
||||||
GTEST_CHECK_(!original_working_dir_.IsEmpty())
|
GTEST_CHECK_(!original_working_dir_.IsEmpty())
|
||||||
<< "Failed to get the current working directory.";
|
<< "Failed to get the current working directory.";
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_FILE_SYSTEM
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
GetTestSuite(test_info->test_suite_name(), test_info->type_param(),
|
GetTestSuite(test_info->test_suite_name_, test_info->type_param(),
|
||||||
set_up_tc, tear_down_tc)
|
set_up_tc, tear_down_tc)
|
||||||
->AddTestInfo(test_info);
|
->AddTestInfo(test_info);
|
||||||
}
|
}
|
||||||
@ -823,6 +826,12 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
bool catch_exceptions() const { return catch_exceptions_; }
|
bool catch_exceptions() const { return catch_exceptions_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct CompareTestSuitesByPointer {
|
||||||
|
bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {
|
||||||
|
return lhs->name_ < rhs->name_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
friend class ::testing::UnitTest;
|
friend class ::testing::UnitTest;
|
||||||
|
|
||||||
// Used by UnitTest::Run() to capture the state of
|
// Used by UnitTest::Run() to capture the state of
|
||||||
@ -873,6 +882,9 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
// elements in the vector.
|
// elements in the vector.
|
||||||
std::vector<TestSuite*> test_suites_;
|
std::vector<TestSuite*> test_suites_;
|
||||||
|
|
||||||
|
// The set of TestSuites by name.
|
||||||
|
std::unordered_map<std::string, TestSuite*> test_suites_by_name_;
|
||||||
|
|
||||||
// Provides a level of indirection for the test suite list to allow
|
// Provides a level of indirection for the test suite list to allow
|
||||||
// easy shuffling and restoring the test suite order. The i-th
|
// easy shuffling and restoring the test suite order. The i-th
|
||||||
// element of this vector is the index of the i-th test suite in the
|
// element of this vector is the index of the i-th test suite in the
|
||||||
|
@ -578,7 +578,7 @@ void InsertSyntheticTestCase(const std::string& name, CodeLocation location,
|
|||||||
void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
|
void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
|
||||||
CodeLocation code_location) {
|
CodeLocation code_location) {
|
||||||
GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite(
|
GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite(
|
||||||
test_suite_name, code_location);
|
test_suite_name, std::move(code_location));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {
|
void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {
|
||||||
@ -589,7 +589,7 @@ void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {
|
|||||||
void TypeParameterizedTestSuiteRegistry::RegisterTestSuite(
|
void TypeParameterizedTestSuiteRegistry::RegisterTestSuite(
|
||||||
const char* test_suite_name, CodeLocation code_location) {
|
const char* test_suite_name, CodeLocation code_location) {
|
||||||
suites_.emplace(std::string(test_suite_name),
|
suites_.emplace(std::string(test_suite_name),
|
||||||
TypeParameterizedTestSuiteInfo(code_location));
|
TypeParameterizedTestSuiteInfo(std::move(code_location)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeParameterizedTestSuiteRegistry::RegisterInstantiation(
|
void TypeParameterizedTestSuiteRegistry::RegisterInstantiation(
|
||||||
@ -801,7 +801,7 @@ class UnitTestFilter {
|
|||||||
// Returns true if and only if name matches at least one of the patterns in
|
// Returns true if and only if name matches at least one of the patterns in
|
||||||
// the filter.
|
// the filter.
|
||||||
bool MatchesName(const std::string& name) const {
|
bool MatchesName(const std::string& name) const {
|
||||||
return exact_match_patterns_.count(name) > 0 ||
|
return exact_match_patterns_.find(name) != exact_match_patterns_.end() ||
|
||||||
std::any_of(glob_patterns_.begin(), glob_patterns_.end(),
|
std::any_of(glob_patterns_.begin(), glob_patterns_.end(),
|
||||||
[&name](const std::string& pattern) {
|
[&name](const std::string& pattern) {
|
||||||
return PatternMatchesString(
|
return PatternMatchesString(
|
||||||
@ -2740,18 +2740,16 @@ bool Test::IsSkipped() {
|
|||||||
|
|
||||||
// Constructs a TestInfo object. It assumes ownership of the test factory
|
// Constructs a TestInfo object. It assumes ownership of the test factory
|
||||||
// object.
|
// object.
|
||||||
TestInfo::TestInfo(const std::string& a_test_suite_name,
|
TestInfo::TestInfo(std::string a_test_suite_name, std::string a_name,
|
||||||
const std::string& a_name, const char* a_type_param,
|
const char* a_type_param, const char* a_value_param,
|
||||||
const char* a_value_param,
|
|
||||||
internal::CodeLocation a_code_location,
|
internal::CodeLocation a_code_location,
|
||||||
internal::TypeId fixture_class_id,
|
internal::TypeId fixture_class_id,
|
||||||
internal::TestFactoryBase* factory)
|
internal::TestFactoryBase* factory)
|
||||||
: test_suite_name_(a_test_suite_name),
|
: test_suite_name_(std::move(a_test_suite_name)),
|
||||||
// begin()/end() is MSVC 17.3.3 ASAN crash workaround (GitHub issue #3997)
|
name_(std::move(a_name)),
|
||||||
name_(a_name.begin(), a_name.end()),
|
|
||||||
type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
|
type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
|
||||||
value_param_(a_value_param ? new std::string(a_value_param) : nullptr),
|
value_param_(a_value_param ? new std::string(a_value_param) : nullptr),
|
||||||
location_(a_code_location),
|
location_(std::move(a_code_location)),
|
||||||
fixture_class_id_(fixture_class_id),
|
fixture_class_id_(fixture_class_id),
|
||||||
should_run_(false),
|
should_run_(false),
|
||||||
is_disabled_(false),
|
is_disabled_(false),
|
||||||
@ -2784,19 +2782,19 @@ namespace internal {
|
|||||||
// The newly created TestInfo instance will assume
|
// The newly created TestInfo instance will assume
|
||||||
// ownership of the factory object.
|
// ownership of the factory object.
|
||||||
TestInfo* MakeAndRegisterTestInfo(
|
TestInfo* MakeAndRegisterTestInfo(
|
||||||
const char* test_suite_name, const char* name, const char* type_param,
|
std::string test_suite_name, const char* name, const char* type_param,
|
||||||
const char* value_param, CodeLocation code_location,
|
const char* value_param, CodeLocation code_location,
|
||||||
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
|
||||||
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) {
|
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) {
|
||||||
TestInfo* const test_info =
|
TestInfo* const test_info =
|
||||||
new TestInfo(test_suite_name, name, type_param, value_param,
|
new TestInfo(std::move(test_suite_name), name, type_param, value_param,
|
||||||
code_location, fixture_class_id, factory);
|
std::move(code_location), fixture_class_id, factory);
|
||||||
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
|
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
|
||||||
return test_info;
|
return test_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReportInvalidTestSuiteType(const char* test_suite_name,
|
void ReportInvalidTestSuiteType(const char* test_suite_name,
|
||||||
CodeLocation code_location) {
|
const CodeLocation& code_location) {
|
||||||
Message errors;
|
Message errors;
|
||||||
errors
|
errors
|
||||||
<< "Attempted redefinition of test suite " << test_suite_name << ".\n"
|
<< "Attempted redefinition of test suite " << test_suite_name << ".\n"
|
||||||
@ -2948,7 +2946,7 @@ int TestSuite::total_test_count() const {
|
|||||||
// this is not a typed or a type-parameterized test suite.
|
// this is not a typed or a type-parameterized test suite.
|
||||||
// set_up_tc: pointer to the function that sets up the test suite
|
// set_up_tc: pointer to the function that sets up the test suite
|
||||||
// tear_down_tc: pointer to the function that tears down the test suite
|
// tear_down_tc: pointer to the function that tears down the test suite
|
||||||
TestSuite::TestSuite(const char* a_name, const char* a_type_param,
|
TestSuite::TestSuite(const std::string& a_name, const char* a_type_param,
|
||||||
internal::SetUpTestSuiteFunc set_up_tc,
|
internal::SetUpTestSuiteFunc set_up_tc,
|
||||||
internal::TearDownTestSuiteFunc tear_down_tc)
|
internal::TearDownTestSuiteFunc tear_down_tc)
|
||||||
: name_(a_name),
|
: name_(a_name),
|
||||||
@ -5746,29 +5744,6 @@ void UnitTestImpl::PostFlagParsingInit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A predicate that checks the name of a TestSuite against a known
|
|
||||||
// value.
|
|
||||||
//
|
|
||||||
// This is used for implementation of the UnitTest class only. We put
|
|
||||||
// it in the anonymous namespace to prevent polluting the outer
|
|
||||||
// namespace.
|
|
||||||
//
|
|
||||||
// TestSuiteNameIs is copyable.
|
|
||||||
class TestSuiteNameIs {
|
|
||||||
public:
|
|
||||||
// Constructor.
|
|
||||||
explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
|
|
||||||
|
|
||||||
// Returns true if and only if the name of test_suite matches name_.
|
|
||||||
bool operator()(const TestSuite* test_suite) const {
|
|
||||||
return test_suite != nullptr &&
|
|
||||||
strcmp(test_suite->name(), name_.c_str()) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string name_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Finds and returns a TestSuite with the given name. If one doesn't
|
// Finds and returns a TestSuite with the given name. If one doesn't
|
||||||
// exist, creates one and returns it. It's the CALLER'S
|
// exist, creates one and returns it. It's the CALLER'S
|
||||||
// RESPONSIBILITY to ensure that this function is only called WHEN THE
|
// RESPONSIBILITY to ensure that this function is only called WHEN THE
|
||||||
@ -5782,19 +5757,27 @@ class TestSuiteNameIs {
|
|||||||
// set_up_tc: pointer to the function that sets up the test suite
|
// set_up_tc: pointer to the function that sets up the test suite
|
||||||
// tear_down_tc: pointer to the function that tears down the test suite
|
// tear_down_tc: pointer to the function that tears down the test suite
|
||||||
TestSuite* UnitTestImpl::GetTestSuite(
|
TestSuite* UnitTestImpl::GetTestSuite(
|
||||||
const char* test_suite_name, const char* type_param,
|
const std::string& test_suite_name, const char* type_param,
|
||||||
internal::SetUpTestSuiteFunc set_up_tc,
|
internal::SetUpTestSuiteFunc set_up_tc,
|
||||||
internal::TearDownTestSuiteFunc tear_down_tc) {
|
internal::TearDownTestSuiteFunc tear_down_tc) {
|
||||||
// Can we find a TestSuite with the given name?
|
// During initialization, all TestInfos for a given suite are added in
|
||||||
const auto test_suite =
|
// sequence. To optimize this case, see if the most recently added suite is
|
||||||
std::find_if(test_suites_.rbegin(), test_suites_.rend(),
|
// the one being requested now.
|
||||||
TestSuiteNameIs(test_suite_name));
|
if (!test_suites_.empty() &&
|
||||||
|
(*test_suites_.rbegin())->name_ == test_suite_name) {
|
||||||
|
return *test_suites_.rbegin();
|
||||||
|
}
|
||||||
|
|
||||||
if (test_suite != test_suites_.rend()) return *test_suite;
|
// Fall back to searching the collection.
|
||||||
|
auto item_it = test_suites_by_name_.find(test_suite_name);
|
||||||
|
if (item_it != test_suites_by_name_.end()) {
|
||||||
|
return item_it->second;
|
||||||
|
}
|
||||||
|
|
||||||
// No. Let's create one.
|
// Not found. Create a new instance.
|
||||||
auto* const new_test_suite =
|
auto* const new_test_suite =
|
||||||
new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc);
|
new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc);
|
||||||
|
test_suites_by_name_.emplace(test_suite_name, new_test_suite);
|
||||||
|
|
||||||
const UnitTestFilter death_test_suite_filter(kDeathTestSuiteFilter);
|
const UnitTestFilter death_test_suite_filter(kDeathTestSuiteFilter);
|
||||||
// Is this a death test suite?
|
// Is this a death test suite?
|
||||||
@ -6146,12 +6129,11 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
|
|||||||
int num_runnable_tests = 0;
|
int num_runnable_tests = 0;
|
||||||
int num_selected_tests = 0;
|
int num_selected_tests = 0;
|
||||||
for (auto* test_suite : test_suites_) {
|
for (auto* test_suite : test_suites_) {
|
||||||
const std::string& test_suite_name = test_suite->name();
|
const std::string& test_suite_name = test_suite->name_;
|
||||||
test_suite->set_should_run(false);
|
test_suite->set_should_run(false);
|
||||||
|
|
||||||
for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {
|
for (TestInfo* test_info : test_suite->test_info_list()) {
|
||||||
TestInfo* const test_info = test_suite->test_info_list()[j];
|
const std::string& test_name = test_info->name_;
|
||||||
const std::string test_name(test_info->name());
|
|
||||||
// A test is disabled if test suite name or test name matches
|
// A test is disabled if test suite name or test name matches
|
||||||
// kDisableTestFilter.
|
// kDisableTestFilter.
|
||||||
const bool is_disabled =
|
const bool is_disabled =
|
||||||
|
Loading…
Reference in New Issue
Block a user