Commit 600105ee by zhanyong.wan

Makes List a random-access data structure. This simplifies the implementation…

Makes List a random-access data structure. This simplifies the implementation and makes it easier to implement test shuffling.
parent b2db677c
...@@ -434,13 +434,14 @@ class TestResult { ...@@ -434,13 +434,14 @@ class TestResult {
TimeInMillis elapsed_time() const { return elapsed_time_; } TimeInMillis elapsed_time() const { return elapsed_time_; }
// Returns the i-th test part result among all the results. i can range // Returns the i-th test part result among all the results. i can range
// from 0 to test_property_count() - 1. If i is not in that range, returns // from 0 to test_property_count() - 1. If i is not in that range, aborts
// NULL. // the program.
const TestPartResult* GetTestPartResult(int i) const; const TestPartResult& GetTestPartResult(int i) const;
// Returns the i-th test property. i can range from 0 to // Returns the i-th test property. i can range from 0 to
// test_property_count() - 1. If i is not in that range, returns NULL. // test_property_count() - 1. If i is not in that range, aborts the
const TestProperty* GetTestProperty(int i) const; // program.
const TestProperty& GetTestProperty(int i) const;
private: private:
friend class DefaultGlobalTestPartResultReporter; friend class DefaultGlobalTestPartResultReporter;
......
...@@ -116,9 +116,7 @@ class ScopedTrace; // Implements scoped trace. ...@@ -116,9 +116,7 @@ class ScopedTrace; // Implements scoped trace.
class TestInfoImpl; // Opaque implementation of TestInfo class TestInfoImpl; // Opaque implementation of TestInfo
class TestResult; // Result of a single Test. class TestResult; // Result of a single Test.
class UnitTestImpl; // Opaque implementation of UnitTest class UnitTestImpl; // Opaque implementation of UnitTest
template <typename E> class List; // A generic list. template <typename E> class List; // A generic list.
template <typename E> class ListNode; // A node in a generic list.
// How many times InitGoogleTest() has been called. // How many times InitGoogleTest() has been called.
extern int g_init_gtest_count; extern int g_init_gtest_count;
......
...@@ -86,12 +86,7 @@ const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { ...@@ -86,12 +86,7 @@ const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
internal::posix::Abort(); internal::posix::Abort();
} }
const internal::ListNode<TestPartResult>* p = list_->Head(); return list_->GetElement(index);
for (int i = 0; i < index; i++) {
p = p->next();
}
return p->element();
} }
// Returns the number of TestPartResult objects in the array. // Returns the number of TestPartResult objects in the array.
......
...@@ -264,10 +264,8 @@ static bool GTestIsInitialized() { return g_init_gtest_count != 0; } ...@@ -264,10 +264,8 @@ static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
static int SumOverTestCaseList(const internal::List<TestCase*>& case_list, static int SumOverTestCaseList(const internal::List<TestCase*>& case_list,
int (TestCase::*method)() const) { int (TestCase::*method)() const) {
int sum = 0; int sum = 0;
for (const internal::ListNode<TestCase*>* node = case_list.Head(); for (int i = 0; i < case_list.size(); i++) {
node != NULL; sum += (case_list.GetElement(i)->*method)();
node = node->next()) {
sum += (node->element()->*method)();
} }
return sum; return sum;
} }
...@@ -1830,16 +1828,17 @@ TestResult::TestResult() ...@@ -1830,16 +1828,17 @@ TestResult::TestResult()
TestResult::~TestResult() { TestResult::~TestResult() {
} }
// Returns the i-th test part result among all the results. i can range // Returns the i-th test part result among all the results. i can
// from 0 to total_part_count() - 1. If i is not in that range, returns // range from 0 to total_part_count() - 1. If i is not in that range,
// NULL. // aborts the program.
const TestPartResult* TestResult::GetTestPartResult(int i) const { const TestPartResult& TestResult::GetTestPartResult(int i) const {
return test_part_results_->GetElement(i); return test_part_results_->GetElement(i);
} }
// Returns the i-th test property. i can range from 0 to // Returns the i-th test property. i can range from 0 to
// test_property_count() - 1. If i is not in that range, returns NULL. // test_property_count() - 1. If i is not in that range, aborts the
const TestProperty* TestResult::GetTestProperty(int i) const { // program.
const TestProperty& TestResult::GetTestProperty(int i) const {
return test_properties_->GetElement(i); return test_properties_->GetElement(i);
} }
...@@ -1861,14 +1860,13 @@ void TestResult::RecordProperty(const TestProperty& test_property) { ...@@ -1861,14 +1860,13 @@ void TestResult::RecordProperty(const TestProperty& test_property) {
return; return;
} }
MutexLock lock(&test_properites_mutex_); MutexLock lock(&test_properites_mutex_);
ListNode<TestProperty>* const node_with_matching_key = TestProperty* const property_with_matching_key =
test_properties_->FindIf(TestPropertyKeyIs(test_property.key())); test_properties_->FindIf(TestPropertyKeyIs(test_property.key()));
if (node_with_matching_key == NULL) { if (property_with_matching_key == NULL) {
test_properties_->PushBack(test_property); test_properties_->PushBack(test_property);
return; return;
} }
TestProperty& property_with_matching_key = node_with_matching_key->element(); property_with_matching_key->SetValue(test_property.value());
property_with_matching_key.SetValue(test_property.value());
} }
// Adds a failure if the key is a reserved attribute of Google Test // Adds a failure if the key is a reserved attribute of Google Test
...@@ -2028,7 +2026,7 @@ bool Test::HasSameFixtureClass() { ...@@ -2028,7 +2026,7 @@ bool Test::HasSameFixtureClass() {
// Info about the first test in the current test case. // Info about the first test in the current test case.
const internal::TestInfoImpl* const first_test_info = const internal::TestInfoImpl* const first_test_info =
test_case->test_info_list().Head()->element()->impl(); test_case->test_info_list().GetElement(0)->impl();
const internal::TypeId first_fixture_id = first_test_info->fixture_class_id(); const internal::TypeId first_fixture_id = first_test_info->fixture_class_id();
const char* const first_test_name = first_test_info->name(); const char* const first_test_name = first_test_info->name();
...@@ -2884,7 +2882,6 @@ void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) { ...@@ -2884,7 +2882,6 @@ void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
class UnitTestEventsRepeater : public UnitTestEventListenerInterface { class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
public: public:
typedef internal::List<UnitTestEventListenerInterface *> Listeners; typedef internal::List<UnitTestEventListenerInterface *> Listeners;
typedef internal::ListNode<UnitTestEventListenerInterface *> ListenersNode;
UnitTestEventsRepeater() {} UnitTestEventsRepeater() {}
virtual ~UnitTestEventsRepeater(); virtual ~UnitTestEventsRepeater();
void AddListener(UnitTestEventListenerInterface *listener); void AddListener(UnitTestEventListenerInterface *listener);
...@@ -2908,10 +2905,8 @@ class UnitTestEventsRepeater : public UnitTestEventListenerInterface { ...@@ -2908,10 +2905,8 @@ class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
}; };
UnitTestEventsRepeater::~UnitTestEventsRepeater() { UnitTestEventsRepeater::~UnitTestEventsRepeater() {
for (ListenersNode* listener = listeners_.Head(); for (int i = 0; i < listeners_.size(); i++) {
listener != NULL; delete listeners_.GetElement(i);
listener = listener->next()) {
delete listener->element();
} }
} }
...@@ -2924,10 +2919,8 @@ void UnitTestEventsRepeater::AddListener( ...@@ -2924,10 +2919,8 @@ void UnitTestEventsRepeater::AddListener(
// This defines a member that repeats the call to all listeners. // This defines a member that repeats the call to all listeners.
#define GTEST_REPEATER_METHOD_(Name, Type) \ #define GTEST_REPEATER_METHOD_(Name, Type) \
void UnitTestEventsRepeater::Name(const Type& parameter) { \ void UnitTestEventsRepeater::Name(const Type& parameter) { \
for (ListenersNode* listener = listeners_.Head(); \ for (int i = 0; i < listeners_.size(); i++) { \
listener != NULL; \ listeners_.GetElement(i)->Name(parameter); \
listener = listener->next()) { \
listener->element()->Name(parameter); \
} \ } \
} }
...@@ -3150,7 +3143,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out, ...@@ -3150,7 +3143,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out,
int failures = 0; int failures = 0;
for (int i = 0; i < result.total_part_count(); ++i) { for (int i = 0; i < result.total_part_count(); ++i) {
const TestPartResult& part = *result.GetTestPartResult(i); const TestPartResult& part = result.GetTestPartResult(i);
if (part.failed()) { if (part.failed()) {
const internal::String message = const internal::String message =
internal::String::Format("%s:%d\n%s", part.file_name(), internal::String::Format("%s:%d\n%s", part.file_name(),
...@@ -3212,7 +3205,7 @@ internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( ...@@ -3212,7 +3205,7 @@ internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
using internal::TestProperty; using internal::TestProperty;
Message attributes; Message attributes;
for (int i = 0; i < result.test_property_count(); ++i) { for (int i = 0; i < result.test_property_count(); ++i) {
const TestProperty& property = *result.GetTestProperty(i); const TestProperty& property = result.GetTestProperty(i);
attributes << " " << property.key() << "=" attributes << " " << property.key() << "="
<< "\"" << EscapeXmlAttribute(property.value()) << "\""; << "\"" << EscapeXmlAttribute(property.value()) << "\"";
} }
...@@ -3407,11 +3400,9 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type, ...@@ -3407,11 +3400,9 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type,
if (impl_->gtest_trace_stack()->size() > 0) { if (impl_->gtest_trace_stack()->size() > 0) {
msg << "\n" << GTEST_NAME_ << " trace:"; msg << "\n" << GTEST_NAME_ << " trace:";
for (internal::ListNode<internal::TraceInfo>* node = for (int i = 0; i < impl_->gtest_trace_stack()->size(); i++) {
impl_->gtest_trace_stack()->Head(); const internal::TraceInfo& trace =
node != NULL; impl_->gtest_trace_stack()->GetElement(i);
node = node->next()) {
const internal::TraceInfo& trace = node->element();
msg << "\n" << trace.file << ":" << trace.line << ": " << trace.message; msg << "\n" << trace.file << ":" << trace.line << ": " << trace.message;
} }
} }
...@@ -3606,7 +3597,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) ...@@ -3606,7 +3597,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
parameterized_test_registry_(), parameterized_test_registry_(),
parameterized_tests_registered_(false), parameterized_tests_registered_(false),
#endif // GTEST_HAS_PARAM_TEST #endif // GTEST_HAS_PARAM_TEST
last_death_test_case_(NULL), last_death_test_case_(-1),
current_test_case_(NULL), current_test_case_(NULL),
current_test_info_(NULL), current_test_info_(NULL),
ad_hoc_test_result_(), ad_hoc_test_result_(),
...@@ -3670,12 +3661,13 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, ...@@ -3670,12 +3661,13 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
Test::SetUpTestCaseFunc set_up_tc, Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc) { Test::TearDownTestCaseFunc tear_down_tc) {
// Can we find a TestCase with the given name? // Can we find a TestCase with the given name?
internal::ListNode<TestCase*>* node = test_cases_.FindIf( TestCase** test_case = test_cases_.FindIf(TestCaseNameIs(test_case_name));
TestCaseNameIs(test_case_name));
if (test_case != NULL)
return *test_case;
if (node == NULL) {
// No. Let's create one. // No. Let's create one.
TestCase* const test_case = TestCase* const new_test_case =
new TestCase(test_case_name, comment, set_up_tc, tear_down_tc); new TestCase(test_case_name, comment, set_up_tc, tear_down_tc);
// Is this a death test case? // Is this a death test case?
...@@ -3683,17 +3675,13 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, ...@@ -3683,17 +3675,13 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
kDeathTestCaseFilter)) { kDeathTestCaseFilter)) {
// Yes. Inserts the test case after the last death test case // Yes. Inserts the test case after the last death test case
// defined so far. // defined so far.
node = test_cases_.InsertAfter(last_death_test_case_, test_case); test_cases_.Insert(new_test_case, ++last_death_test_case_);
last_death_test_case_ = node;
} else { } else {
// No. Appends to the end of the list. // No. Appends to the end of the list.
test_cases_.PushBack(test_case); test_cases_.PushBack(new_test_case);
node = test_cases_.Last();
}
} }
// Returns the TestCase found. return new_test_case;
return node->element();
} }
// Helpers for setting up / tearing down the given environment. They // Helpers for setting up / tearing down the given environment. They
...@@ -3925,19 +3913,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { ...@@ -3925,19 +3913,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
// this shard. // this shard.
int num_runnable_tests = 0; int num_runnable_tests = 0;
int num_selected_tests = 0; int num_selected_tests = 0;
for (const internal::ListNode<TestCase *> *test_case_node = for (int i = 0; i < test_cases_.size(); i++) {
test_cases_.Head(); TestCase* const test_case = test_cases_.GetElement(i);
test_case_node != NULL;
test_case_node = test_case_node->next()) {
TestCase * const test_case = test_case_node->element();
const String &test_case_name = test_case->name(); const String &test_case_name = test_case->name();
test_case->set_should_run(false); test_case->set_should_run(false);
for (const internal::ListNode<TestInfo *> *test_info_node = for (int j = 0; j < test_case->test_info_list().size(); j++) {
test_case->test_info_list().Head(); TestInfo* const test_info = test_case->test_info_list().GetElement(j);
test_info_node != NULL;
test_info_node = test_info_node->next()) {
TestInfo * const test_info = test_info_node->element();
const String test_name(test_info->name()); const String test_name(test_info->name());
// A test is disabled if test case name or test name matches // A test is disabled if test case name or test name matches
// kDisableTestFilter. // kDisableTestFilter.
...@@ -3974,17 +3956,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { ...@@ -3974,17 +3956,13 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
// Prints the names of the tests matching the user-specified filter flag. // Prints the names of the tests matching the user-specified filter flag.
void UnitTestImpl::ListTestsMatchingFilter() { void UnitTestImpl::ListTestsMatchingFilter() {
for (const internal::ListNode<TestCase*>* test_case_node = test_cases_.Head(); for (int i = 0; i < test_cases_.size(); i++) {
test_case_node != NULL; const TestCase* const test_case = test_cases_.GetElement(i);
test_case_node = test_case_node->next()) {
const TestCase* const test_case = test_case_node->element();
bool printed_test_case_name = false; bool printed_test_case_name = false;
for (const internal::ListNode<TestInfo*>* test_info_node = for (int j = 0; j < test_case->test_info_list().size(); j++) {
test_case->test_info_list().Head(); const TestInfo* const test_info =
test_info_node != NULL; test_case->test_info_list().GetElement(j);
test_info_node = test_info_node->next()) {
const TestInfo* const test_info = test_info_node->element();
if (test_info->matches_filter()) { if (test_info->matches_filter()) {
if (!printed_test_case_name) { if (!printed_test_case_name) {
printed_test_case_name = true; printed_test_case_name = true;
......
...@@ -46,7 +46,6 @@ namespace testing { ...@@ -46,7 +46,6 @@ namespace testing {
namespace { namespace {
using internal::List; using internal::List;
using internal::ListNode;
using internal::String; using internal::String;
using internal::TestProperty; using internal::TestProperty;
using internal::TestPropertyKeyIs; using internal::TestPropertyKeyIs;
...@@ -70,9 +69,10 @@ void ExpectKeyAndValueWereRecordedForId(const List<TestProperty>& properties, ...@@ -70,9 +69,10 @@ void ExpectKeyAndValueWereRecordedForId(const List<TestProperty>& properties,
int id, int id,
const char* suffix) { const char* suffix) {
TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str());
const ListNode<TestProperty>* node = properties.FindIf(matches_key); const TestProperty* property = properties.FindIf(matches_key);
EXPECT_TRUE(node != NULL) << "expecting " << suffix << " node for id " << id; ASSERT_TRUE(property != NULL)
EXPECT_STREQ(IdToString(id).c_str(), node->element().value()); << "expecting " << suffix << " value for id " << id;
EXPECT_STREQ(IdToString(id).c_str(), property->value());
} }
// Calls a large number of Google Test assertions, where exactly one of them // Calls a large number of Google Test assertions, where exactly one of them
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment