summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-09-04 18:30:25 +0000
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-09-04 18:30:25 +0000
commitf39160b423e8f90902066cf6774e4180667dcbee (patch)
treef990763455e874fb887364bbd9c712386824d20d /src
parent89be5763249cbab785abfa310fb1cd6b5e9c4adf (diff)
downloadgtest-f39160b423e8f90902066cf6774e4180667dcbee.tar.gz
gtest-f39160b423e8f90902066cf6774e4180667dcbee.tar.bz2
gtest-f39160b423e8f90902066cf6774e4180667dcbee.tar.xz
More implementation of the event listener interface (by Vlad Losev); Reduces the stack space usage of assertions by moving AssertHelper's fields to the heap (by Jorg Brown); Makes String faster, smaller, and simpler (by Zhanyong Wan); Fixes a bug in String::Format() (by Chandler); Adds the /MD version of VC projects to the distribution (by Vlad Losev).
git-svn-id: http://googletest.googlecode.com/svn/trunk@301 861a406c-534a-0410-8894-cb66d6ee9925
Diffstat (limited to 'src')
-rw-r--r--src/gtest-death-test.cc6
-rw-r--r--src/gtest-internal-inl.h43
-rw-r--r--src/gtest.cc451
3 files changed, 270 insertions, 230 deletions
diff --git a/src/gtest-death-test.cc b/src/gtest-death-test.cc
index 02ce48d..d975af7 100644
--- a/src/gtest-death-test.cc
+++ b/src/gtest-death-test.cc
@@ -469,7 +469,8 @@ bool DeathTestImpl::Passed(bool status_ok) {
break;
case DIED:
if (status_ok) {
- if (RE::PartialMatch(error_message.c_str(), *regex())) {
+ const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
+ if (matched) {
success = true;
} else {
buffer << " Result: died but not with expected error.\n"
@@ -767,6 +768,9 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
// concurrent writes to the log files. We capture stderr in the parent
// process and append the child process' output to a log.
LogToStderr();
+ // Event forwarding to the listeners of event listener API mush be shut
+ // down in death test subprocesses.
+ GetUnitTestImpl()->listeners()->SuppressEventForwarding();
return EXECUTE_TEST;
} else {
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h
index 8431971..93217f4 100644
--- a/src/gtest-internal-inl.h
+++ b/src/gtest-internal-inl.h
@@ -741,6 +741,9 @@ class UnitTestImpl {
return test_cases_.GetElementOr(i, NULL);
}
+ // Provides access to the event listener list.
+ EventListeners* listeners() { return &listeners_; }
+
// Returns the TestResult for the test that's currently running, or
// the TestResult for the ad hoc test if no test is running.
TestResult* current_test_result();
@@ -748,18 +751,6 @@ class UnitTestImpl {
// Returns the TestResult for the ad hoc test.
const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
- // Sets the unit test result printer.
- //
- // Does nothing if the input and the current printer object are the
- // same; otherwise, deletes the old printer object and makes the
- // input the current printer.
- void set_result_printer(UnitTestEventListenerInterface* result_printer);
-
- // Returns the current unit test result printer if it is not NULL;
- // otherwise, creates an appropriate result printer, makes it the
- // current printer, and returns it.
- UnitTestEventListenerInterface* result_printer();
-
// Sets the OS stack trace getter.
//
// Does nothing if the input and the current OS stack trace getter
@@ -907,9 +898,13 @@ class UnitTestImpl {
}
#if GTEST_HAS_DEATH_TEST
+ void InitDeathTestSubprocessControlInfo() {
+ internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
+ }
// Returns a pointer to the parsed --gtest_internal_run_death_test
// flag, or NULL if that flag was not specified.
// This information is useful only in a death test child process.
+ // Must not be called before a call to InitGoogleTest.
const InternalRunDeathTestFlag* internal_run_death_test_flag() const {
return internal_run_death_test_flag_.get();
}
@@ -919,9 +914,22 @@ class UnitTestImpl {
return death_test_factory_.get();
}
+ void SuppressTestEventsIfInSubprocess();
+
friend class ReplaceDeathTestFactory;
#endif // GTEST_HAS_DEATH_TEST
+ // Initializes the event listener performing XML output as specified by
+ // UnitTestOptions. Must not be called before InitGoogleTest.
+ void ConfigureXmlOutput();
+
+// Performs initialization dependent upon flag values obtained in
+// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to
+// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest
+// this function is also called from RunAllTests. Since this function can be
+// called more than once, it has to be idempotent.
+ void PostFlagParsingInit();
+
// Gets the random seed used at the start of the current test run.
int random_seed() const { return random_seed_; }
@@ -992,11 +1000,9 @@ class UnitTestImpl {
// test, and records the result in ad_hoc_test_result_.
TestResult ad_hoc_test_result_;
- // The unit test result printer. Will be deleted when the UnitTest
- // object is destructed. By default, a plain text printer is used,
- // but the user can set this field to use a custom printer if that
- // is desired.
- UnitTestEventListenerInterface* result_printer_;
+ // The list of event listeners that can be used to track events inside
+ // Google Test.
+ EventListeners listeners_;
// The OS stack trace getter. Will be deleted when the UnitTest
// object is destructed. By default, an OsStackTraceGetter is used,
@@ -1004,6 +1010,9 @@ class UnitTestImpl {
// desired.
OsStackTraceGetterInterface* os_stack_trace_getter_;
+ // True iff PostFlagParsingInit() has been called.
+ bool post_flag_parse_init_performed_;
+
// The random number seed used at the beginning of the test run.
int random_seed_;
diff --git a/src/gtest.cc b/src/gtest.cc
index 5cfabf8..1b602f5 100644
--- a/src/gtest.cc
+++ b/src/gtest.cc
@@ -129,9 +129,12 @@
namespace testing {
+using internal::EventListeners;
+using internal::EmptyTestEventListener;
using internal::TestCase;
using internal::TestProperty;
using internal::TestResult;
+using internal::UnitTestEventListenerInterface;
// Constants.
@@ -303,14 +306,18 @@ static bool ShouldRunTestCase(const TestCase* test_case) {
// AssertHelper constructor.
AssertHelper::AssertHelper(TestPartResultType type, const char* file,
int line, const char* message)
- : type_(type), file_(file), line_(line), message_(message) {
+ : data_(new AssertHelperData(type, file, line, message)) {
+}
+
+AssertHelper::~AssertHelper() {
+ delete data_;
}
// Message assignment, for assertion streaming support.
void AssertHelper::operator=(const Message& message) const {
UnitTest::GetInstance()->
- AddTestPartResult(type_, file_, line_,
- AppendUserMessage(message_, message),
+ AddTestPartResult(data_->type, data_->file, data_->line,
+ AppendUserMessage(data_->message, message),
UnitTest::GetInstance()->impl()
->CurrentOsStackTraceExceptTop(1)
// Skips the stack frame for this function itself.
@@ -476,86 +483,6 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
} // namespace internal
-// The interface for printing the result of a UnitTest
-class UnitTestEventListenerInterface {
- public:
- // The d'tor is pure virtual as this is an abstract class.
- virtual ~UnitTestEventListenerInterface() {}
-
- // Called before the unit test starts.
- virtual void OnUnitTestStart(const UnitTest& unit_test) = 0;
-
- // Called after the unit test ends.
- virtual void OnUnitTestEnd(const UnitTest& unit_test) = 0;
-
- // Called before the test case starts.
- virtual void OnTestCaseStart(const TestCase& test_case) = 0;
-
- // Called after the test case ends.
- virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
-
- // Called before the global set-up starts.
- virtual void OnGlobalSetUpStart(const UnitTest& unit_test) = 0;
-
- // Called after the global set-up ends.
- virtual void OnGlobalSetUpEnd(const UnitTest& unit_test) = 0;
-
- // Called before the global tear-down starts.
- virtual void OnGlobalTearDownStart(const UnitTest& unit_test) = 0;
-
- // Called after the global tear-down ends.
- virtual void OnGlobalTearDownEnd(const UnitTest& unit_test) = 0;
-
- // Called before the test starts.
- virtual void OnTestStart(const TestInfo& test_info) = 0;
-
- // Called after the test ends.
- virtual void OnTestEnd(const TestInfo& test_info) = 0;
-
- // Called after an assertion.
- virtual void OnNewTestPartResult(const TestPartResult& test_part_result) = 0;
-};
-
-// The convenience class for users who need to override just one or two
-// methods and are not concerned that a possible change to a signature of
-// the methods they override will not be caught during the build.
-class EmptyTestEventListener : public UnitTestEventListenerInterface {
- public:
- // Called before the unit test starts.
- virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) {}
-
- // Called after the unit test ends.
- virtual void OnUnitTestEnd(const UnitTest& /*unit_test*/) {}
-
- // Called before the test case starts.
- virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
-
- // Called after the test case ends.
- virtual void OnTestCaseEnd(const TestCase& /*test_case&*/) {}
-
- // Called before the global set-up starts.
- virtual void OnGlobalSetUpStart(const UnitTest& /*unit_test*/) {}
-
- // Called after the global set-up ends.
- virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) {}
-
- // Called before the global tear-down starts.
- virtual void OnGlobalTearDownStart(const UnitTest& /*unit_test*/) {}
-
- // Called after the global tear-down ends.
- virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {}
-
- // Called before the test starts.
- virtual void OnTestStart(const TestInfo& /*test_info*/) {}
-
- // Called after the test ends.
- virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
-
- // Called after an assertion.
- virtual void OnNewTestPartResult(const TestPartResult& /*test_part_result*/) {
- }
-};
-
// The c'tor sets this object as the test part result reporter used by
// Google Test. The 'result' parameter specifies where to report the
// results. Intercepts only failures from the current thread.
@@ -690,7 +617,7 @@ DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
const TestPartResult& result) {
unit_test_->current_test_result()->AddTestPartResult(result);
- unit_test_->result_printer()->OnNewTestPartResult(result);
+ unit_test_->listeners()->repeater()->OnNewTestPartResult(result);
}
DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
@@ -1738,28 +1665,38 @@ bool String::EndsWithCaseInsensitive(const char* suffix) const {
// available.
//
// The result is limited to 4096 characters (including the tailing 0).
-// If 4096 characters are not enough to format the input,
-// "<buffer exceeded>" is returned.
+// If 4096 characters are not enough to format the input, or if
+// there's an error, "<formatting error or buffer exceeded>" is
+// returned.
String String::Format(const char * format, ...) {
va_list args;
va_start(args, format);
char buffer[4096];
+ const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]);
+
// MSVC 8 deprecates vsnprintf(), so we want to suppress warning
// 4996 (deprecated function) there.
#ifdef _MSC_VER // We are using MSVC.
#pragma warning(push) // Saves the current warning state.
#pragma warning(disable:4996) // Temporarily disables warning 4996.
- const int size =
- vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args);
+ const int size = vsnprintf(buffer, kBufferSize, format, args);
#pragma warning(pop) // Restores the warning state.
#else // We are not using MSVC.
- const int size =
- vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args);
+ const int size = vsnprintf(buffer, kBufferSize, format, args);
#endif // _MSC_VER
va_end(args);
- return (size >= 0) ? String(buffer, size) : String("<buffer exceeded>");
+ // vsnprintf()'s behavior is not portable. When the buffer is not
+ // big enough, it returns a negative value in MSVC, and returns the
+ // needed buffer size on Linux. When there is an output error, it
+ // always returns a negative value. For simplicity, we lump the two
+ // error cases together.
+ if (size < 0 || size >= kBufferSize) {
+ return String("<formatting error or buffer exceeded>");
+ } else {
+ return String(buffer, size);
+ }
}
// Converts the buffer in a StrStream to a String, converting NUL
@@ -2297,11 +2234,11 @@ void TestInfoImpl::Run() {
UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_info(parent_);
- // Notifies the unit test event listener that a test is about to
- // start.
- UnitTestEventListenerInterface* const result_printer =
- impl->result_printer();
- result_printer->OnTestStart(*parent_);
+ UnitTestEventListenerInterface* repeater =
+ UnitTest::GetInstance()->listeners().repeater();
+
+ // Notifies the unit test event listeners that a test is about to start.
+ repeater->OnTestStart(*parent_);
const TimeInMillis start = GetTimeInMillis();
@@ -2344,7 +2281,7 @@ void TestInfoImpl::Run() {
result_.set_elapsed_time(GetTimeInMillis() - start);
// Notifies the unit test event listener that a test has just finished.
- result_printer->OnTestEnd(*parent_);
+ repeater->OnTestEnd(*parent_);
// Tells UnitTest to stop associating assertion results to this
// test.
@@ -2425,10 +2362,10 @@ void TestCase::Run() {
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_case(this);
- UnitTestEventListenerInterface * const result_printer =
- impl->result_printer();
+ UnitTestEventListenerInterface* repeater =
+ UnitTest::GetInstance()->listeners().repeater();
- result_printer->OnTestCaseStart(*this);
+ repeater->OnTestCaseStart(*this);
impl->os_stack_trace_getter()->UponLeavingGTest();
set_up_tc_();
@@ -2438,7 +2375,7 @@ void TestCase::Run() {
impl->os_stack_trace_getter()->UponLeavingGTest();
tear_down_tc_();
- result_printer->OnTestCaseEnd(*this);
+ repeater->OnTestCaseEnd(*this);
impl->set_current_test_case(NULL);
}
@@ -2471,10 +2408,6 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) {
} // namespace internal
-// A result printer that never prints anything. Used in the child process
-// of an exec-style death test to avoid needless output clutter.
-class NullUnitTestResultPrinter : public EmptyTestEventListener {};
-
// Formats a countable noun. Depending on its quantity, either the
// singular form or the plural form is used. e.g.
//
@@ -2663,14 +2596,6 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_end(args);
}
-} // namespace internal
-
-using internal::ColoredPrintf;
-using internal::COLOR_DEFAULT;
-using internal::COLOR_RED;
-using internal::COLOR_GREEN;
-using internal::COLOR_YELLOW;
-
// This class implements the UnitTestEventListenerInterface interface.
//
// Class PrettyUnitTestResultPrinter is copyable.
@@ -2888,10 +2813,16 @@ void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
// This class forwards events to other event listeners.
class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
public:
- typedef internal::Vector<UnitTestEventListenerInterface *> Listeners;
- UnitTestEventsRepeater() {}
+ UnitTestEventsRepeater() : forwarding_enabled_(true) {}
virtual ~UnitTestEventsRepeater();
- void AddListener(UnitTestEventListenerInterface *listener);
+ void Append(UnitTestEventListenerInterface *listener);
+ UnitTestEventListenerInterface* Release(
+ UnitTestEventListenerInterface* listener);
+
+ // Controls whether events will be forwarded to listeners_. Set to false
+ // in death test child processes.
+ bool forwarding_enabled() const { return forwarding_enabled_; }
+ void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
virtual void OnUnitTestStart(const UnitTest& unit_test);
virtual void OnUnitTestEnd(const UnitTest& unit_test);
@@ -2906,7 +2837,11 @@ class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
virtual void OnNewTestPartResult(const TestPartResult& result);
private:
- Listeners listeners_;
+ // Controls whether events will be forwarded to listeners_. Set to false
+ // in death test child processes.
+ bool forwarding_enabled_;
+ // The list of listeners that receive events.
+ Vector<UnitTestEventListenerInterface*> listeners_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestEventsRepeater);
};
@@ -2917,17 +2852,31 @@ UnitTestEventsRepeater::~UnitTestEventsRepeater() {
}
}
-void UnitTestEventsRepeater::AddListener(
- UnitTestEventListenerInterface *listener) {
+void UnitTestEventsRepeater::Append(UnitTestEventListenerInterface *listener) {
listeners_.PushBack(listener);
}
+// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
+UnitTestEventListenerInterface* UnitTestEventsRepeater::Release(
+ UnitTestEventListenerInterface *listener) {
+ for (int i = 0; i < listeners_.size(); ++i) {
+ if (listeners_.GetElement(i) == listener) {
+ listeners_.Erase(i);
+ return listener;
+ }
+ }
+
+ return NULL;
+}
+
// Since the methods are identical, use a macro to reduce boilerplate.
// This defines a member that repeats the call to all listeners.
#define GTEST_REPEATER_METHOD_(Name, Type) \
void UnitTestEventsRepeater::Name(const Type& parameter) { \
- for (int i = 0; i < listeners_.size(); i++) { \
- listeners_.GetElement(i)->Name(parameter); \
+ if (forwarding_enabled_) { \
+ for (int i = 0; i < listeners_.size(); i++) { \
+ listeners_.GetElement(i)->Name(parameter); \
+ } \
} \
}
@@ -2945,7 +2894,7 @@ GTEST_REPEATER_METHOD_(OnNewTestPartResult, TestPartResult)
#undef GTEST_REPEATER_METHOD_
-// End PrettyUnitTestResultPrinter
+// End UnitTestEventsRepeater
// This class generates an XML output file.
class XmlUnitTestResultPrinter : public EmptyTestEventListener {
@@ -2970,18 +2919,15 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
// is_attribute is true, the text is meant to appear as an attribute
// value, and normalizable whitespace is preserved by replacing it
// with character references.
- static internal::String EscapeXml(const char* str,
- bool is_attribute);
+ static String EscapeXml(const char* str, bool is_attribute);
// Convenience wrapper around EscapeXml when str is an attribute value.
- static internal::String EscapeXmlAttribute(const char* str) {
+ static String EscapeXmlAttribute(const char* str) {
return EscapeXml(str, true);
}
// Convenience wrapper around EscapeXml when str is not an attribute value.
- static internal::String EscapeXmlText(const char* str) {
- return EscapeXml(str, false);
- }
+ static String EscapeXmlText(const char* str) { return EscapeXml(str, false); }
// Prints an XML representation of a TestInfo object.
static void PrintXmlTestInfo(FILE* out,
@@ -2998,11 +2944,10 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
// delimited XML attributes based on the property key="value" pairs.
// When the String is not empty, it includes a space at the beginning,
// to delimit this attribute from prior attributes.
- static internal::String TestPropertiesAsXmlAttributes(
- const TestResult& result);
+ static String TestPropertiesAsXmlAttributes(const TestResult& result);
// The output file.
- const internal::String output_file_;
+ const String output_file_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter);
};
@@ -3020,11 +2965,11 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
// Called after the unit test ends.
void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
FILE* xmlout = NULL;
- internal::FilePath output_file(output_file_);
- internal::FilePath output_dir(output_file.RemoveFileName());
+ FilePath output_file(output_file_);
+ FilePath output_dir(output_file.RemoveFileName());
if (output_dir.CreateDirectoriesRecursively()) {
- xmlout = internal::posix::FOpen(output_file_.c_str(), "w");
+ xmlout = posix::FOpen(output_file_.c_str(), "w");
}
if (xmlout == NULL) {
// TODO(wan): report the reason of the failure.
@@ -3059,8 +3004,7 @@ void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
// most invalid characters can be retained using character references.
// TODO(wan): It might be nice to have a minimally invasive, human-readable
// escaping scheme for invalid characters, rather than dropping them.
-internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
- bool is_attribute) {
+String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) {
Message m;
if (str != NULL) {
@@ -3090,7 +3034,7 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
default:
if (IsValidXmlCharacter(*src)) {
if (is_attribute && IsNormalizableWhitespace(*src))
- m << internal::String::Format("&#x%02X;", unsigned(*src));
+ m << String::Format("&#x%02X;", unsigned(*src));
else
m << *src;
}
@@ -3102,7 +3046,6 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
return m.GetString();
}
-
// The following routines generate an XML representation of a UnitTest
// object.
//
@@ -3119,8 +3062,6 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
// </testsuite>
// </testsuites>
-namespace internal {
-
// Formats the given time in milliseconds as seconds. The returned
// C-string is owned by this function and cannot be released by the
// caller. Calling the function again invalidates the previous
@@ -3131,8 +3072,6 @@ const char* FormatTimeInMillisAsSeconds(TimeInMillis ms) {
return str.c_str();
}
-} // namespace internal
-
// Prints an XML representation of a TestInfo object.
// TODO(wan): There is also value in printing properties with the plain printer.
void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out,
@@ -3144,7 +3083,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out,
"classname=\"%s\"%s",
EscapeXmlAttribute(test_info.name()).c_str(),
test_info.should_run() ? "run" : "notrun",
- internal::FormatTimeInMillisAsSeconds(result.elapsed_time()),
+ FormatTimeInMillisAsSeconds(result.elapsed_time()),
EscapeXmlAttribute(test_case_name).c_str(),
TestPropertiesAsXmlAttributes(result).c_str());
@@ -3152,9 +3091,8 @@ void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out,
for (int i = 0; i < result.total_part_count(); ++i) {
const TestPartResult& part = result.GetTestPartResult(i);
if (part.failed()) {
- const internal::String message =
- internal::String::Format("%s:%d\n%s", part.file_name(),
- part.line_number(), part.message());
+ const String message = String::Format("%s:%d\n%s", part.file_name(),
+ part.line_number(), part.message());
if (++failures == 1)
fprintf(out, ">\n");
fprintf(out,
@@ -3182,7 +3120,7 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
test_case.disabled_test_count());
fprintf(out,
"errors=\"0\" time=\"%s\">\n",
- internal::FormatTimeInMillisAsSeconds(test_case.elapsed_time()));
+ FormatTimeInMillisAsSeconds(test_case.elapsed_time()));
for (int i = 0; i < test_case.total_test_count(); ++i)
PrintXmlTestInfo(out, test_case.name(), *test_case.GetTestInfo(i));
fprintf(out, " </testsuite>\n");
@@ -3198,7 +3136,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
unit_test.total_test_count(),
unit_test.failed_test_count(),
unit_test.disabled_test_count(),
- internal::FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
+ FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
if (GTEST_FLAG(shuffle)) {
fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
}
@@ -3210,7 +3148,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
// Produces a string representing the test properties in a result as space
// delimited XML attributes based on the property key="value" pairs.
-internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
+String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
const TestResult& result) {
Message attributes;
for (int i = 0; i < result.test_property_count(); ++i) {
@@ -3223,8 +3161,6 @@ internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
// End XmlUnitTestResultPrinter
-namespace internal {
-
// Class ScopedTrace
// Pushes the given source file location and message onto a per-thread
@@ -3271,6 +3207,84 @@ OsStackTraceGetter::kElidedFramesMarker =
} // namespace internal
+// class EventListeners
+
+EventListeners::EventListeners()
+ : repeater_(new internal::UnitTestEventsRepeater()),
+ default_result_printer_(NULL),
+ default_xml_generator_(NULL) {
+}
+
+EventListeners::~EventListeners() { delete repeater_; }
+
+// Returns the standard listener responsible for the default console
+// output. Can be removed from the listeners list to shut down default
+// console output. Note that removing this object from the listener list
+// with Release transfers its ownership to the user.
+void EventListeners::Append(UnitTestEventListenerInterface* listener) {
+ repeater_->Append(listener);
+}
+
+// Removes the given event listener from the list and returns it. It then
+// becomes the caller's responsibility to delete the listener. Returns
+// NULL if the listener is not found in the list.
+UnitTestEventListenerInterface* EventListeners::Release(
+ UnitTestEventListenerInterface* listener) {
+ if (listener == default_result_printer_)
+ default_result_printer_ = NULL;
+ else if (listener == default_xml_generator_)
+ default_xml_generator_ = NULL;
+ return repeater_->Release(listener);
+}
+
+// Returns repeater that broadcasts the UnitTestEventListenerInterface
+// events to all subscribers.
+UnitTestEventListenerInterface* EventListeners::repeater() { return repeater_; }
+
+// Sets the default_result_printer attribute to the provided listener.
+// The listener is also added to the listener list and previous
+// default_result_printer is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void EventListeners::SetDefaultResultPrinter(
+ UnitTestEventListenerInterface* listener) {
+ if (default_result_printer_ != listener) {
+ // It is an error to pass this method a listener that is already in the
+ // list.
+ delete Release(default_result_printer_);
+ default_result_printer_ = listener;
+ if (listener != NULL)
+ Append(listener);
+ }
+}
+
+// Sets the default_xml_generator attribute to the provided listener. The
+// listener is also added to the listener list and previous
+// default_xml_generator is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void EventListeners::SetDefaultXmlGenerator(
+ UnitTestEventListenerInterface* listener) {
+ if (default_xml_generator_ != listener) {
+ // It is an error to pass this method a listener that is already in the
+ // list.
+ delete Release(default_xml_generator_);
+ default_xml_generator_ = listener;
+ if (listener != NULL)
+ Append(listener);
+ }
+}
+
+// Controls whether events will be forwarded by the repeater to the
+// listeners in the list.
+bool EventListeners::EventForwardingEnabled() const {
+ return repeater_->forwarding_enabled();
+}
+
+void EventListeners::SuppressEventForwarding() {
+ repeater_->set_forwarding_enabled(false);
+}
+
// class UnitTest
// Gets the singleton UnitTest object. The first time this method is
@@ -3359,6 +3373,12 @@ const TestCase* UnitTest::GetTestCase(int i) const {
return impl()->GetTestCase(i);
}
+// Returns the list of event listeners that can be used to track events
+// inside Google Test.
+EventListeners& UnitTest::listeners() {
+ return *impl()->listeners();
+}
+
// Registers and returns a global test environment. When a test
// program is run, all global test environments will be set-up in the
// order they were registered. After all tests in the program have
@@ -3614,8 +3634,8 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
current_test_case_(NULL),
current_test_info_(NULL),
ad_hoc_test_result_(),
- result_printer_(NULL),
os_stack_trace_getter_(NULL),
+ post_flag_parse_init_performed_(false),
random_seed_(0),
#if GTEST_HAS_DEATH_TEST
elapsed_time_(0),
@@ -3624,6 +3644,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
#else
elapsed_time_(0) {
#endif // GTEST_HAS_DEATH_TEST
+ listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
}
UnitTestImpl::~UnitTestImpl() {
@@ -3633,12 +3654,58 @@ UnitTestImpl::~UnitTestImpl() {
// Deletes every Environment.
environments_.ForEach(internal::Delete<Environment>);
- // Deletes the current test result printer.
- delete result_printer_;
-
delete os_stack_trace_getter_;
}
+#if GTEST_HAS_DEATH_TEST
+// Disables event forwarding if the control is currently in a death test
+// subprocess. Must not be called before InitGoogleTest.
+void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
+ if (internal_run_death_test_flag_.get() != NULL)
+ listeners()->SuppressEventForwarding();
+}
+#endif // GTEST_HAS_DEATH_TEST
+
+// Initializes event listeners performing XML output as specified by
+// UnitTestOptions. Must not be called before InitGoogleTest.
+void UnitTestImpl::ConfigureXmlOutput() {
+ const String& output_format = UnitTestOptions::GetOutputFormat();
+ if (output_format == "xml") {
+ listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
+ UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
+ } else if (output_format != "") {
+ printf("WARNING: unrecognized output format \"%s\" ignored.\n",
+ output_format.c_str());
+ fflush(stdout);
+ }
+}
+
+// Performs initialization dependent upon flag values obtained in
+// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to
+// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest
+// this function is also called from RunAllTests. Since this function can be
+// called more than once, it has to be idempotent.
+void UnitTestImpl::PostFlagParsingInit() {
+ // Ensures that this function does not execute more than once.
+ if (!post_flag_parse_init_performed_) {
+ post_flag_parse_init_performed_ = true;
+
+#if GTEST_HAS_DEATH_TEST
+ InitDeathTestSubprocessControlInfo();
+ SuppressTestEventsIfInSubprocess();
+#endif // GTEST_HAS_DEATH_TEST
+
+ // Registers parameterized tests. This makes parameterized tests
+ // available to the UnitTest reflection API without running
+ // RUN_ALL_TESTS.
+ RegisterParameterizedTests();
+
+ // Configures listeners for XML output. This makes it possible for users
+ // to shut down the default XML output before invoking RUN_ALL_TESTS.
+ ConfigureXmlOutput();
+ }
+}
+
// A predicate that checks the name of a TestCase against a known
// value.
//
@@ -3726,7 +3793,8 @@ int UnitTestImpl::RunAllTests() {
if (g_help_flag)
return 0;
- RegisterParameterizedTests();
+ // TODO(vladl@google.com): Add a call to PostFlagParsingInit() here when
+ // merging into the main branch.
// Even if sharding is not on, test runners may want to use the
// GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
@@ -3738,12 +3806,9 @@ int UnitTestImpl::RunAllTests() {
bool in_subprocess_for_death_test = false;
#if GTEST_HAS_DEATH_TEST
- internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
#endif // GTEST_HAS_DEATH_TEST
- UnitTestEventListenerInterface * const printer = result_printer();
-
const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
in_subprocess_for_death_test);
@@ -3766,6 +3831,8 @@ int UnitTestImpl::RunAllTests() {
// True iff at least one test has failed.
bool failed = false;
+ UnitTestEventListenerInterface* repeater = listeners()->repeater();
+
// How many times to repeat the tests? We don't want to repeat them
// when we are inside the subprocess of a death test.
const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
@@ -3773,21 +3840,24 @@ int UnitTestImpl::RunAllTests() {
const bool forever = repeat < 0;
for (int i = 0; forever || i != repeat; i++) {
if (repeat != 1) {
+ // TODO(vladl@google.com): Move this output to
+ // PrettyUnitTestResultPrinter. Add the iteration number parameter to
+ // OnUnitTestStart.
printf("\nRepeating all tests (iteration %d) . . .\n\n", i + 1);
}
- // Tells the unit test event listener that the tests are about to
- // start.
- printer->OnUnitTestStart(*parent_);
+ // Tells the unit test event listeners that the tests are about to start.
+ repeater->OnUnitTestStart(*parent_);
+ // TODO(vladl@google.com): Move to before the OnUnitTestStart notification?
const TimeInMillis start = GetTimeInMillis();
// Runs each test case if there is at least one test to run.
if (has_tests_to_run) {
// Sets up all environments beforehand.
- printer->OnGlobalSetUpStart(*parent_);
+ repeater->OnGlobalSetUpStart(*parent_);
environments_.ForEach(SetUpEnvironment);
- printer->OnGlobalSetUpEnd(*parent_);
+ repeater->OnGlobalSetUpEnd(*parent_);
// Runs the tests only if there was no fatal failure during global
// set-up.
@@ -3796,16 +3866,15 @@ int UnitTestImpl::RunAllTests() {
}
// Tears down all environments in reverse order afterwards.
- printer->OnGlobalTearDownStart(*parent_);
+ repeater->OnGlobalTearDownStart(*parent_);
environments_in_reverse_order_.ForEach(TearDownEnvironment);
- printer->OnGlobalTearDownEnd(*parent_);
+ repeater->OnGlobalTearDownEnd(*parent_);
}
elapsed_time_ = GetTimeInMillis() - start;
- // Tells the unit test event listener that the tests have just
- // finished.
- printer->OnUnitTestEnd(*parent_);
+ // Tells the unit test event listener that the tests have just finished.
+ repeater->OnUnitTestEnd(*parent_);
// Gets the result and clears it.
if (!Passed()) {
@@ -3997,49 +4066,6 @@ void UnitTestImpl::ListTestsMatchingFilter() {
fflush(stdout);
}
-// Sets the unit test result printer.
-//
-// Does nothing if the input and the current printer object are the
-// same; otherwise, deletes the old printer object and makes the
-// input the current printer.
-void UnitTestImpl::set_result_printer(
- UnitTestEventListenerInterface* result_printer) {
- if (result_printer_ != result_printer) {
- delete result_printer_;
- result_printer_ = result_printer;
- }
-}
-
-// Returns the current unit test result printer if it is not NULL;
-// otherwise, creates an appropriate result printer, makes it the
-// current printer, and returns it.
-UnitTestEventListenerInterface* UnitTestImpl::result_printer() {
- if (result_printer_ != NULL) {
- return result_printer_;
- }
-
-#if GTEST_HAS_DEATH_TEST
- if (internal_run_death_test_flag_.get() != NULL) {
- result_printer_ = new NullUnitTestResultPrinter;
- return result_printer_;
- }
-#endif // GTEST_HAS_DEATH_TEST
-
- UnitTestEventsRepeater *repeater = new UnitTestEventsRepeater;
- const String& output_format = internal::UnitTestOptions::GetOutputFormat();
- if (output_format == "xml") {
- repeater->AddListener(new XmlUnitTestResultPrinter(
- internal::UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
- } else if (output_format != "") {
- printf("WARNING: unrecognized output format \"%s\" ignored.\n",
- output_format.c_str());
- fflush(stdout);
- }
- repeater->AddListener(new PrettyUnitTestResultPrinter);
- result_printer_ = repeater;
- return result_printer_;
-}
-
// Sets the OS stack trace getter.
//
// Does nothing if the input and the current OS stack trace getter are
@@ -4420,6 +4446,7 @@ void InitGoogleTestImpl(int* argc, CharType** argv) {
#endif // GTEST_HAS_DEATH_TEST
ParseGoogleTestFlagsOnly(argc, argv);
+ GetUnitTestImpl()->PostFlagParsingInit();
}
} // namespace internal