Adds sample4_unittest to scons (by Vlad Losev); adds logic for getting the thread count on Mac (by Vlad Losev); adds HasFailure() and HasNonfatalFailure() (by Zhanyong Wan).

This commit is contained in:
zhanyong.wan 2009-04-07 21:03:22 +00:00
parent 0da92aaf7f
commit c12f63214e
8 changed files with 189 additions and 4 deletions

View File

@ -272,6 +272,13 @@ class Test {
// Returns true iff the current test has a fatal failure.
static bool HasFatalFailure();
// Returns true iff the current test has a non-fatal failure.
static bool HasNonfatalFailure();
// Returns true iff the current test has a (either fatal or
// non-fatal) failure.
static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
// Logs a property for the current test. Only the last value for a given
// key is remembered.
// These are public static so they can be called from utility functions

View File

@ -673,9 +673,9 @@ class ThreadLocal {
T value_;
};
// There's no portable way to detect the number of threads, so we just
// return 0 to indicate that we cannot detect it.
inline size_t GetThreadCount() { return 0; }
// Returns the number of threads running in the process, or 0 to indicate that
// we cannot detect it.
size_t GetThreadCount();
// The above synchronization primitives have dummy implementations.
// Therefore Google Test is not thread-safe.

View File

@ -273,6 +273,8 @@ if env.get('GTEST_BUILD_SAMPLES', False):
GtestSample(env, 'sample2_unittest', gtest_main,
additional_sources=['../samples/sample2.cc'])
GtestSample(env, 'sample3_unittest', gtest_main)
GtestSample(env, 'sample4_unittest', gtest_main,
additional_sources=['../samples/sample4.cc'])
GtestSample(env, 'sample5_unittest', gtest_main,
additional_sources=[sample1_obj])
GtestSample(env, 'sample6_unittest', gtest_main)

View File

@ -548,6 +548,9 @@ class TestResult {
// Returns true iff the test fatally failed.
bool HasFatalFailure() const;
// Returns true iff the test has a non-fatal failure.
bool HasNonfatalFailure() const;
// Returns the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; }
@ -575,6 +578,9 @@ class TestResult {
// Increments the death test count, returning the new count.
int increment_death_test_count() { return ++death_test_count_; }
// Clears the test part results.
void ClearTestPartResults() { test_part_results_.Clear(); }
// Clears the object.
void Clear();
private:
@ -1300,6 +1306,11 @@ inline UnitTestImpl* GetUnitTestImpl() {
return UnitTest::GetInstance()->impl();
}
// Clears all test part results of the current test.
inline void ClearCurrentTestPartResults() {
GetUnitTestImpl()->current_test_result()->ClearTestPartResults();
}
// Internal helper functions for implementing the simple regular
// expression matcher.
bool IsInSet(char ch, const char* str);

View File

@ -42,6 +42,11 @@
#include <unistd.h>
#endif // GTEST_OS_WINDOWS
#if GTEST_OS_MAC
#include <mach/mach_init.h>
#include <mach/task.h>
#endif // GTEST_OS_MAC
#ifdef _WIN32_WCE
#include <windows.h> // For TerminateProcess()
#endif // _WIN32_WCE
@ -69,6 +74,22 @@ const int kStdErrFileno = 2;
const int kStdErrFileno = STDERR_FILENO;
#endif // _MSC_VER
// Returns the number of threads running in the process, or 0 to indicate that
// we cannot detect it.
size_t GetThreadCount() {
#if GTEST_OS_MAC
mach_msg_type_number_t thread_count;
thread_act_port_array_t thread_list;
kern_return_t status = task_threads(mach_task_self(),
&thread_list, &thread_count);
return status == KERN_SUCCESS ? static_cast<size_t>(thread_count) : 0;
#else
// There's no portable way to detect the number of threads, so we just
// return 0 to indicate that we cannot detect it.
return 0;
#endif // GTEST_OS_MAC
}
#if GTEST_USES_POSIX_RE
// Implements RE. Currently only needed for death tests.

View File

@ -1852,7 +1852,7 @@ int TestResult::failed_part_count() const {
}
// Returns true iff the test part fatally failed.
static bool TestPartFatallyFailed(const TestPartResult & result) {
static bool TestPartFatallyFailed(const TestPartResult& result) {
return result.fatally_failed();
}
@ -1861,6 +1861,16 @@ bool TestResult::HasFatalFailure() const {
return test_part_results_.CountIf(TestPartFatallyFailed) > 0;
}
// Returns true iff the test part non-fatally failed.
static bool TestPartNonfatallyFailed(const TestPartResult& result) {
return result.nonfatally_failed();
}
// Returns true iff the test has a non-fatal failure.
bool TestResult::HasNonfatalFailure() const {
return test_part_results_.CountIf(TestPartNonfatallyFailed) > 0;
}
// Gets the number of all test parts. This is the sum of the number
// of successful test parts and the number of failed test parts.
int TestResult::total_part_count() const {
@ -2059,6 +2069,12 @@ bool Test::HasFatalFailure() {
return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();
}
// Returns true iff the current test has a non-fatal failure.
bool Test::HasNonfatalFailure() {
return internal::GetUnitTestImpl()->current_test_result()->
HasNonfatalFailure();
}
// class TestInfo
// Constructs a TestInfo object. It assumes ownership of the test factory

View File

@ -32,6 +32,11 @@
// This file tests the internal cross-platform support utilities.
#include <gtest/internal/gtest-port.h>
#if GTEST_OS_MAC
#include <pthread.h>
#endif // GTEST_OS_MAC
#include <gtest/gtest.h>
#include <gtest/gtest-spi.h>
@ -76,6 +81,44 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) {
GTEST_CHECK_(true) << "Check failed in switch case";
}
#if GTEST_OS_MAC
void* ThreadFunc(void* data) {
pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data);
pthread_mutex_lock(mutex);
pthread_mutex_unlock(mutex);
return NULL;
}
TEST(GetThreadCountTest, ReturnsCorrectValue) {
EXPECT_EQ(1, GetThreadCount());
pthread_mutex_t mutex;
pthread_attr_t attr;
pthread_t thread_id;
// TODO(vladl@google.com): turn mutex into internal::Mutex for automatic
// destruction.
pthread_mutex_init(&mutex, NULL);
pthread_mutex_lock(&mutex);
ASSERT_EQ(0, pthread_attr_init(&attr));
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
ASSERT_EQ(0, pthread_attr_destroy(&attr));
ASSERT_EQ(0, status);
EXPECT_EQ(2, GetThreadCount());
pthread_mutex_unlock(&mutex);
void* dummy;
ASSERT_EQ(0, pthread_join(thread_id, &dummy));
EXPECT_EQ(1, GetThreadCount());
pthread_mutex_destroy(&mutex);
}
#else
TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) {
EXPECT_EQ(0, GetThreadCount());
}
#endif // GTEST_OS_MAC
#if GTEST_HAS_DEATH_TEST
TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) {

View File

@ -131,6 +131,7 @@ using testing::TPRT_SUCCESS;
using testing::UnitTest;
using testing::internal::kTestTypeIdInGoogleTest;
using testing::internal::AppendUserMessage;
using testing::internal::ClearCurrentTestPartResults;
using testing::internal::CodePointToUtf8;
using testing::internal::EqFailure;
using testing::internal::FloatingPoint;
@ -5456,3 +5457,87 @@ TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) {
EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str());
EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str());
}
TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) {
EXPECT_FALSE(HasNonfatalFailure());
}
static void FailFatally() { FAIL(); }
TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsOnlyFatalFailure) {
FailFatally();
const bool has_nonfatal_failure = HasNonfatalFailure();
ClearCurrentTestPartResults();
EXPECT_FALSE(has_nonfatal_failure);
}
TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) {
ADD_FAILURE();
const bool has_nonfatal_failure = HasNonfatalFailure();
ClearCurrentTestPartResults();
EXPECT_TRUE(has_nonfatal_failure);
}
TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) {
FailFatally();
ADD_FAILURE();
const bool has_nonfatal_failure = HasNonfatalFailure();
ClearCurrentTestPartResults();
EXPECT_TRUE(has_nonfatal_failure);
}
// A wrapper for calling HasNonfatalFailure outside of a test body.
static bool HasNonfatalFailureHelper() {
return testing::Test::HasNonfatalFailure();
}
TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody) {
EXPECT_FALSE(HasNonfatalFailureHelper());
}
TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody2) {
ADD_FAILURE();
const bool has_nonfatal_failure = HasNonfatalFailureHelper();
ClearCurrentTestPartResults();
EXPECT_TRUE(has_nonfatal_failure);
}
TEST(HasFailureTest, ReturnsFalseWhenThereIsNoFailure) {
EXPECT_FALSE(HasFailure());
}
TEST(HasFailureTest, ReturnsTrueWhenThereIsFatalFailure) {
FailFatally();
const bool has_failure = HasFailure();
ClearCurrentTestPartResults();
EXPECT_TRUE(has_failure);
}
TEST(HasFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) {
ADD_FAILURE();
const bool has_failure = HasFailure();
ClearCurrentTestPartResults();
EXPECT_TRUE(has_failure);
}
TEST(HasFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) {
FailFatally();
ADD_FAILURE();
const bool has_failure = HasFailure();
ClearCurrentTestPartResults();
EXPECT_TRUE(has_failure);
}
// A wrapper for calling HasFailure outside of a test body.
static bool HasFailureHelper() { return testing::Test::HasFailure(); }
TEST(HasFailureTest, WorksOutsideOfTestBody) {
EXPECT_FALSE(HasFailureHelper());
}
TEST(HasFailureTest, WorksOutsideOfTestBody2) {
ADD_FAILURE();
const bool has_failure = HasFailureHelper();
ClearCurrentTestPartResults();
EXPECT_TRUE(has_failure);
}