Updated gtest to upstream rev616
This commit is contained in:
parent
cfa9aa9206
commit
1ee5c95ee9
File diff suppressed because it is too large
Load Diff
@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# pragma GCC diagnostic ignored "-Wmissing-declarations"
|
# pragma GCC diagnostic ignored "-Wmissing-declarations"
|
||||||
|
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The following lines pull in the real gtest *.cc files.
|
// The following lines pull in the real gtest *.cc files.
|
||||||
@ -313,6 +314,7 @@ class GTEST_API_ SingleFailureChecker {
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
|
|
||||||
@ -514,6 +516,12 @@ GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
|
|||||||
// Formats the given time in milliseconds as seconds.
|
// Formats the given time in milliseconds as seconds.
|
||||||
GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
|
GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
|
||||||
|
|
||||||
|
// Converts the given time in milliseconds to a date string in the ISO 8601
|
||||||
|
// format, without the timezone information. N.B.: due to the use the
|
||||||
|
// non-reentrant localtime() function, this function is not thread safe. Do
|
||||||
|
// not use it in any code that can be called from multiple threads.
|
||||||
|
GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
|
||||||
|
|
||||||
// Parses a string for an Int32 flag, in the form of "--flag=value".
|
// Parses a string for an Int32 flag, in the form of "--flag=value".
|
||||||
//
|
//
|
||||||
// On success, stores the value of the flag in *value, and returns
|
// On success, stores the value of the flag in *value, and returns
|
||||||
@ -592,6 +600,7 @@ class GTestFlagSaver {
|
|||||||
GTEST_FLAG(stream_result_to) = stream_result_to_;
|
GTEST_FLAG(stream_result_to) = stream_result_to_;
|
||||||
GTEST_FLAG(throw_on_failure) = throw_on_failure_;
|
GTEST_FLAG(throw_on_failure) = throw_on_failure_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Fields for saving the original values of flags.
|
// Fields for saving the original values of flags.
|
||||||
bool also_run_disabled_tests_;
|
bool also_run_disabled_tests_;
|
||||||
@ -834,8 +843,11 @@ class OsStackTraceGetterInterface {
|
|||||||
class OsStackTraceGetter : public OsStackTraceGetterInterface {
|
class OsStackTraceGetter : public OsStackTraceGetterInterface {
|
||||||
public:
|
public:
|
||||||
OsStackTraceGetter() : caller_frame_(NULL) {}
|
OsStackTraceGetter() : caller_frame_(NULL) {}
|
||||||
virtual String CurrentStackTrace(int max_depth, int skip_count);
|
|
||||||
virtual void UponLeavingGTest();
|
virtual String CurrentStackTrace(int max_depth, int skip_count)
|
||||||
|
GTEST_LOCK_EXCLUDED_(mutex_);
|
||||||
|
|
||||||
|
virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_);
|
||||||
|
|
||||||
// This string is inserted in place of stack frames that are part of
|
// This string is inserted in place of stack frames that are part of
|
||||||
// Google Test's implementation.
|
// Google Test's implementation.
|
||||||
@ -950,6 +962,10 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
// Gets the number of tests that should run.
|
// Gets the number of tests that should run.
|
||||||
int test_to_run_count() const;
|
int test_to_run_count() const;
|
||||||
|
|
||||||
|
// Gets the time of the test program start, in ms from the start of the
|
||||||
|
// UNIX epoch.
|
||||||
|
TimeInMillis start_timestamp() const { return start_timestamp_; }
|
||||||
|
|
||||||
// Gets the elapsed time, in milliseconds.
|
// Gets the elapsed time, in milliseconds.
|
||||||
TimeInMillis elapsed_time() const { return elapsed_time_; }
|
TimeInMillis elapsed_time() const { return elapsed_time_; }
|
||||||
|
|
||||||
@ -1008,7 +1024,7 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
// For example, if Foo() calls Bar(), which in turn calls
|
// For example, if Foo() calls Bar(), which in turn calls
|
||||||
// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
|
// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
|
||||||
// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
|
// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
|
||||||
String CurrentOsStackTraceExceptTop(int skip_count);
|
String CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_;
|
||||||
|
|
||||||
// Finds and returns a TestCase with the given name. If one doesn't
|
// Finds and returns a TestCase with the given name. If one doesn't
|
||||||
// exist, creates one and returns it.
|
// exist, creates one and returns it.
|
||||||
@ -1282,6 +1298,10 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
// Our random number generator.
|
// Our random number generator.
|
||||||
internal::Random random_;
|
internal::Random random_;
|
||||||
|
|
||||||
|
// The time of the test program start, in ms from the start of the
|
||||||
|
// UNIX epoch.
|
||||||
|
TimeInMillis start_timestamp_;
|
||||||
|
|
||||||
// How long the test took to run, in milliseconds.
|
// How long the test took to run, in milliseconds.
|
||||||
TimeInMillis elapsed_time_;
|
TimeInMillis elapsed_time_;
|
||||||
|
|
||||||
@ -1613,7 +1633,7 @@ UInt32 Random::Generate(UInt32 range) {
|
|||||||
// Test. g_init_gtest_count is set to the number of times
|
// Test. g_init_gtest_count is set to the number of times
|
||||||
// InitGoogleTest() has been called. We don't protect this variable
|
// InitGoogleTest() has been called. We don't protect this variable
|
||||||
// under a mutex as it is only accessed in the main thread.
|
// under a mutex as it is only accessed in the main thread.
|
||||||
int g_init_gtest_count = 0;
|
GTEST_API_ int g_init_gtest_count = 0;
|
||||||
static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
|
static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
|
||||||
|
|
||||||
// Iterates over a vector of TestCases, keeping a running sum of the
|
// Iterates over a vector of TestCases, keeping a running sum of the
|
||||||
@ -1668,7 +1688,7 @@ void AssertHelper::operator=(const Message& message) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mutex for linked pointers.
|
// Mutex for linked pointers.
|
||||||
GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
|
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
|
||||||
|
|
||||||
// Application pathname gotten in InitGoogleTest.
|
// Application pathname gotten in InitGoogleTest.
|
||||||
String g_executable_path;
|
String g_executable_path;
|
||||||
@ -2125,17 +2145,6 @@ TimeInMillis GetTimeInMillis() {
|
|||||||
|
|
||||||
// class String
|
// class String
|
||||||
|
|
||||||
// Returns the input enclosed in double quotes if it's not NULL;
|
|
||||||
// otherwise returns "(null)". For example, "\"Hello\"" is returned
|
|
||||||
// for input "Hello".
|
|
||||||
//
|
|
||||||
// This is useful for printing a C string in the syntax of a literal.
|
|
||||||
//
|
|
||||||
// Known issue: escape sequences are not handled yet.
|
|
||||||
String String::ShowCStringQuoted(const char* c_str) {
|
|
||||||
return c_str ? String::Format("\"%s\"", c_str) : String("(null)");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copies at most length characters from str into a newly-allocated
|
// Copies at most length characters from str into a newly-allocated
|
||||||
// piece of memory of size length+1. The memory is allocated with new[].
|
// piece of memory of size length+1. The memory is allocated with new[].
|
||||||
// A terminating null byte is written to the memory, and a pointer to it
|
// A terminating null byte is written to the memory, and a pointer to it
|
||||||
@ -2476,8 +2485,8 @@ AssertionResult CmpHelperSTREQ(const char* expected_expression,
|
|||||||
|
|
||||||
return EqFailure(expected_expression,
|
return EqFailure(expected_expression,
|
||||||
actual_expression,
|
actual_expression,
|
||||||
String::ShowCStringQuoted(expected),
|
PrintToString(expected),
|
||||||
String::ShowCStringQuoted(actual),
|
PrintToString(actual),
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2492,8 +2501,8 @@ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
|
|||||||
|
|
||||||
return EqFailure(expected_expression,
|
return EqFailure(expected_expression,
|
||||||
actual_expression,
|
actual_expression,
|
||||||
String::ShowCStringQuoted(expected),
|
PrintToString(expected),
|
||||||
String::ShowCStringQuoted(actual),
|
PrintToString(actual),
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2841,15 +2850,6 @@ String String::ShowWideCString(const wchar_t * wide_c_str) {
|
|||||||
return String(internal::WideStringToUtf8(wide_c_str, -1).c_str());
|
return String(internal::WideStringToUtf8(wide_c_str, -1).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar to ShowWideCString(), except that this function encloses
|
|
||||||
// the converted string in double quotes.
|
|
||||||
String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) {
|
|
||||||
if (wide_c_str == NULL) return String("(null)");
|
|
||||||
|
|
||||||
return String::Format("L\"%s\"",
|
|
||||||
String::ShowWideCString(wide_c_str).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compares two wide C strings. Returns true iff they have the same
|
// Compares two wide C strings. Returns true iff they have the same
|
||||||
// content.
|
// content.
|
||||||
//
|
//
|
||||||
@ -2875,8 +2875,8 @@ AssertionResult CmpHelperSTREQ(const char* expected_expression,
|
|||||||
|
|
||||||
return EqFailure(expected_expression,
|
return EqFailure(expected_expression,
|
||||||
actual_expression,
|
actual_expression,
|
||||||
String::ShowWideCStringQuoted(expected),
|
PrintToString(expected),
|
||||||
String::ShowWideCStringQuoted(actual),
|
PrintToString(actual),
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2891,8 +2891,8 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression,
|
|||||||
|
|
||||||
return AssertionFailure() << "Expected: (" << s1_expression << ") != ("
|
return AssertionFailure() << "Expected: (" << s1_expression << ") != ("
|
||||||
<< s2_expression << "), actual: "
|
<< s2_expression << "), actual: "
|
||||||
<< String::ShowWideCStringQuoted(s1)
|
<< PrintToString(s1)
|
||||||
<< " vs " << String::ShowWideCStringQuoted(s2);
|
<< " vs " << PrintToString(s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compares two C strings, ignoring case. Returns true iff they have
|
// Compares two C strings, ignoring case. Returns true iff they have
|
||||||
@ -4015,8 +4015,6 @@ class PrettyUnitTestResultPrinter : public TestEventListener {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static void PrintFailedTests(const UnitTest& unit_test);
|
static void PrintFailedTests(const UnitTest& unit_test);
|
||||||
|
|
||||||
internal::String test_case_name_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fired before each iteration of tests starts.
|
// Fired before each iteration of tests starts.
|
||||||
@ -4063,11 +4061,10 @@ void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
|
void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
|
||||||
test_case_name_ = test_case.name();
|
|
||||||
const internal::String counts =
|
const internal::String counts =
|
||||||
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
|
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
|
||||||
ColoredPrintf(COLOR_GREEN, "[----------] ");
|
ColoredPrintf(COLOR_GREEN, "[----------] ");
|
||||||
printf("%s from %s", counts.c_str(), test_case_name_.c_str());
|
printf("%s from %s", counts.c_str(), test_case.name());
|
||||||
if (test_case.type_param() == NULL) {
|
if (test_case.type_param() == NULL) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
} else {
|
} else {
|
||||||
@ -4078,7 +4075,7 @@ void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
|
|||||||
|
|
||||||
void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
|
void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
|
||||||
ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
|
ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
|
||||||
PrintTestName(test_case_name_.c_str(), test_info.name());
|
PrintTestName(test_info.test_case_name(), test_info.name());
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
@ -4101,7 +4098,7 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
|
|||||||
} else {
|
} else {
|
||||||
ColoredPrintf(COLOR_RED, "[ FAILED ] ");
|
ColoredPrintf(COLOR_RED, "[ FAILED ] ");
|
||||||
}
|
}
|
||||||
PrintTestName(test_case_name_.c_str(), test_info.name());
|
PrintTestName(test_info.test_case_name(), test_info.name());
|
||||||
if (test_info.result()->Failed())
|
if (test_info.result()->Failed())
|
||||||
PrintFullTestCommentIfPresent(test_info);
|
PrintFullTestCommentIfPresent(test_info);
|
||||||
|
|
||||||
@ -4117,12 +4114,11 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
|
|||||||
void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
|
void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
|
||||||
if (!GTEST_FLAG(print_time)) return;
|
if (!GTEST_FLAG(print_time)) return;
|
||||||
|
|
||||||
test_case_name_ = test_case.name();
|
|
||||||
const internal::String counts =
|
const internal::String counts =
|
||||||
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
|
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
|
||||||
ColoredPrintf(COLOR_GREEN, "[----------] ");
|
ColoredPrintf(COLOR_GREEN, "[----------] ");
|
||||||
printf("%s from %s (%s ms total)\n\n",
|
printf("%s from %s (%s ms total)\n\n",
|
||||||
counts.c_str(), test_case_name_.c_str(),
|
counts.c_str(), test_case.name(),
|
||||||
internal::StreamableToString(test_case.elapsed_time()).c_str());
|
internal::StreamableToString(test_case.elapsed_time()).c_str());
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
@ -4507,6 +4503,32 @@ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Converts the given epoch time in milliseconds to a date string in the ISO
|
||||||
|
// 8601 format, without the timezone information.
|
||||||
|
std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {
|
||||||
|
// Using non-reentrant version as localtime_r is not portable.
|
||||||
|
time_t seconds = static_cast<time_t>(ms / 1000);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push) // Saves the current warning state.
|
||||||
|
# pragma warning(disable:4996) // Temporarily disables warning 4996
|
||||||
|
// (function or variable may be unsafe).
|
||||||
|
const struct tm* const time_struct = localtime(&seconds); // NOLINT
|
||||||
|
# pragma warning(pop) // Restores the warning state again.
|
||||||
|
#else
|
||||||
|
const struct tm* const time_struct = localtime(&seconds); // NOLINT
|
||||||
|
#endif
|
||||||
|
if (time_struct == NULL)
|
||||||
|
return ""; // Invalid ms value
|
||||||
|
|
||||||
|
return String::Format("%d-%02d-%02dT%02d:%02d:%02d", // YYYY-MM-DDThh:mm:ss
|
||||||
|
time_struct->tm_year + 1900,
|
||||||
|
time_struct->tm_mon + 1,
|
||||||
|
time_struct->tm_mday,
|
||||||
|
time_struct->tm_hour,
|
||||||
|
time_struct->tm_min,
|
||||||
|
time_struct->tm_sec);
|
||||||
|
}
|
||||||
|
|
||||||
// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
|
// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
|
||||||
void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
|
void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
|
||||||
const char* data) {
|
const char* data) {
|
||||||
@ -4556,16 +4578,17 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
|
|||||||
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()) {
|
||||||
if (++failures == 1)
|
if (++failures == 1) {
|
||||||
*stream << ">\n";
|
*stream << ">\n";
|
||||||
*stream << " <failure message=\""
|
}
|
||||||
<< EscapeXmlAttribute(part.summary()).c_str()
|
|
||||||
<< "\" type=\"\">";
|
|
||||||
const string location = internal::FormatCompilerIndependentFileLocation(
|
const string location = internal::FormatCompilerIndependentFileLocation(
|
||||||
part.file_name(), part.line_number());
|
part.file_name(), part.line_number());
|
||||||
const string message = location + "\n" + part.message();
|
const string summary = location + "\n" + part.summary();
|
||||||
OutputXmlCDataSection(stream,
|
*stream << " <failure message=\""
|
||||||
RemoveInvalidXmlCharacters(message).c_str());
|
<< EscapeXmlAttribute(summary.c_str())
|
||||||
|
<< "\" type=\"\">";
|
||||||
|
const string detail = location + "\n" + part.message();
|
||||||
|
OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
|
||||||
*stream << "</failure>\n";
|
*stream << "</failure>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4603,10 +4626,11 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
|
|||||||
fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||||
fprintf(out,
|
fprintf(out,
|
||||||
"<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
|
"<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
|
||||||
"errors=\"0\" time=\"%s\" ",
|
"errors=\"0\" timestamp=\"%s\" time=\"%s\" ",
|
||||||
unit_test.total_test_count(),
|
unit_test.total_test_count(),
|
||||||
unit_test.failed_test_count(),
|
unit_test.failed_test_count(),
|
||||||
unit_test.disabled_test_count(),
|
unit_test.disabled_test_count(),
|
||||||
|
FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()).c_str(),
|
||||||
FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str());
|
FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str());
|
||||||
if (GTEST_FLAG(shuffle)) {
|
if (GTEST_FLAG(shuffle)) {
|
||||||
fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
|
fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
|
||||||
@ -4812,8 +4836,8 @@ void StreamingListener::MakeConnection() {
|
|||||||
|
|
||||||
// Pushes the given source file location and message onto a per-thread
|
// Pushes the given source file location and message onto a per-thread
|
||||||
// trace stack maintained by Google Test.
|
// trace stack maintained by Google Test.
|
||||||
// L < UnitTest::mutex_
|
ScopedTrace::ScopedTrace(const char* file, int line, const Message& message)
|
||||||
ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) {
|
GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
|
||||||
TraceInfo trace;
|
TraceInfo trace;
|
||||||
trace.file = file;
|
trace.file = file;
|
||||||
trace.line = line;
|
trace.line = line;
|
||||||
@ -4823,8 +4847,8 @@ ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pops the info pushed by the c'tor.
|
// Pops the info pushed by the c'tor.
|
||||||
// L < UnitTest::mutex_
|
ScopedTrace::~ScopedTrace()
|
||||||
ScopedTrace::~ScopedTrace() {
|
GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
|
||||||
UnitTest::GetInstance()->PopGTestTrace();
|
UnitTest::GetInstance()->PopGTestTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4838,14 +4862,14 @@ ScopedTrace::~ScopedTrace() {
|
|||||||
// skip_count - the number of top frames to be skipped; doesn't count
|
// skip_count - the number of top frames to be skipped; doesn't count
|
||||||
// against max_depth.
|
// against max_depth.
|
||||||
//
|
//
|
||||||
// L < mutex_
|
String OsStackTraceGetter::CurrentStackTrace(int /* max_depth */,
|
||||||
// We use "L < mutex_" to denote that the function may acquire mutex_.
|
int /* skip_count */)
|
||||||
String OsStackTraceGetter::CurrentStackTrace(int, int) {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
return String("");
|
return String("");
|
||||||
}
|
}
|
||||||
|
|
||||||
// L < mutex_
|
void OsStackTraceGetter::UponLeavingGTest()
|
||||||
void OsStackTraceGetter::UponLeavingGTest() {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* const
|
const char* const
|
||||||
@ -4999,6 +5023,12 @@ int UnitTest::total_test_count() const { return impl()->total_test_count(); }
|
|||||||
// Gets the number of tests that should run.
|
// Gets the number of tests that should run.
|
||||||
int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
|
int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
|
||||||
|
|
||||||
|
// Gets the time of the test program start, in ms from the start of the
|
||||||
|
// UNIX epoch.
|
||||||
|
internal::TimeInMillis UnitTest::start_timestamp() const {
|
||||||
|
return impl()->start_timestamp();
|
||||||
|
}
|
||||||
|
|
||||||
// Gets the elapsed time, in milliseconds.
|
// Gets the elapsed time, in milliseconds.
|
||||||
internal::TimeInMillis UnitTest::elapsed_time() const {
|
internal::TimeInMillis UnitTest::elapsed_time() const {
|
||||||
return impl()->elapsed_time();
|
return impl()->elapsed_time();
|
||||||
@ -5052,12 +5082,13 @@ Environment* UnitTest::AddEnvironment(Environment* env) {
|
|||||||
// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call
|
// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call
|
||||||
// this to report their results. The user code should use the
|
// this to report their results. The user code should use the
|
||||||
// assertion macros instead of calling this directly.
|
// assertion macros instead of calling this directly.
|
||||||
// L < mutex_
|
void UnitTest::AddTestPartResult(
|
||||||
void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
|
TestPartResult::Type result_type,
|
||||||
const char* file_name,
|
const char* file_name,
|
||||||
int line_number,
|
int line_number,
|
||||||
const internal::String& message,
|
const internal::String& message,
|
||||||
const internal::String& os_stack_trace) {
|
const internal::String& os_stack_trace)
|
||||||
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
Message msg;
|
Message msg;
|
||||||
msg << message;
|
msg << message;
|
||||||
|
|
||||||
@ -5141,7 +5172,6 @@ int UnitTest::Run() {
|
|||||||
// process. In either case the user does not want to see pop-up dialogs
|
// process. In either case the user does not want to see pop-up dialogs
|
||||||
// about crashes - they are expected.
|
// about crashes - they are expected.
|
||||||
if (impl()->catch_exceptions() || in_death_test_child_process) {
|
if (impl()->catch_exceptions() || in_death_test_child_process) {
|
||||||
|
|
||||||
# if !GTEST_OS_WINDOWS_MOBILE
|
# if !GTEST_OS_WINDOWS_MOBILE
|
||||||
// SetErrorMode doesn't exist on CE.
|
// SetErrorMode doesn't exist on CE.
|
||||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
|
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
|
||||||
@ -5172,7 +5202,6 @@ int UnitTest::Run() {
|
|||||||
0x0, // Clear the following flags:
|
0x0, // Clear the following flags:
|
||||||
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
|
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_SEH
|
#endif // GTEST_HAS_SEH
|
||||||
|
|
||||||
@ -5190,16 +5219,16 @@ const char* UnitTest::original_working_dir() const {
|
|||||||
|
|
||||||
// Returns the TestCase object for the test that's currently running,
|
// Returns the TestCase object for the test that's currently running,
|
||||||
// or NULL if no test is running.
|
// or NULL if no test is running.
|
||||||
// L < mutex_
|
const TestCase* UnitTest::current_test_case() const
|
||||||
const TestCase* UnitTest::current_test_case() const {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(&mutex_);
|
||||||
return impl_->current_test_case();
|
return impl_->current_test_case();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the TestInfo object for the test that's currently running,
|
// Returns the TestInfo object for the test that's currently running,
|
||||||
// or NULL if no test is running.
|
// or NULL if no test is running.
|
||||||
// L < mutex_
|
const TestInfo* UnitTest::current_test_info() const
|
||||||
const TestInfo* UnitTest::current_test_info() const {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(&mutex_);
|
||||||
return impl_->current_test_info();
|
return impl_->current_test_info();
|
||||||
}
|
}
|
||||||
@ -5210,9 +5239,9 @@ int UnitTest::random_seed() const { return impl_->random_seed(); }
|
|||||||
#if GTEST_HAS_PARAM_TEST
|
#if GTEST_HAS_PARAM_TEST
|
||||||
// Returns ParameterizedTestCaseRegistry object used to keep track of
|
// Returns ParameterizedTestCaseRegistry object used to keep track of
|
||||||
// value-parameterized tests and instantiate and register them.
|
// value-parameterized tests and instantiate and register them.
|
||||||
// L < mutex_
|
|
||||||
internal::ParameterizedTestCaseRegistry&
|
internal::ParameterizedTestCaseRegistry&
|
||||||
UnitTest::parameterized_test_registry() {
|
UnitTest::parameterized_test_registry()
|
||||||
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
return impl_->parameterized_test_registry();
|
return impl_->parameterized_test_registry();
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_PARAM_TEST
|
#endif // GTEST_HAS_PARAM_TEST
|
||||||
@ -5229,15 +5258,15 @@ UnitTest::~UnitTest() {
|
|||||||
|
|
||||||
// Pushes a trace defined by SCOPED_TRACE() on to the per-thread
|
// Pushes a trace defined by SCOPED_TRACE() on to the per-thread
|
||||||
// Google Test trace stack.
|
// Google Test trace stack.
|
||||||
// L < mutex_
|
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace)
|
||||||
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(&mutex_);
|
||||||
impl_->gtest_trace_stack().push_back(trace);
|
impl_->gtest_trace_stack().push_back(trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pops a trace from the per-thread Google Test trace stack.
|
// Pops a trace from the per-thread Google Test trace stack.
|
||||||
// L < mutex_
|
void UnitTest::PopGTestTrace()
|
||||||
void UnitTest::PopGTestTrace() {
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
internal::MutexLock lock(&mutex_);
|
internal::MutexLock lock(&mutex_);
|
||||||
impl_->gtest_trace_stack().pop_back();
|
impl_->gtest_trace_stack().pop_back();
|
||||||
}
|
}
|
||||||
@ -5273,6 +5302,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
|
|||||||
post_flag_parse_init_performed_(false),
|
post_flag_parse_init_performed_(false),
|
||||||
random_seed_(0), // Will be overridden by the flag before first use.
|
random_seed_(0), // Will be overridden by the flag before first use.
|
||||||
random_(0), // Will be reseeded before first use.
|
random_(0), // Will be reseeded before first use.
|
||||||
|
start_timestamp_(0),
|
||||||
elapsed_time_(0),
|
elapsed_time_(0),
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
internal_run_death_test_flag_(NULL),
|
internal_run_death_test_flag_(NULL),
|
||||||
@ -5504,6 +5534,7 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
|
|
||||||
TestEventListener* repeater = listeners()->repeater();
|
TestEventListener* repeater = listeners()->repeater();
|
||||||
|
|
||||||
|
start_timestamp_ = GetTimeInMillis();
|
||||||
repeater->OnTestProgramStart(*parent_);
|
repeater->OnTestProgramStart(*parent_);
|
||||||
|
|
||||||
// How many times to repeat the tests? We don't want to repeat them
|
// How many times to repeat the tests? We don't want to repeat them
|
||||||
@ -5865,7 +5896,7 @@ bool SkipPrefix(const char* prefix, const char** pstr) {
|
|||||||
// part can be omitted.
|
// part can be omitted.
|
||||||
//
|
//
|
||||||
// Returns the value of the flag, or NULL if the parsing failed.
|
// Returns the value of the flag, or NULL if the parsing failed.
|
||||||
static const char* ParseFlagValue(const char* str,
|
const char* ParseFlagValue(const char* str,
|
||||||
const char* flag,
|
const char* flag,
|
||||||
bool def_optional) {
|
bool def_optional) {
|
||||||
// str and flag must not be NULL.
|
// str and flag must not be NULL.
|
||||||
@ -6240,13 +6271,18 @@ void InitGoogleTest(int* argc, wchar_t** argv) {
|
|||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
# if GTEST_OS_MAC && !GTEST_OS_MAC_IOS
|
# if GTEST_OS_MAC
|
||||||
# include <crt_externs.h>
|
# include <crt_externs.h>
|
||||||
# endif // GTEST_OS_MAC
|
# endif // GTEST_OS_MAC
|
||||||
|
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <limits.h>
|
# include <limits.h>
|
||||||
|
|
||||||
|
# if GTEST_OS_LINUX
|
||||||
|
# include <signal.h>
|
||||||
|
# endif // GTEST_OS_LINUX
|
||||||
|
|
||||||
# include <stdarg.h>
|
# include <stdarg.h>
|
||||||
|
|
||||||
# if GTEST_OS_WINDOWS
|
# if GTEST_OS_WINDOWS
|
||||||
@ -6256,6 +6292,10 @@ void InitGoogleTest(int* argc, wchar_t** argv) {
|
|||||||
# include <sys/wait.h>
|
# include <sys/wait.h>
|
||||||
# endif // GTEST_OS_WINDOWS
|
# endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
|
# if GTEST_OS_QNX
|
||||||
|
# include <spawn.h>
|
||||||
|
# endif // GTEST_OS_QNX
|
||||||
|
|
||||||
#endif // GTEST_HAS_DEATH_TEST
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
|
|
||||||
@ -6301,13 +6341,42 @@ GTEST_DEFINE_string_(
|
|||||||
"Indicates the file, line number, temporal index of "
|
"Indicates the file, line number, temporal index of "
|
||||||
"the single death test to run, and a file descriptor to "
|
"the single death test to run, and a file descriptor to "
|
||||||
"which a success code may be sent, all separated by "
|
"which a success code may be sent, all separated by "
|
||||||
"colons. This flag is specified if and only if the current "
|
"the '|' characters. This flag is specified if and only if the current "
|
||||||
"process is a sub-process launched for running a thread-safe "
|
"process is a sub-process launched for running a thread-safe "
|
||||||
"death test. FOR INTERNAL USE ONLY.");
|
"death test. FOR INTERNAL USE ONLY.");
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Valid only for fast death tests. Indicates the code is running in the
|
||||||
|
// child process of a fast style death test.
|
||||||
|
static bool g_in_fast_death_test_child = false;
|
||||||
|
|
||||||
|
// Returns a Boolean value indicating whether the caller is currently
|
||||||
|
// executing in the context of the death test child process. Tools such as
|
||||||
|
// Valgrind heap checkers may need this to modify their behavior in death
|
||||||
|
// tests. IMPORTANT: This is an internal utility. Using it may break the
|
||||||
|
// implementation of death tests. User code MUST NOT use it.
|
||||||
|
bool InDeathTestChild() {
|
||||||
|
# if GTEST_OS_WINDOWS
|
||||||
|
|
||||||
|
// On Windows, death tests are thread-safe regardless of the value of the
|
||||||
|
// death_test_style flag.
|
||||||
|
return !GTEST_FLAG(internal_run_death_test).empty();
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
if (GTEST_FLAG(death_test_style) == "threadsafe")
|
||||||
|
return !GTEST_FLAG(internal_run_death_test).empty();
|
||||||
|
else
|
||||||
|
return g_in_fast_death_test_child;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
// ExitedWithCode constructor.
|
// ExitedWithCode constructor.
|
||||||
ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
|
ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
|
||||||
}
|
}
|
||||||
@ -7017,6 +7086,7 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
|
|||||||
// Event forwarding to the listeners of event listener API mush be shut
|
// Event forwarding to the listeners of event listener API mush be shut
|
||||||
// down in death test subprocesses.
|
// down in death test subprocesses.
|
||||||
GetUnitTestImpl()->listeners()->SuppressEventForwarding();
|
GetUnitTestImpl()->listeners()->SuppressEventForwarding();
|
||||||
|
g_in_fast_death_test_child = true;
|
||||||
return EXECUTE_TEST;
|
return EXECUTE_TEST;
|
||||||
} else {
|
} else {
|
||||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
||||||
@ -7036,6 +7106,11 @@ class ExecDeathTest : public ForkingDeathTest {
|
|||||||
ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
|
ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
|
||||||
virtual TestRole AssumeRole();
|
virtual TestRole AssumeRole();
|
||||||
private:
|
private:
|
||||||
|
static ::std::vector<testing::internal::string>
|
||||||
|
GetArgvsForDeathTestChildProcess() {
|
||||||
|
::std::vector<testing::internal::string> args = GetInjectableArgvs();
|
||||||
|
return args;
|
||||||
|
}
|
||||||
// The name of the file in which the death test is located.
|
// The name of the file in which the death test is located.
|
||||||
const char* const file_;
|
const char* const file_;
|
||||||
// The line number on which the death test is located.
|
// The line number on which the death test is located.
|
||||||
@ -7070,6 +7145,7 @@ class Arguments {
|
|||||||
char* const* Argv() {
|
char* const* Argv() {
|
||||||
return &args_[0];
|
return &args_[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<char*> args_;
|
std::vector<char*> args_;
|
||||||
};
|
};
|
||||||
@ -7081,7 +7157,7 @@ struct ExecDeathTestArgs {
|
|||||||
int close_fd; // File descriptor to close; the read end of a pipe
|
int close_fd; // File descriptor to close; the read end of a pipe
|
||||||
};
|
};
|
||||||
|
|
||||||
# if GTEST_OS_MAC && !GTEST_OS_MAC_IOS
|
# if GTEST_OS_MAC
|
||||||
inline char** GetEnviron() {
|
inline char** GetEnviron() {
|
||||||
// When Google Test is built as a framework on MacOS X, the environ variable
|
// When Google Test is built as a framework on MacOS X, the environ variable
|
||||||
// is unavailable. Apple's documentation (man environ) recommends using
|
// is unavailable. Apple's documentation (man environ) recommends using
|
||||||
@ -7095,6 +7171,7 @@ extern "C" char** environ;
|
|||||||
inline char** GetEnviron() { return environ; }
|
inline char** GetEnviron() { return environ; }
|
||||||
# endif // GTEST_OS_MAC
|
# endif // GTEST_OS_MAC
|
||||||
|
|
||||||
|
# if !GTEST_OS_QNX
|
||||||
// The main function for a threadsafe-style death test child process.
|
// The main function for a threadsafe-style death test child process.
|
||||||
// This function is called in a clone()-ed process and thus must avoid
|
// This function is called in a clone()-ed process and thus must avoid
|
||||||
// any potentially unsafe operations like malloc or libc functions.
|
// any potentially unsafe operations like malloc or libc functions.
|
||||||
@ -7127,6 +7204,7 @@ static int ExecDeathTestChildMain(void* child_arg) {
|
|||||||
GetLastErrnoDescription().c_str()));
|
GetLastErrnoDescription().c_str()));
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
# endif // !GTEST_OS_QNX
|
||||||
|
|
||||||
// Two utility routines that together determine the direction the stack
|
// Two utility routines that together determine the direction the stack
|
||||||
// grows.
|
// grows.
|
||||||
@ -7137,24 +7215,75 @@ static int ExecDeathTestChildMain(void* child_arg) {
|
|||||||
// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
|
// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
|
||||||
// StackLowerThanAddress into StackGrowsDown, which then doesn't give
|
// StackLowerThanAddress into StackGrowsDown, which then doesn't give
|
||||||
// correct answer.
|
// correct answer.
|
||||||
bool StackLowerThanAddress(const void* ptr) GTEST_NO_INLINE_;
|
void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_;
|
||||||
bool StackLowerThanAddress(const void* ptr) {
|
void StackLowerThanAddress(const void* ptr, bool* result) {
|
||||||
int dummy;
|
int dummy;
|
||||||
return &dummy < ptr;
|
*result = (&dummy < ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool StackGrowsDown() {
|
static bool StackGrowsDown() {
|
||||||
int dummy;
|
int dummy;
|
||||||
return StackLowerThanAddress(&dummy);
|
bool result;
|
||||||
|
StackLowerThanAddress(&dummy, &result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A threadsafe implementation of fork(2) for threadsafe-style death tests
|
// Spawns a child process with the same executable as the current process in
|
||||||
// that uses clone(2). It dies with an error message if anything goes
|
// a thread-safe manner and instructs it to run the death test. The
|
||||||
// wrong.
|
// implementation uses fork(2) + exec. On systems where clone(2) is
|
||||||
static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
|
// available, it is used instead, being slightly more thread-safe. On QNX,
|
||||||
|
// fork supports only single-threaded environments, so this function uses
|
||||||
|
// spawn(2) there instead. The function dies with an error message if
|
||||||
|
// anything goes wrong.
|
||||||
|
static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
|
||||||
ExecDeathTestArgs args = { argv, close_fd };
|
ExecDeathTestArgs args = { argv, close_fd };
|
||||||
pid_t child_pid = -1;
|
pid_t child_pid = -1;
|
||||||
|
|
||||||
|
# if GTEST_OS_QNX
|
||||||
|
// Obtains the current directory and sets it to be closed in the child
|
||||||
|
// process.
|
||||||
|
const int cwd_fd = open(".", O_RDONLY);
|
||||||
|
GTEST_DEATH_TEST_CHECK_(cwd_fd != -1);
|
||||||
|
GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC));
|
||||||
|
// We need to execute the test program in the same environment where
|
||||||
|
// it was originally invoked. Therefore we change to the original
|
||||||
|
// working directory first.
|
||||||
|
const char* const original_dir =
|
||||||
|
UnitTest::GetInstance()->original_working_dir();
|
||||||
|
// We can safely call chdir() as it's a direct system call.
|
||||||
|
if (chdir(original_dir) != 0) {
|
||||||
|
DeathTestAbort(String::Format("chdir(\"%s\") failed: %s",
|
||||||
|
original_dir,
|
||||||
|
GetLastErrnoDescription().c_str()));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd_flags;
|
||||||
|
// Set close_fd to be closed after spawn.
|
||||||
|
GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD));
|
||||||
|
GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD,
|
||||||
|
fd_flags | FD_CLOEXEC));
|
||||||
|
struct inheritance inherit = {0};
|
||||||
|
// spawn is a system call.
|
||||||
|
child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron());
|
||||||
|
// Restores the current working directory.
|
||||||
|
GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);
|
||||||
|
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));
|
||||||
|
|
||||||
|
# else // GTEST_OS_QNX
|
||||||
|
# if GTEST_OS_LINUX
|
||||||
|
// When a SIGPROF signal is received while fork() or clone() are executing,
|
||||||
|
// the process may hang. To avoid this, we ignore SIGPROF here and re-enable
|
||||||
|
// it after the call to fork()/clone() is complete.
|
||||||
|
struct sigaction saved_sigprof_action;
|
||||||
|
struct sigaction ignore_sigprof_action;
|
||||||
|
memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action));
|
||||||
|
sigemptyset(&ignore_sigprof_action.sa_mask);
|
||||||
|
ignore_sigprof_action.sa_handler = SIG_IGN;
|
||||||
|
GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction(
|
||||||
|
SIGPROF, &ignore_sigprof_action, &saved_sigprof_action));
|
||||||
|
# endif // GTEST_OS_LINUX
|
||||||
|
|
||||||
# if GTEST_HAS_CLONE
|
# if GTEST_HAS_CLONE
|
||||||
const bool use_fork = GTEST_FLAG(death_test_use_fork);
|
const bool use_fork = GTEST_FLAG(death_test_use_fork);
|
||||||
|
|
||||||
@ -7180,6 +7309,11 @@ static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
|
|||||||
ExecDeathTestChildMain(&args);
|
ExecDeathTestChildMain(&args);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
# endif // GTEST_OS_QNX
|
||||||
|
# if GTEST_OS_LINUX
|
||||||
|
GTEST_DEATH_TEST_CHECK_SYSCALL_(
|
||||||
|
sigaction(SIGPROF, &saved_sigprof_action, NULL));
|
||||||
|
# endif // GTEST_OS_LINUX
|
||||||
|
|
||||||
GTEST_DEATH_TEST_CHECK_(child_pid != -1);
|
GTEST_DEATH_TEST_CHECK_(child_pid != -1);
|
||||||
return child_pid;
|
return child_pid;
|
||||||
@ -7216,7 +7350,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
|
|||||||
GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag,
|
GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag,
|
||||||
file_, line_, death_test_index, pipe_fd[1]);
|
file_, line_, death_test_index, pipe_fd[1]);
|
||||||
Arguments args;
|
Arguments args;
|
||||||
args.AddArguments(GetArgvs());
|
args.AddArguments(GetArgvsForDeathTestChildProcess());
|
||||||
args.AddArgument(filter_flag.c_str());
|
args.AddArgument(filter_flag.c_str());
|
||||||
args.AddArgument(internal_flag.c_str());
|
args.AddArgument(internal_flag.c_str());
|
||||||
|
|
||||||
@ -7227,7 +7361,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
|
|||||||
// is necessary.
|
// is necessary.
|
||||||
FlushInfoLog();
|
FlushInfoLog();
|
||||||
|
|
||||||
const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]);
|
const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]);
|
||||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
||||||
set_child_pid(child_pid);
|
set_child_pid(child_pid);
|
||||||
set_read_fd(pipe_fd[0]);
|
set_read_fd(pipe_fd[0]);
|
||||||
@ -7862,6 +7996,11 @@ void FilePath::Normalize() {
|
|||||||
# include <mach/vm_map.h>
|
# include <mach/vm_map.h>
|
||||||
#endif // GTEST_OS_MAC
|
#endif // GTEST_OS_MAC
|
||||||
|
|
||||||
|
#if GTEST_OS_QNX
|
||||||
|
# include <devctl.h>
|
||||||
|
# include <sys/procfs.h>
|
||||||
|
#endif // GTEST_OS_QNX
|
||||||
|
|
||||||
|
|
||||||
// Indicates that this translation unit is part of Google Test's
|
// Indicates that this translation unit is part of Google Test's
|
||||||
// implementation. It must come before gtest-internal-inl.h is
|
// implementation. It must come before gtest-internal-inl.h is
|
||||||
@ -7904,6 +8043,26 @@ size_t GetThreadCount() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif GTEST_OS_QNX
|
||||||
|
|
||||||
|
// Returns the number of threads running in the process, or 0 to indicate that
|
||||||
|
// we cannot detect it.
|
||||||
|
size_t GetThreadCount() {
|
||||||
|
const int fd = open("/proc/self/as", O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
procfs_info process_info;
|
||||||
|
const int status =
|
||||||
|
devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL);
|
||||||
|
close(fd);
|
||||||
|
if (status == EOK) {
|
||||||
|
return static_cast<size_t>(process_info.num_threads);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
size_t GetThreadCount() {
|
size_t GetThreadCount() {
|
||||||
@ -8295,7 +8454,6 @@ class CapturedStream {
|
|||||||
public:
|
public:
|
||||||
// The ctor redirects the stream to a temporary file.
|
// The ctor redirects the stream to a temporary file.
|
||||||
CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
|
CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
|
||||||
|
|
||||||
# if GTEST_OS_WINDOWS
|
# if GTEST_OS_WINDOWS
|
||||||
char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT
|
char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT
|
||||||
char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT
|
char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT
|
||||||
@ -8312,10 +8470,15 @@ class CapturedStream {
|
|||||||
<< temp_file_path;
|
<< temp_file_path;
|
||||||
filename_ = temp_file_path;
|
filename_ = temp_file_path;
|
||||||
# else
|
# else
|
||||||
// There's no guarantee that a test has write access to the
|
// There's no guarantee that a test has write access to the current
|
||||||
// current directory, so we create the temporary file in the /tmp
|
// directory, so we create the temporary file in the /tmp directory instead.
|
||||||
// directory instead.
|
// We use /tmp on most systems, and /mnt/sdcard on Android. That's because
|
||||||
|
// Android doesn't have /tmp.
|
||||||
|
# if GTEST_OS_LINUX_ANDROID
|
||||||
|
char name_template[] = "/mnt/sdcard/gtest_captured_stream.XXXXXX";
|
||||||
|
# else
|
||||||
char name_template[] = "/tmp/captured_stream.XXXXXX";
|
char name_template[] = "/tmp/captured_stream.XXXXXX";
|
||||||
|
# endif // GTEST_OS_LINUX_ANDROID
|
||||||
const int captured_fd = mkstemp(name_template);
|
const int captured_fd = mkstemp(name_template);
|
||||||
filename_ = name_template;
|
filename_ = name_template;
|
||||||
# endif // GTEST_OS_WINDOWS
|
# endif // GTEST_OS_WINDOWS
|
||||||
@ -8434,11 +8597,23 @@ String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
|
|||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
// A copy of all command line arguments. Set by InitGoogleTest().
|
// A copy of all command line arguments. Set by InitGoogleTest().
|
||||||
::std::vector<String> g_argvs;
|
::std::vector<testing::internal::string> g_argvs;
|
||||||
|
|
||||||
// Returns the command line as a vector of strings.
|
static const ::std::vector<testing::internal::string>* g_injected_test_argvs =
|
||||||
const ::std::vector<String>& GetArgvs() { return g_argvs; }
|
NULL; // Owned.
|
||||||
|
|
||||||
|
void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
|
||||||
|
if (g_injected_test_argvs != argvs)
|
||||||
|
delete g_injected_test_argvs;
|
||||||
|
g_injected_test_argvs = argvs;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
|
||||||
|
if (g_injected_test_argvs != NULL) {
|
||||||
|
return *g_injected_test_argvs;
|
||||||
|
}
|
||||||
|
return g_argvs;
|
||||||
|
}
|
||||||
#endif // GTEST_HAS_DEATH_TEST
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS_MOBILE
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
@ -8605,14 +8780,6 @@ namespace {
|
|||||||
|
|
||||||
using ::std::ostream;
|
using ::std::ostream;
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS_MOBILE // Windows CE does not define _snprintf_s.
|
|
||||||
# define snprintf _snprintf
|
|
||||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400 // VC 8.0 and later deprecate snprintf and _snprintf.
|
|
||||||
# define snprintf _snprintf_s
|
|
||||||
#elif defined(_MSC_VER) && _MSC_VER
|
|
||||||
# define snprintf _snprintf
|
|
||||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
|
||||||
|
|
||||||
// Prints a segment of bytes in the given object.
|
// Prints a segment of bytes in the given object.
|
||||||
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
||||||
size_t count, ostream* os) {
|
size_t count, ostream* os) {
|
||||||
@ -8627,7 +8794,7 @@ void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
|||||||
else
|
else
|
||||||
*os << '-';
|
*os << '-';
|
||||||
}
|
}
|
||||||
snprintf(text, sizeof(text), "%02X", obj_bytes[j]);
|
GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]);
|
||||||
*os << text;
|
*os << text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8741,9 +8908,9 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
|
|||||||
return kSpecialEscape;
|
return kSpecialEscape;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints a char c as if it's part of a string literal, escaping it when
|
// Prints a wchar_t c as if it's part of a string literal, escaping it when
|
||||||
// necessary; returns how c was formatted.
|
// necessary; returns how c was formatted.
|
||||||
static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
|
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case L'\'':
|
case L'\'':
|
||||||
*os << "'";
|
*os << "'";
|
||||||
@ -8758,8 +8925,9 @@ static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
|
|||||||
|
|
||||||
// Prints a char c as if it's part of a string literal, escaping it when
|
// Prints a char c as if it's part of a string literal, escaping it when
|
||||||
// necessary; returns how c was formatted.
|
// necessary; returns how c was formatted.
|
||||||
static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) {
|
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
|
||||||
return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
|
return PrintAsStringLiteralTo(
|
||||||
|
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints a wide or narrow character c and its code. '\0' is printed
|
// Prints a wide or narrow character c and its code. '\0' is printed
|
||||||
@ -8805,48 +8973,63 @@ void PrintTo(wchar_t wc, ostream* os) {
|
|||||||
PrintCharAndCodeTo<wchar_t>(wc, os);
|
PrintCharAndCodeTo<wchar_t>(wc, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints the given array of characters to the ostream.
|
// Prints the given array of characters to the ostream. CharType must be either
|
||||||
// The array starts at *begin, the length is len, it may include '\0' characters
|
// char or wchar_t.
|
||||||
// and may not be null-terminated.
|
// The array starts at begin, the length is len, it may include '\0' characters
|
||||||
static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
|
// and may not be NUL-terminated.
|
||||||
*os << "\"";
|
template <typename CharType>
|
||||||
|
static void PrintCharsAsStringTo(
|
||||||
|
const CharType* begin, size_t len, ostream* os) {
|
||||||
|
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
|
||||||
|
*os << kQuoteBegin;
|
||||||
bool is_previous_hex = false;
|
bool is_previous_hex = false;
|
||||||
for (size_t index = 0; index < len; ++index) {
|
for (size_t index = 0; index < len; ++index) {
|
||||||
const char cur = begin[index];
|
const CharType cur = begin[index];
|
||||||
if (is_previous_hex && IsXDigit(cur)) {
|
if (is_previous_hex && IsXDigit(cur)) {
|
||||||
// Previous character is of '\x..' form and this character can be
|
// Previous character is of '\x..' form and this character can be
|
||||||
// interpreted as another hexadecimal digit in its number. Break string to
|
// interpreted as another hexadecimal digit in its number. Break string to
|
||||||
// disambiguate.
|
// disambiguate.
|
||||||
*os << "\" \"";
|
*os << "\" " << kQuoteBegin;
|
||||||
}
|
}
|
||||||
is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape;
|
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
|
||||||
}
|
}
|
||||||
*os << "\"";
|
*os << "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
|
||||||
|
// 'begin'. CharType must be either char or wchar_t.
|
||||||
|
template <typename CharType>
|
||||||
|
static void UniversalPrintCharArray(
|
||||||
|
const CharType* begin, size_t len, ostream* os) {
|
||||||
|
// The code
|
||||||
|
// const char kFoo[] = "foo";
|
||||||
|
// generates an array of 4, not 3, elements, with the last one being '\0'.
|
||||||
|
//
|
||||||
|
// Therefore when printing a char array, we don't print the last element if
|
||||||
|
// it's '\0', such that the output matches the string literal as it's
|
||||||
|
// written in the source code.
|
||||||
|
if (len > 0 && begin[len - 1] == '\0') {
|
||||||
|
PrintCharsAsStringTo(begin, len - 1, os);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If, however, the last element in the array is not '\0', e.g.
|
||||||
|
// const char kFoo[] = { 'f', 'o', 'o' };
|
||||||
|
// we must print the entire array. We also print a message to indicate
|
||||||
|
// that the array is not NUL-terminated.
|
||||||
|
PrintCharsAsStringTo(begin, len, os);
|
||||||
|
*os << " (no terminating NUL)";
|
||||||
|
}
|
||||||
|
|
||||||
// Prints a (const) char array of 'len' elements, starting at address 'begin'.
|
// Prints a (const) char array of 'len' elements, starting at address 'begin'.
|
||||||
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
|
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
|
||||||
PrintCharsAsStringTo(begin, len, os);
|
UniversalPrintCharArray(begin, len, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints the given array of wide characters to the ostream.
|
// Prints a (const) wchar_t array of 'len' elements, starting at address
|
||||||
// The array starts at *begin, the length is len, it may include L'\0'
|
// 'begin'.
|
||||||
// characters and may not be null-terminated.
|
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
|
||||||
static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
|
UniversalPrintCharArray(begin, len, os);
|
||||||
ostream* os) {
|
|
||||||
*os << "L\"";
|
|
||||||
bool is_previous_hex = false;
|
|
||||||
for (size_t index = 0; index < len; ++index) {
|
|
||||||
const wchar_t cur = begin[index];
|
|
||||||
if (is_previous_hex && isascii(cur) && IsXDigit(static_cast<char>(cur))) {
|
|
||||||
// Previous character is of '\x..' form and this character can be
|
|
||||||
// interpreted as another hexadecimal digit in its number. Break string to
|
|
||||||
// disambiguate.
|
|
||||||
*os << "\" L\"";
|
|
||||||
}
|
|
||||||
is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape;
|
|
||||||
}
|
|
||||||
*os << "\"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints the given C string to the ostream.
|
// Prints the given C string to the ostream.
|
||||||
@ -8872,7 +9055,7 @@ void PrintTo(const wchar_t* s, ostream* os) {
|
|||||||
*os << "NULL";
|
*os << "NULL";
|
||||||
} else {
|
} else {
|
||||||
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
||||||
PrintWideCharsAsStringTo(s, wcslen(s), os);
|
PrintCharsAsStringTo(s, wcslen(s), os);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // wchar_t is native
|
#endif // wchar_t is native
|
||||||
@ -8891,13 +9074,13 @@ void PrintStringTo(const ::std::string& s, ostream* os) {
|
|||||||
// Prints a ::wstring object.
|
// Prints a ::wstring object.
|
||||||
#if GTEST_HAS_GLOBAL_WSTRING
|
#if GTEST_HAS_GLOBAL_WSTRING
|
||||||
void PrintWideStringTo(const ::wstring& s, ostream* os) {
|
void PrintWideStringTo(const ::wstring& s, ostream* os) {
|
||||||
PrintWideCharsAsStringTo(s.data(), s.size(), os);
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||||
|
|
||||||
#if GTEST_HAS_STD_WSTRING
|
#if GTEST_HAS_STD_WSTRING
|
||||||
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
|
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
|
||||||
PrintWideCharsAsStringTo(s.data(), s.size(), os);
|
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_STD_WSTRING
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user