Commit 3bef459e by zhanyong.wan

Adds threading support (by Miklos Fazekas, Vlad Losev, and Chandler Carruth);…

Adds threading support (by Miklos Fazekas, Vlad Losev, and Chandler Carruth); adds wide InitGoogleTest to gtest.def (by Vlad Losev); updates the version number (by Zhanyong Wan); updates the release notes for 1.5.0 (by Vlad Losev); removes scons scripts from the distribution (by Zhanyong Wan); adds the cmake build script to the distribution (by Zhanyong Wan); adds fused source files to the distribution (by Vlad Losev and Chandler Carruth).
parent dd280cfa
Changes for 1.5.0:
* New feature: Ability to use test assertions in multi-threaded tests
on platforms implementing pthreads.
* New feature: Predicates used inside EXPECT_TRUE() and friends
can now generate custom failure messages.
* New feature: Google Test can now be compiled as a DLL on Windows.
* New feature: The distribution package now includes fused source files.
* New feature: Prints help when encountering unrecognized Google Test flags.
* Experimental feature: CMake build script (requires CMake 2.6.4+).
* double values streamed to an assertion are printed with enough precision
to differentiate any two different values.
* Google Test now works on Solaris.
* Build and test script improvements.
* Bug fixes and implementation clean-ups.
Potentially breaking changes:
* Stopped supporting VC++ 7.1 with exceptions disabled.
* Dropped support for 'make install'.
Changes for 1.4.0: Changes for 1.4.0:
* New feature: the event listener API * New feature: the event listener API
......
...@@ -30,6 +30,9 @@ include_directories( ...@@ -30,6 +30,9 @@ include_directories(
link_directories( link_directories(
${gtest_BINARY_DIR}/src) ${gtest_BINARY_DIR}/src)
# Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
find_package(Threads)
# Defines the compiler/linker flags used to build gtest. You can # Defines the compiler/linker flags used to build gtest. You can
# tweak these definitions to suit your need. # tweak these definitions to suit your need.
if (MSVC) if (MSVC)
...@@ -39,6 +42,11 @@ if (MSVC) ...@@ -39,6 +42,11 @@ if (MSVC)
set(cxx_default "${cxx_base} -EHsc -D_HAS_EXCEPTIONS=1") set(cxx_default "${cxx_base} -EHsc -D_HAS_EXCEPTIONS=1")
else() else()
set(cxx_base "${CMAKE_CXX_FLAGS}") set(cxx_base "${CMAKE_CXX_FLAGS}")
if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available.
set(cxx_base "${cxx_base} -DGTEST_HAS_PTHREAD=1")
endif()
set(cxx_default "${cxx_base} -fexceptions") set(cxx_default "${cxx_base} -fexceptions")
endif() endif()
...@@ -53,6 +61,9 @@ function(cxx_library name cxx_flags) ...@@ -53,6 +61,9 @@ function(cxx_library name cxx_flags)
set_target_properties(${name} set_target_properties(${name}
PROPERTIES PROPERTIES
COMPILE_FLAGS "${cxx_flags}") COMPILE_FLAGS "${cxx_flags}")
if (CMAKE_USE_PTHREADS_INIT)
target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT})
endif()
endfunction() endfunction()
cxx_library(gtest "${cxx_default}" src/gtest-all.cc) cxx_library(gtest "${cxx_default}" src/gtest-all.cc)
...@@ -150,6 +161,7 @@ endfunction() ...@@ -150,6 +161,7 @@ endfunction()
cxx_test(gtest_unittest gtest_main) cxx_test(gtest_unittest gtest_main)
if (build_all_gtest_tests) if (build_all_gtest_tests)
cxx_test(gtest-death-test_test gtest_main)
cxx_test(gtest_environment_test gtest) cxx_test(gtest_environment_test gtest)
cxx_test(gtest-filepath_test gtest_main) cxx_test(gtest-filepath_test gtest_main)
cxx_test(gtest-linked_ptr_test gtest_main) cxx_test(gtest-linked_ptr_test gtest_main)
...@@ -192,10 +204,6 @@ if (build_all_gtest_tests) ...@@ -192,10 +204,6 @@ if (build_all_gtest_tests)
cxx_library(gtest_main_no_rtti "${cxx_no_rtti}" cxx_library(gtest_main_no_rtti "${cxx_no_rtti}"
src/gtest-all.cc src/gtest_main.cc) src/gtest-all.cc src/gtest_main.cc)
find_package(Threads) # Defines CMAKE_THREAD_LIBS_INIT.
cxx_test_with_flags(gtest-death-test_test "${cxx_default}"
"gtest_main;${CMAKE_THREAD_LIBS_INIT}" test/gtest-death-test_test.cc)
cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}" cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}"
gtest_main_no_rtti test/gtest_unittest.cc) gtest_main_no_rtti test/gtest_unittest.cc)
......
...@@ -11,10 +11,6 @@ EXTRA_DIST = \ ...@@ -11,10 +11,6 @@ EXTRA_DIST = \
include/gtest/internal/gtest-type-util.h.pump \ include/gtest/internal/gtest-type-util.h.pump \
include/gtest/internal/gtest-param-util-generated.h.pump \ include/gtest/internal/gtest-param-util-generated.h.pump \
make/Makefile \ make/Makefile \
run_tests.py \
scons/SConscript \
scons/SConstruct \
scons/SConstruct.common \
scripts/fuse_gtest_files.py \ scripts/fuse_gtest_files.py \
scripts/gen_gtest_pred_impl.py \ scripts/gen_gtest_pred_impl.py \
scripts/generate_gtest_def.py \ scripts/generate_gtest_def.py \
...@@ -28,8 +24,7 @@ EXTRA_DIST += \ ...@@ -28,8 +24,7 @@ EXTRA_DIST += \
src/gtest-internal-inl.h \ src/gtest-internal-inl.h \
src/gtest-port.cc \ src/gtest-port.cc \
src/gtest-test-part.cc \ src/gtest-test-part.cc \
src/gtest-typed-test.cc \ src/gtest-typed-test.cc
src/gtest.def
# Sample files that we don't compile. # Sample files that we don't compile.
EXTRA_DIST += \ EXTRA_DIST += \
...@@ -112,6 +107,10 @@ EXTRA_DIST += \ ...@@ -112,6 +107,10 @@ EXTRA_DIST += \
test/run_tests_util.py \ test/run_tests_util.py \
test/run_tests_util_test.py test/run_tests_util_test.py
# CMake script
EXTRA_DIST += \
CMakeLists.txt
# MSVC project files # MSVC project files
EXTRA_DIST += \ EXTRA_DIST += \
msvc/gtest-md.sln \ msvc/gtest-md.sln \
...@@ -123,7 +122,8 @@ EXTRA_DIST += \ ...@@ -123,7 +122,8 @@ EXTRA_DIST += \
msvc/gtest_prod_test-md.vcproj \ msvc/gtest_prod_test-md.vcproj \
msvc/gtest_prod_test.vcproj \ msvc/gtest_prod_test.vcproj \
msvc/gtest_unittest-md.vcproj \ msvc/gtest_unittest-md.vcproj \
msvc/gtest_unittest.vcproj msvc/gtest_unittest.vcproj \
msvc/gtest.def
# xcode project files # xcode project files
EXTRA_DIST += \ EXTRA_DIST += \
...@@ -173,6 +173,14 @@ EXTRA_DIST += $(m4data_DATA) ...@@ -173,6 +173,14 @@ EXTRA_DIST += $(m4data_DATA)
# directories. # directories.
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include
# Modifies compiler and linker flags for pthreads compatibility.
if HAVE_PTHREADS
AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1
AM_LIBS = @PTHREAD_LIBS@
else
AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0
endif
# Build rules for libraries. # Build rules for libraries.
lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la
...@@ -244,6 +252,38 @@ samples_sample10_unittest_LDADD = lib/libgtest.la ...@@ -244,6 +252,38 @@ samples_sample10_unittest_LDADD = lib/libgtest.la
TESTS += test/gtest_all_test TESTS += test/gtest_all_test
check_PROGRAMS += test/gtest_all_test check_PROGRAMS += test/gtest_all_test
test_gtest_all_test_SOURCES = test/gtest_all_test.cc test_gtest_all_test_SOURCES = test/gtest_all_test.cc
test_gtest_all_test_CXXFLAGS = $(AM_CXXFLAGS) $(PTHREAD_CFLAGS) test_gtest_all_test_LDADD = lib/libgtest_main.la
test_gtest_all_test_LDADD = $(PTHREAD_LIBS) $(PTHREAD_CFLAGS) \
lib/libgtest_main.la # Tests that fused gtest files compile and work.
TESTS += test/gtest_fused_test
check_PROGRAMS += test/gtest_fused_test
test_gtest_fused_test_SOURCES = fused-src/gtest/gtest-all.cc \
fused-src/gtest/gtest_main.cc \
fused-src/gtest/gtest.h \
samples/sample1.cc samples/sample1_unittest.cc
test_gtest_fused_test_CPPFLAGS = -I"$(srcdir)/fused-src"
# Build rules for putting fused Google Test files into the distribution
# package. The user can also create those files by manually running
# scripts/fuse_gtest_files.py.
$(srcdir)/fused-src/gtest/gtest-all.cc: fused-gtest-internal
$(srcdir)/fused-src/gtest/gtest.h: fused-gtest-internal
fused-gtest-internal: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \
$(lib_libgtest_la_SOURCES) \
scripts/fuse_gtest_files.py
mkdir -p "$(srcdir)/fused-src/gtest"
chmod -R u+w "$(srcdir)/fused-src"
rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc"
rm -f "$(srcdir)/fused-src/gtest/gtest.h"
"$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src"
$(srcdir)/fused-src/gtest/gtest_main.cc: src/gtest_main.cc
mkdir -p "$(srcdir)/fused-src/gtest"
chmod -R u+w "$(srcdir)/fused-src"
cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest"
maintainer-clean-local:
chmod -R u+w "$(srcdir)/fused-src"
rm -rf "$(srcdir)/fused-src/gtest"
...@@ -5,7 +5,7 @@ m4_include(m4/acx_pthread.m4) ...@@ -5,7 +5,7 @@ m4_include(m4/acx_pthread.m4)
# "[1.0.1]"). It also asumes that there won't be any closing parenthesis # "[1.0.1]"). It also asumes that there won't be any closing parenthesis
# between "AC_INIT(" and the closing ")" including comments and strings. # between "AC_INIT(" and the closing ")" including comments and strings.
AC_INIT([Google C++ Testing Framework], AC_INIT([Google C++ Testing Framework],
[1.4.0], [1.5.0],
[googletestframework@googlegroups.com], [googletestframework@googlegroups.com],
[gtest]) [gtest])
...@@ -39,8 +39,24 @@ AS_IF([test "$PYTHON" != ":"], ...@@ -39,8 +39,24 @@ AS_IF([test "$PYTHON" != ":"],
[AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])]) [AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])])
AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"]) AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"])
# Check for pthreads. # Configure pthreads.
ACX_PTHREAD AC_ARG_WITH([pthreads],
[AS_HELP_STRING([--with-pthreads],
[use pthreads (default is yes)])],
[with_pthreads=$withval],
[with_pthreads=check])
have_pthreads=no
AS_IF([test "x$with_pthreads" != "xno"],
[ACX_PTHREAD(
[],
[AS_IF([test "x$with_pthreads" != "xcheck"],
[AC_MSG_FAILURE(
[--with-pthreads was specified, but unable to be used])])])
have_pthreads="$acx_pthread_ok"])
AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" == "xyes"])
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_LIBS)
# TODO(chandlerc@google.com) Check for the necessary system headers. # TODO(chandlerc@google.com) Check for the necessary system headers.
......
...@@ -77,7 +77,7 @@ namespace testing { ...@@ -77,7 +77,7 @@ namespace testing {
namespace internal { namespace internal {
// Protects copying of all linked_ptr objects. // Protects copying of all linked_ptr objects.
extern Mutex g_linked_ptr_mutex; GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
// This is used internally by all instances of linked_ptr<>. It needs to be // This is used internally by all instances of linked_ptr<>. It needs to be
// a non-template class because different types of linked_ptr<> can refer to // a non-template class because different types of linked_ptr<> can refer to
......
...@@ -75,6 +75,7 @@ EXPORTS ...@@ -75,6 +75,7 @@ EXPORTS
?HasNonfatalFailure@TestResult@testing@@QBE_NXZ ?HasNonfatalFailure@TestResult@testing@@QBE_NXZ
?Init@RE@internal@testing@@AAEXPBD@Z ?Init@RE@internal@testing@@AAEXPBD@Z
?InitGoogleTest@testing@@YAXPAHPAPAD@Z ?InitGoogleTest@testing@@YAXPAHPAPAD@Z
?InitGoogleTest@testing@@YAXPAHPAPA_W@Z
?IsHRESULTFailure@internal@testing@@YA?AVAssertionResult@2@PBDJ@Z ?IsHRESULTFailure@internal@testing@@YA?AVAssertionResult@2@PBDJ@Z
?IsHRESULTSuccess@internal@testing@@YA?AVAssertionResult@2@PBDJ@Z ?IsHRESULTSuccess@internal@testing@@YA?AVAssertionResult@2@PBDJ@Z
?IsTrue@internal@testing@@YA_N_N@Z ?IsTrue@internal@testing@@YA_N_N@Z
......
...@@ -128,6 +128,10 @@ env_with_exceptions = EnvCreator.Create(env_warning_ok, ...@@ -128,6 +128,10 @@ env_with_exceptions = EnvCreator.Create(env_warning_ok,
EnvCreator.WithExceptions) EnvCreator.WithExceptions)
env_without_rtti = EnvCreator.Create(env_warning_ok, EnvCreator.NoRtti) env_without_rtti = EnvCreator.Create(env_warning_ok, EnvCreator.NoRtti)
env_with_exceptions_and_threads = EnvCreator.Create(env_with_threads,
EnvCreator.WithExceptions)
env_with_exceptions_and_threads['OBJ_SUFFIX'] = '_with_exceptions_and_threads'
############################################################ ############################################################
# Helpers for creating build targets. # Helpers for creating build targets.
...@@ -232,7 +236,11 @@ gtest, gtest_main = GtestStaticLibraries(env) ...@@ -232,7 +236,11 @@ gtest, gtest_main = GtestStaticLibraries(env)
gtest_ex, gtest_main_ex = GtestStaticLibraries(env_with_exceptions) gtest_ex, gtest_main_ex = GtestStaticLibraries(env_with_exceptions)
gtest_no_rtti, gtest_main_no_rtti = GtestStaticLibraries(env_without_rtti) gtest_no_rtti, gtest_main_no_rtti = GtestStaticLibraries(env_without_rtti)
gtest_use_own_tuple, gtest_main_use_own_tuple = GtestStaticLibraries( gtest_use_own_tuple, gtest_main_use_own_tuple = GtestStaticLibraries(
env_use_own_tuple) env_use_own_tuple)
gtest_with_threads, gtest_main_with_threads = GtestStaticLibraries(
env_with_threads)
gtest_ex_with_threads, gtest_main_ex_with_threads = GtestStaticLibraries(
env_with_exceptions_and_threads)
# Install the libraries if needed. # Install the libraries if needed.
if 'LIB_OUTPUT' in env.Dictionary(): if 'LIB_OUTPUT' in env.Dictionary():
...@@ -259,7 +267,6 @@ if BUILD_TESTS: ...@@ -259,7 +267,6 @@ if BUILD_TESTS:
additional_sources=['../test/gtest-param-test2_test.cc']) additional_sources=['../test/gtest-param-test2_test.cc'])
GtestTest(env, 'gtest_color_test_', gtest) GtestTest(env, 'gtest_color_test_', gtest)
GtestTest(env, 'gtest-linked_ptr_test', gtest_main) GtestTest(env, 'gtest-linked_ptr_test', gtest_main)
GtestTest(env, 'gtest-port_test', gtest_main)
GtestTest(env, 'gtest_break_on_failure_unittest_', gtest) GtestTest(env, 'gtest_break_on_failure_unittest_', gtest)
GtestTest(env, 'gtest_filter_unittest_', gtest) GtestTest(env, 'gtest_filter_unittest_', gtest)
GtestTest(env, 'gtest_help_test_', gtest_main) GtestTest(env, 'gtest_help_test_', gtest_main)
...@@ -275,10 +282,12 @@ if BUILD_TESTS: ...@@ -275,10 +282,12 @@ if BUILD_TESTS:
############################################################ ############################################################
# Tests targets using custom environments. # Tests targets using custom environments.
GtestTest(env_warning_ok, 'gtest_unittest', gtest_main) GtestTest(env_warning_ok, 'gtest_unittest', gtest_main)
GtestTest(env_with_exceptions, 'gtest_output_test_', gtest_ex) GtestTest(env_with_exceptions_and_threads, 'gtest_output_test_',
gtest_ex_with_threads)
GtestTest(env_with_exceptions, 'gtest_throw_on_failure_ex_test', gtest_ex) GtestTest(env_with_exceptions, 'gtest_throw_on_failure_ex_test', gtest_ex)
GtestTest(env_with_threads, 'gtest-death-test_test', gtest_main) GtestTest(env_with_threads, 'gtest-death-test_test', gtest_main_with_threads)
GtestTest(env_with_threads, 'gtest_stress_test', gtest) GtestTest(env_with_threads, 'gtest-port_test', gtest_main_with_threads)
GtestTest(env_with_threads, 'gtest_stress_test', gtest_with_threads)
GtestTest(env_less_optimized, 'gtest_env_var_test_', gtest) GtestTest(env_less_optimized, 'gtest_env_var_test_', gtest)
GtestTest(env_less_optimized, 'gtest_uninitialized_test_', gtest) GtestTest(env_less_optimized, 'gtest_uninitialized_test_', gtest)
GtestTest(env_use_own_tuple, 'gtest-tuple_test', gtest_main_use_own_tuple) GtestTest(env_use_own_tuple, 'gtest-tuple_test', gtest_main_use_own_tuple)
......
...@@ -119,6 +119,7 @@ class EnvCreator: ...@@ -119,6 +119,7 @@ class EnvCreator:
# selecting on a platform. # selecting on a platform.
env.Append(CCFLAGS=['-pthread']) env.Append(CCFLAGS=['-pthread'])
env.Append(LINKFLAGS=['-pthread']) env.Append(LINKFLAGS=['-pthread'])
env.Append(CPPDEFINES='GTEST_HAS_PTHREAD=1')
WithThreads = classmethod(WithThreads) WithThreads = classmethod(WithThreads)
def NoRtti(cls, env): def NoRtti(cls, env):
......
...@@ -200,7 +200,9 @@ class SConstructHelper: ...@@ -200,7 +200,9 @@ class SConstructHelper:
'-Wall', '-Wall',
'-Werror', '-Werror',
'-Wshadow', '-Wshadow',
'-DGTEST_HAS_PTHREAD=1'
]) ])
env.Append(LINKFLAGS=['-pthread'])
if optimized: if optimized:
env.Append(CCFLAGS=['-O2'], CPPDEFINES=['NDEBUG', '_NDEBUG']) env.Append(CCFLAGS=['-O2'], CPPDEFINES=['NDEBUG', '_NDEBUG'])
else: else:
......
...@@ -214,7 +214,7 @@ if test "${this_bindir}" = "${this_bindir%${bindir}}"; then ...@@ -214,7 +214,7 @@ if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
# TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
# should work to remove it, and/or remove libtool altogether, replacing it # should work to remove it, and/or remove libtool altogether, replacing it
# with direct references to the library and a link path. # with direct references to the library and a link path.
gtest_libs="${build_dir}/lib/libgtest.la" gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
gtest_ldflags="" gtest_ldflags=""
# We provide hooks to include from either the source or build dir, where the # We provide hooks to include from either the source or build dir, where the
...@@ -222,15 +222,15 @@ if test "${this_bindir}" = "${this_bindir%${bindir}}"; then ...@@ -222,15 +222,15 @@ if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
# build rules for generated headers and have them automatically be preferred # build rules for generated headers and have them automatically be preferred
# over provided versions. # over provided versions.
gtest_cppflags="-I${build_dir}/include -I${src_dir}/include" gtest_cppflags="-I${build_dir}/include -I${src_dir}/include"
gtest_cxxflags="" gtest_cxxflags="@PTHREAD_CFLAGS@"
else else
# We're using an installed gtest, although it may be staged under some # We're using an installed gtest, although it may be staged under some
# prefix. Assume (as our own libraries do) that we can resolve the prefix, # prefix. Assume (as our own libraries do) that we can resolve the prefix,
# and are present in the dynamic link paths. # and are present in the dynamic link paths.
gtest_ldflags="-L${libdir}" gtest_ldflags="-L${libdir}"
gtest_libs="-l${name}" gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
gtest_cppflags="-I${includedir}" gtest_cppflags="-I${includedir}"
gtest_cxxflags="" gtest_cxxflags="@PTHREAD_CFLAGS@"
fi fi
# Do an installation query if requested. # Do an installation query if requested.
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
#include <windows.h> // For DWORD. #include <windows.h> // For DWORD.
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#include <gtest/gtest.h> #include <gtest/gtest.h> // NOLINT
#include <gtest/gtest-spi.h> #include <gtest/gtest-spi.h>
namespace testing { namespace testing {
...@@ -1228,6 +1228,9 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { ...@@ -1228,6 +1228,9 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
// TestResult contains some private methods that should be hidden from // TestResult contains some private methods that should be hidden from
// Google Test user but are required for testing. This class allow our tests // Google Test user but are required for testing. This class allow our tests
// to access them. // to access them.
//
// This class is supplied only for the purpose of testing Google Test's own
// constructs. Do not use it in user tests, either directly or indirectly.
class TestResultAccessor { class TestResultAccessor {
public: public:
static void RecordProperty(TestResult* test_result, static void RecordProperty(TestResult* test_result,
......
...@@ -75,6 +75,94 @@ const int kStdOutFileno = STDOUT_FILENO; ...@@ -75,6 +75,94 @@ const int kStdOutFileno = STDOUT_FILENO;
const int kStdErrFileno = STDERR_FILENO; const int kStdErrFileno = STDERR_FILENO;
#endif // _MSC_VER #endif // _MSC_VER
#if GTEST_HAS_PTHREAD
// ThreadStartSemaphore allows the controller thread to pause execution of
// newly created test threads until signalled. Instances of this class must
// be created and destroyed in the controller thread.
ThreadStartSemaphore::ThreadStartSemaphore() : signalled_(false) {
int err = pthread_mutex_init(&mutex_, NULL);
GTEST_CHECK_(err == 0) << "pthread_mutex_init failed with error " << err;
err = pthread_cond_init(&cond_, NULL);
GTEST_CHECK_(err == 0) << "pthread_cond_init failed with error " << err;
pthread_mutex_lock(&mutex_);
}
ThreadStartSemaphore::~ThreadStartSemaphore() {
// Every ThreadStartSemaphore object must be signalled. It locks
// internal mutex upon creation and Signal unlocks it.
GTEST_CHECK_(signalled_);
int err = pthread_mutex_destroy(&mutex_);
GTEST_CHECK_(err == 0)
<< "pthread_mutex_destroy failed with error " << err;
err = pthread_cond_destroy(&cond_);
GTEST_CHECK_(err == 0)
<< "pthread_cond_destroy failed with error " << err;
}
// Signals to all test threads to start. Must be called from the
// controlling thread.
void ThreadStartSemaphore::Signal() {
signalled_ = true;
int err = pthread_cond_signal(&cond_);
GTEST_CHECK_(err == 0)
<< "pthread_cond_signal failed with error " << err;
err = pthread_mutex_unlock(&mutex_);
GTEST_CHECK_(err == 0)
<< "pthread_mutex_unlock failed with error " << err;
}
// Blocks until the controlling thread signals. Should be called from a
// test thread.
void ThreadStartSemaphore::Wait() {
int err = pthread_mutex_lock(&mutex_);
GTEST_CHECK_(err == 0) << "pthread_mutex_lock failed with error " << err;
while (!signalled_) {
err = pthread_cond_wait(&cond_, &mutex_);
GTEST_CHECK_(err == 0)
<< "pthread_cond_wait failed with error " << err;
}
err = pthread_mutex_unlock(&mutex_);
GTEST_CHECK_(err == 0)
<< "pthread_mutex_unlock failed with error " << err;
}
void MutexBase::Lock() {
const int err = pthread_mutex_lock(&mutex_);
GTEST_CHECK_(err == 0) << "pthread_mutex_lock failed with error " << err;
owner_ = pthread_self();
}
void MutexBase::Unlock() {
// We don't protect writing to owner_ here, as it's the caller's
// responsibility to ensure that the current thread holds the mutex when
// this is called.
owner_ = 0;
const int err = pthread_mutex_unlock(&mutex_);
GTEST_CHECK_(err == 0) << "pthread_mutex_unlock failed with error " << err;
}
// Does nothing if the current thread holds the mutex. Otherwise, crashes
// with high probability.
void MutexBase::AssertHeld() const {
GTEST_CHECK_(owner_ == pthread_self())
<< "Current thread is not holding mutex." << this;
}
Mutex::Mutex() {
owner_ = 0;
const int err = pthread_mutex_init(&mutex_, NULL);
GTEST_CHECK_(err == 0) << "pthread_mutex_init failed with error " << err;
}
Mutex::~Mutex() {
const int err = pthread_mutex_destroy(&mutex_);
GTEST_CHECK_(err == 0) << "pthread_mutex_destroy failed with error " << err;
}
#endif // GTEST_HAS_PTHREAD
#if GTEST_OS_MAC #if GTEST_OS_MAC
// Returns the number of threads running in the process, or 0 to indicate that // Returns the number of threads running in the process, or 0 to indicate that
......
...@@ -342,7 +342,7 @@ void AssertHelper::operator=(const Message& message) const { ...@@ -342,7 +342,7 @@ void AssertHelper::operator=(const Message& message) const {
} }
// Mutex for linked pointers. // Mutex for linked pointers.
Mutex g_linked_ptr_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX); 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;
......
...@@ -410,7 +410,7 @@ void SetPthreadFlag() { ...@@ -410,7 +410,7 @@ void SetPthreadFlag() {
} // namespace } // namespace
#if GTEST_HAS_CLONE #if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
if (!testing::GTEST_FLAG(death_test_use_fork)) { if (!testing::GTEST_FLAG(death_test_use_fork)) {
...@@ -422,7 +422,7 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { ...@@ -422,7 +422,7 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
} }
} }
#endif // GTEST_HAS_CLONE #endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
// Tests that a method of another class can be used in a death test. // Tests that a method of another class can be used in a death test.
TEST_F(TestForDeathTest, MethodOfAnotherClass) { TEST_F(TestForDeathTest, MethodOfAnotherClass) {
......
...@@ -35,11 +35,16 @@ ...@@ -35,11 +35,16 @@
#include <stdio.h> #include <stdio.h>
#if GTEST_HAS_PTHREAD
#include <unistd.h> // For nanosleep().
#endif // GTEST_HAS_PTHREAD
#if GTEST_OS_MAC #if GTEST_OS_MAC
#include <pthread.h>
#include <time.h> #include <time.h>
#endif // GTEST_OS_MAC #endif // GTEST_OS_MAC
#include <utility> // For std::pair and std::make_pair.
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gtest/gtest-spi.h> #include <gtest/gtest-spi.h>
...@@ -52,6 +57,9 @@ ...@@ -52,6 +57,9 @@
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_ #undef GTEST_IMPLEMENTATION_
using std::make_pair;
using std::pair;
namespace testing { namespace testing {
namespace internal { namespace internal {
...@@ -94,7 +102,7 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) { ...@@ -94,7 +102,7 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) {
#if GTEST_OS_MAC #if GTEST_OS_MAC
void* ThreadFunc(void* data) { void* ThreadFunc(void* data) {
pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data); pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data);
pthread_mutex_lock(mutex); pthread_mutex_lock(mutex);
pthread_mutex_unlock(mutex); pthread_mutex_unlock(mutex);
return NULL; return NULL;
...@@ -745,5 +753,216 @@ TEST(CaptureDeathTest, CannotReenterStdoutCapture) { ...@@ -745,5 +753,216 @@ TEST(CaptureDeathTest, CannotReenterStdoutCapture) {
#endif // !GTEST_OS_WINDOWS_MOBILE #endif // !GTEST_OS_WINDOWS_MOBILE
TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) {
ThreadLocal<int> t1;
EXPECT_EQ(0, t1.get());
ThreadLocal<void*> t2;
EXPECT_TRUE(t2.get() == NULL);
}
TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) {
ThreadLocal<int> t1(123);
EXPECT_EQ(123, t1.get());
int i = 0;
ThreadLocal<int*> t2(&i);
EXPECT_EQ(&i, t2.get());
}
class NoCopyConstructor {
public:
NoCopyConstructor() {}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(NoCopyConstructor);
};
TEST(ThreadLocalTest, ValueCopyConstructorIsNotRequiredForDefaultVersion) {
ThreadLocal<NoCopyConstructor> bar;
bar.get();
}
class NoDefaultContructor {
public:
explicit NoDefaultContructor(const char*) {}
NoDefaultContructor(const NoDefaultContructor&) {}
};
TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) {
ThreadLocal<NoDefaultContructor> bar(NoDefaultContructor("foo"));
bar.pointer();
}
TEST(ThreadLocalTest, GetAndPointerReturnSameValue) {
ThreadLocal<String> thread_local;
// This is why EXPECT_TRUE is used here rather than EXPECT_EQ because
// we don't care about a particular value of thread_local.pointer() here;
// we only care about pointer and reference referring to the same lvalue.
EXPECT_EQ(thread_local.pointer(), &(thread_local.get()));
// Verifies the condition still holds after calling set.
thread_local.set("foo");
EXPECT_EQ(thread_local.pointer(), &(thread_local.get()));
}
TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) {
ThreadLocal<String> thread_local;
const ThreadLocal<String>& const_thread_local = thread_local;
EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer());
thread_local.set("foo");
EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer());
}
#if GTEST_IS_THREADSAFE
TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) {
// AssertHeld() is flaky only in the presence of multiple threads accessing
// the lock. In this case, the test is robust.
EXPECT_DEATH_IF_SUPPORTED({
Mutex m;
{ MutexLock lock(&m); }
m.AssertHeld();
},
"Current thread is not holding mutex..+");
}
void SleepMilliseconds(int time) {
usleep(static_cast<useconds_t>(time * 1000.0));
}
class AtomicCounterWithMutex {
public:
explicit AtomicCounterWithMutex(Mutex* mutex) :
value_(0), mutex_(mutex), random_(42) {}
void Increment() {
MutexLock lock(mutex_);
int temp = value_;
{
// Locking a mutex puts up a memory barrier, preventing reads and
// writes to value_ rearranged when observed from other threads.
//
// We cannot use Mutex and MutexLock here or rely on their memory
// barrier functionality as we are testing them here.
pthread_mutex_t memory_barrier_mutex;
int err = pthread_mutex_init(&memory_barrier_mutex, NULL);
GTEST_CHECK_(err == 0) << "pthread_mutex_init failed with error " << err;
err = pthread_mutex_lock(&memory_barrier_mutex);
GTEST_CHECK_(err == 0) << "pthread_mutex_lock failed with error " << err;
SleepMilliseconds(random_.Generate(30));
err = pthread_mutex_unlock(&memory_barrier_mutex);
GTEST_CHECK_(err == 0)
<< "pthread_mutex_unlock failed with error " << err;
}
value_ = temp + 1;
}
int value() const { return value_; }
private:
volatile int value_;
Mutex* const mutex_; // Protects value_.
Random random_;
};
void CountingThreadFunc(pair<AtomicCounterWithMutex*, int> param) {
for (int i = 0; i < param.second; ++i)
param.first->Increment();
}
// Tests that the mutex only lets one thread at a time to lock it.
TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
Mutex mutex;
AtomicCounterWithMutex locked_counter(&mutex);
typedef ThreadWithParam<pair<AtomicCounterWithMutex*, int> > ThreadType;
const int kCycleCount = 20;
const int kThreadCount = 7;
scoped_ptr<ThreadType> counting_threads[kThreadCount];
ThreadStartSemaphore semaphore;
// Creates and runs kThreadCount threads that increment locked_counter
// kCycleCount times each.
for (int i = 0; i < kThreadCount; ++i) {
counting_threads[i].reset(new ThreadType(&CountingThreadFunc,
make_pair(&locked_counter,
kCycleCount),
&semaphore));
}
semaphore.Signal(); // Start the threads.
for (int i = 0; i < kThreadCount; ++i)
counting_threads[i]->Join();
// If the mutex lets more than one thread to increment the counter at a
// time, they are likely to encounter a race condition and have some
// increments overwritten, resulting in the lower then expected counter
// value.
EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value());
}
template <typename T>
void RunFromThread(void (func)(T), T param) {
ThreadWithParam<T> thread(func, param, NULL);
thread.Join();
}
void RetrieveThreadLocalValue(pair<ThreadLocal<String>*, String*> param) {
*param.second = param.first->get();
}
TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) {
ThreadLocal<String> thread_local("foo");
EXPECT_STREQ("foo", thread_local.get().c_str());
thread_local.set("bar");
EXPECT_STREQ("bar", thread_local.get().c_str());
String result;
RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result));
EXPECT_STREQ("foo", result.c_str());
}
class CountedDestructor {
public:
~CountedDestructor() { counter_++; }
static int counter() { return counter_; }
static void set_counter(int value) { counter_ = value; }
private:
static int counter_;
};
int CountedDestructor::counter_ = 0;
template <typename T>
void CallThreadLocalGet(ThreadLocal<T>* threadLocal) {
threadLocal->get();
}
TEST(ThreadLocalTest, DestroysManagedObjectsNoLaterThanSelf) {
CountedDestructor::set_counter(0);
{
ThreadLocal<CountedDestructor> thread_local;
ThreadWithParam<ThreadLocal<CountedDestructor>*> thread(
&CallThreadLocalGet<CountedDestructor>, &thread_local, NULL);
thread.Join();
}
// There should be 2 desctuctor calls as ThreadLocal also contains a member
// T - used as a prototype for copy ctr version.
EXPECT_EQ(2, CountedDestructor::counter());
}
TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) {
ThreadLocal<String> thread_local;
thread_local.set("Foo");
EXPECT_STREQ("Foo", thread_local.get().c_str());
String result;
RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result));
EXPECT_TRUE(result.c_str() == NULL);
}
#endif // GTEST_IS_THREADSAFE
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
...@@ -484,6 +484,11 @@ class MyOtherListener : public EmptyTestEventListener {}; ...@@ -484,6 +484,11 @@ class MyOtherListener : public EmptyTestEventListener {};
int main(int argc, char **argv) { int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
void (*wide_init_google_test)(int*, wchar_t**) = &testing::InitGoogleTest;
// Ensures the linker doesn't throw away reference to wide InitGoogleTest.
GTEST_CHECK_(wide_init_google_test != NULL);
TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
TestEventListener* listener = new MyListener; TestEventListener* listener = new MyListener;
......
...@@ -238,7 +238,9 @@ SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list ...@@ -238,7 +238,9 @@ SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list
SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list
SUPPORTS_STACK_TRACES = False SUPPORTS_STACK_TRACES = False
CAN_GENERATE_GOLDEN_FILE = SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and
SUPPORTS_TYPED_TESTS and
SUPPORTS_THREADS)
class GTestOutputTest(gtest_test_utils.TestCase): class GTestOutputTest(gtest_test_utils.TestCase):
...@@ -314,8 +316,8 @@ that does not support all the required features (death tests""") ...@@ -314,8 +316,8 @@ that does not support all the required features (death tests""")
"""\nand typed tests). Please check that you are using VC++ 8.0 SP1 """\nand typed tests). Please check that you are using VC++ 8.0 SP1
or higher as your compiler.""") or higher as your compiler.""")
else: else:
message += """\nand typed tests). Please generate the golden file message += """\ntyped tests, and threads). Please generate the
using a binary built with those features enabled.""" golden file using a binary built with those features enabled."""
sys.stderr.write(message) sys.stderr.write(message)
sys.exit(1) sys.exit(1)
......
...@@ -7,7 +7,7 @@ Expected: true ...@@ -7,7 +7,7 @@ Expected: true
gtest_output_test_.cc:#: Failure gtest_output_test_.cc:#: Failure
Value of: 3 Value of: 3
Expected: 2 Expected: 2
[==========] Running 56 tests from 23 test cases. [==========] Running 59 tests from 25 test cases.
[----------] Global test environment set-up. [----------] Global test environment set-up.
FooEnvironment::SetUp() called. FooEnvironment::SetUp() called.
BarEnvironment::SetUp() called. BarEnvironment::SetUp() called.
...@@ -506,6 +506,35 @@ Failed ...@@ -506,6 +506,35 @@ Failed
Expected non-fatal failure. Expected non-fatal failure.
[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads
[----------] 2 tests from ExpectFailureWithThreadsTest
[ RUN ] ExpectFailureWithThreadsTest.ExpectFatalFailure
(expecting 2 failures)
gtest_output_test_.cc:#: Failure
Failed
Expected fatal failure.
gtest.cc:#: Failure
Expected: 1 fatal failure
Actual: 0 failures
[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure
[ RUN ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure
(expecting 2 failures)
gtest_output_test_.cc:#: Failure
Failed
Expected non-fatal failure.
gtest.cc:#: Failure
Expected: 1 non-fatal failure
Actual: 0 failures
[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure
[----------] 1 test from ScopedFakeTestPartResultReporterTest
[ RUN ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
(expecting 2 failures)
gtest_output_test_.cc:#: Failure
Failed
Expected fatal failure.
gtest_output_test_.cc:#: Failure
Failed
Expected non-fatal failure.
[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
[----------] Global test environment tear-down [----------] Global test environment tear-down
BarEnvironment::TearDown() called. BarEnvironment::TearDown() called.
gtest_output_test_.cc:#: Failure gtest_output_test_.cc:#: Failure
...@@ -515,9 +544,9 @@ FooEnvironment::TearDown() called. ...@@ -515,9 +544,9 @@ FooEnvironment::TearDown() called.
gtest_output_test_.cc:#: Failure gtest_output_test_.cc:#: Failure
Failed Failed
Expected fatal failure. Expected fatal failure.
[==========] 56 tests from 23 test cases ran. [==========] 59 tests from 25 test cases ran.
[ PASSED ] 21 tests. [ PASSED ] 21 tests.
[ FAILED ] 35 tests, listed below: [ FAILED ] 38 tests, listed below:
[ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInSubroutine
[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine
[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine
...@@ -553,8 +582,11 @@ Expected fatal failure. ...@@ -553,8 +582,11 @@ Expected fatal failure.
[ FAILED ] ExpectFailureTest.ExpectNonFatalFailure [ FAILED ] ExpectFailureTest.ExpectNonFatalFailure
[ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads [ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads
[ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads
[ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure
[ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure
[ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
35 FAILED TESTS 38 FAILED TESTS
 YOU HAVE 1 DISABLED TEST  YOU HAVE 1 DISABLED TEST
Note: Google Test filter = FatalFailureTest.*:LoggingTest.* Note: Google Test filter = FatalFailureTest.*:LoggingTest.*
......
...@@ -48,23 +48,17 @@ ...@@ -48,23 +48,17 @@
namespace testing { namespace testing {
namespace { namespace {
using internal::scoped_ptr;
using internal::String; using internal::String;
using internal::TestPropertyKeyIs; using internal::TestPropertyKeyIs;
using internal::Vector; using internal::Vector;
using internal::ThreadStartSemaphore;
using internal::ThreadWithParam;
// In order to run tests in this file, for platforms where Google Test is // In order to run tests in this file, for platforms where Google Test is
// thread safe, implement ThreadWithParam with the following interface: // thread safe, implement ThreadWithParam and ThreadStartSemaphore. See the
// // description of their API in gtest-port.h, where they are defined for
// template <typename T> class ThreadWithParam { // already supported platforms.
// public:
// // Creates the thread. The thread should execute thread_func(param) when
// // started by a call to Start().
// ThreadWithParam(void (*thread_func)(T), T param);
// // Starts the thread.
// void Start();
// // Waits for the thread to finish.
// void Join();
// };
// How many threads to create? // How many threads to create?
const int kThreadCount = 50; const int kThreadCount = 50;
...@@ -132,22 +126,17 @@ void CheckTestFailureCount(int expected_failures) { ...@@ -132,22 +126,17 @@ void CheckTestFailureCount(int expected_failures) {
// Tests using SCOPED_TRACE() and Google Test assertions in many threads // Tests using SCOPED_TRACE() and Google Test assertions in many threads
// concurrently. // concurrently.
TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) {
ThreadWithParam<int>* threads[kThreadCount] = {}; {
for (int i = 0; i != kThreadCount; i++) { scoped_ptr<ThreadWithParam<int> > threads[kThreadCount];
// Creates a thread to run the ManyAsserts() function. ThreadStartSemaphore semaphore;
threads[i] = new ThreadWithParam<int>(&ManyAsserts, i); for (int i = 0; i != kThreadCount; i++)
threads[i].reset(new ThreadWithParam<int>(&ManyAsserts, i, &semaphore));
// Starts the thread.
threads[i]->Start();
}
// At this point, we have many threads running. semaphore.Signal(); // Starts all the threads.
for (int i = 0; i != kThreadCount; i++) { // Blocks until all the threads are done.
// We block until the thread is done. for (int i = 0; i != kThreadCount; i++)
threads[i]->Join(); threads[i]->Join();
delete threads[i];
threads[i] = NULL;
} }
// Ensures that kThreadCount*kThreadCount failures have been reported. // Ensures that kThreadCount*kThreadCount failures have been reported.
...@@ -180,8 +169,7 @@ void FailingThread(bool is_fatal) { ...@@ -180,8 +169,7 @@ void FailingThread(bool is_fatal) {
} }
void GenerateFatalFailureInAnotherThread(bool is_fatal) { void GenerateFatalFailureInAnotherThread(bool is_fatal) {
ThreadWithParam<bool> thread(&FailingThread, is_fatal); ThreadWithParam<bool> thread(&FailingThread, is_fatal, NULL);
thread.Start();
thread.Join(); thread.Join();
} }
......
...@@ -174,7 +174,6 @@ using testing::internal::StreamableToString; ...@@ -174,7 +174,6 @@ using testing::internal::StreamableToString;
using testing::internal::String; using testing::internal::String;
using testing::internal::TestEventListenersAccessor; using testing::internal::TestEventListenersAccessor;
using testing::internal::TestResultAccessor; using testing::internal::TestResultAccessor;
using testing::internal::ThreadLocal;
using testing::internal::UInt32; using testing::internal::UInt32;
using testing::internal::Vector; using testing::internal::Vector;
using testing::internal::WideStringToUtf8; using testing::internal::WideStringToUtf8;
...@@ -6577,23 +6576,6 @@ TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) { ...@@ -6577,23 +6576,6 @@ TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) {
StaticAssertTypeEq<int*, IntAlias*>(); StaticAssertTypeEq<int*, IntAlias*>();
} }
TEST(ThreadLocalTest, DefaultConstructor) {
ThreadLocal<int> t1;
EXPECT_EQ(0, t1.get());
ThreadLocal<void*> t2;
EXPECT_TRUE(t2.get() == NULL);
}
TEST(ThreadLocalTest, Init) {
ThreadLocal<int> t1(123);
EXPECT_EQ(123, t1.get());
int i = 0;
ThreadLocal<int*> t2(&i);
EXPECT_EQ(&i, t2.get());
}
TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) { TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) {
testing::UnitTest* const unit_test = testing::UnitTest::GetInstance(); testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment