aboutsummaryrefslogtreecommitdiff
path: root/googletest/test/googletest-port-test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'googletest/test/googletest-port-test.cc')
-rw-r--r--googletest/test/googletest-port-test.cc237
1 files changed, 131 insertions, 106 deletions
diff --git a/googletest/test/googletest-port-test.cc b/googletest/test/googletest-port-test.cc
index 1e0c8616..8d210260 100644
--- a/googletest/test/googletest-port-test.cc
+++ b/googletest/test/googletest-port-test.cc
@@ -32,17 +32,20 @@
#include "gtest/internal/gtest-port.h"
-#if GTEST_OS_MAC
-# include <time.h>
+#ifdef GTEST_OS_MAC
+#include <time.h>
#endif // GTEST_OS_MAC
+#include <chrono> // NOLINT
#include <list>
#include <memory>
+#include <string>
+#include <thread> // NOLINT
#include <utility> // For std::pair and std::make_pair.
#include <vector>
-#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
+#include "gtest/gtest.h"
#include "src/gtest-internal-inl.h"
using std::make_pair;
@@ -94,7 +97,7 @@ class Base {
explicit Base(int n) : member_(n) {}
Base(const Base&) = default;
Base& operator=(const Base&) = default;
- virtual ~Base() {}
+ virtual ~Base() = default;
int member() { return member_; }
private:
@@ -236,8 +239,8 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) {
}
switch (0)
- case 0:
- GTEST_CHECK_(true) << "Check failed in switch case";
+ case 0:
+ GTEST_CHECK_(true) << "Check failed in switch case";
}
// Verifies behavior of FormatFileLocation.
@@ -278,9 +281,11 @@ TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) {
EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(nullptr, -1));
}
-#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX || GTEST_OS_FUCHSIA || \
- GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
- GTEST_OS_NETBSD || GTEST_OS_OPENBSD
+#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC) || \
+ defined(GTEST_OS_QNX) || defined(GTEST_OS_FUCHSIA) || \
+ defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_FREEBSD) || \
+ defined(GTEST_OS_GNU_KFREEBSD) || defined(GTEST_OS_NETBSD) || \
+ defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_GNU_HURD)
void* ThreadFunc(void* data) {
internal::Mutex* mutex = static_cast<internal::Mutex*>(data);
mutex->Lock();
@@ -289,36 +294,61 @@ void* ThreadFunc(void* data) {
}
TEST(GetThreadCountTest, ReturnsCorrectValue) {
- const size_t starting_count = GetThreadCount();
- pthread_t thread_id;
+ size_t starting_count;
+ size_t thread_count_after_create;
+ size_t thread_count_after_join = 0;
+
+ // We can't guarantee that no other thread was created or destroyed between
+ // any two calls to GetThreadCount(). We make multiple attempts, hoping that
+ // background noise is not constant and we would see the "right" values at
+ // some point.
+ for (int attempt = 0; attempt < 20; ++attempt) {
+ starting_count = GetThreadCount();
+ pthread_t thread_id;
+
+ internal::Mutex mutex;
+ {
+ internal::MutexLock lock(&mutex);
+ pthread_attr_t attr;
+ ASSERT_EQ(0, pthread_attr_init(&attr));
+ ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
- internal::Mutex mutex;
- {
- internal::MutexLock lock(&mutex);
- pthread_attr_t attr;
- 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(starting_count + 1, GetThreadCount());
- }
+ const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
+ ASSERT_EQ(0, pthread_attr_destroy(&attr));
+ ASSERT_EQ(0, status);
- void* dummy;
- ASSERT_EQ(0, pthread_join(thread_id, &dummy));
+ thread_count_after_create = GetThreadCount();
+ }
- // The OS may not immediately report the updated thread count after
- // joining a thread, causing flakiness in this test. To counter that, we
- // wait for up to .5 seconds for the OS to report the correct value.
- for (int i = 0; i < 5; ++i) {
- if (GetThreadCount() == starting_count)
- break;
+ void* dummy;
+ ASSERT_EQ(0, pthread_join(thread_id, &dummy));
+
+ // Join before we decide whether we need to retry the test. Retry if an
+ // arbitrary other thread was created or destroyed in the meantime.
+ if (thread_count_after_create != starting_count + 1) continue;
+
+ // The OS may not immediately report the updated thread count after
+ // joining a thread, causing flakiness in this test. To counter that, we
+ // wait for up to .5 seconds for the OS to report the correct value.
+ bool thread_count_matches = false;
+ for (int i = 0; i < 5; ++i) {
+ thread_count_after_join = GetThreadCount();
+ if (thread_count_after_join == starting_count) {
+ thread_count_matches = true;
+ break;
+ }
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ }
- SleepMilliseconds(100);
+ // Retry if an arbitrary other thread was created or destroyed.
+ if (!thread_count_matches) continue;
+
+ break;
}
- EXPECT_EQ(starting_count, GetThreadCount());
+ EXPECT_EQ(thread_count_after_create, starting_count + 1);
+ EXPECT_EQ(thread_count_after_join, starting_count);
}
#else
TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) {
@@ -330,25 +360,27 @@ TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) {
const bool a_false_condition = false;
const char regex[] =
#ifdef _MSC_VER
- "googletest-port-test\\.cc\\(\\d+\\):"
-#elif GTEST_USES_POSIX_RE
- "googletest-port-test\\.cc:[0-9]+"
+ "googletest-port-test\\.cc\\(\\d+\\):"
+#elif defined(GTEST_USES_POSIX_RE)
+ "googletest-port-test\\.cc:[0-9]+"
#else
- "googletest-port-test\\.cc:\\d+"
+ "googletest-port-test\\.cc:\\d+"
#endif // _MSC_VER
- ".*a_false_condition.*Extra info.*";
+ ".*a_false_condition.*Extra info.*";
EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info",
regex);
}
-#if GTEST_HAS_DEATH_TEST
+#ifdef GTEST_HAS_DEATH_TEST
TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) {
- EXPECT_EXIT({
- GTEST_CHECK_(true) << "Extra info";
- ::std::cerr << "Success\n";
- exit(0); },
+ EXPECT_EXIT(
+ {
+ GTEST_CHECK_(true) << "Extra info";
+ ::std::cerr << "Success\n";
+ exit(0);
+ },
::testing::ExitedWithCode(0), "Success");
}
@@ -358,20 +390,16 @@ TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) {
// the platform. The test will produce compiler errors in case of failure.
// For simplicity, we only cover the most important platforms here.
TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) {
-#if !GTEST_USES_PCRE
-# if GTEST_HAS_POSIX_RE
-
+#ifdef GTEST_HAS_ABSL
+ EXPECT_TRUE(GTEST_USES_RE2);
+#elif GTEST_HAS_POSIX_RE
EXPECT_TRUE(GTEST_USES_POSIX_RE);
-
-# else
-
+#else
EXPECT_TRUE(GTEST_USES_SIMPLE_RE);
-
-# endif
-#endif // !GTEST_USES_PCRE
+#endif
}
-#if GTEST_USES_POSIX_RE
+#ifdef GTEST_USES_POSIX_RE
template <typename Str>
class RETest : public ::testing::Test {};
@@ -390,15 +418,15 @@ TYPED_TEST(RETest, ImplicitConstructorWorks) {
const RE simple(TypeParam("hello"));
EXPECT_STREQ("hello", simple.pattern());
- const RE normal(TypeParam(".*(\\w+)"));
- EXPECT_STREQ(".*(\\w+)", normal.pattern());
+ const RE normal(TypeParam(".*([[:alnum:]_]+)"));
+ EXPECT_STREQ(".*([[:alnum:]_]+)", normal.pattern());
}
// Tests that RE's constructors reject invalid regular expressions.
TYPED_TEST(RETest, RejectsInvalidRegex) {
- EXPECT_NONFATAL_FAILURE({
- const RE invalid(TypeParam("?"));
- }, "\"?\" is not a valid POSIX Extended regular expression.");
+ EXPECT_NONFATAL_FAILURE(
+ { const RE invalid(TypeParam("?")); },
+ "\"?\" is not a valid POSIX Extended regular expression.");
}
// Tests RE::FullMatch().
@@ -428,7 +456,7 @@ TYPED_TEST(RETest, PartialMatchWorks) {
EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re));
}
-#elif GTEST_USES_SIMPLE_RE
+#elif defined(GTEST_USES_SIMPLE_RE)
TEST(IsInSetTest, NulCharIsNotInAnySet) {
EXPECT_FALSE(IsInSet('\0', ""));
@@ -792,8 +820,7 @@ TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) {
EXPECT_TRUE(MatchRegexAtHead("a?b", "ab"));
}
-TEST(MatchRegexAtHeadTest,
- WorksWhenRegexStartsWithRepetionOfEscapeSequence) {
+TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetionOfEscapeSequence) {
EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc"));
EXPECT_FALSE(MatchRegexAtHead("\\s?b", " b"));
@@ -849,17 +876,14 @@ TEST(RETest, ImplicitConstructorWorks) {
// Tests that RE's constructors reject invalid regular expressions.
TEST(RETest, RejectsInvalidRegex) {
- EXPECT_NONFATAL_FAILURE({
- const RE normal(NULL);
- }, "NULL is not a valid simple regular expression");
+ EXPECT_NONFATAL_FAILURE({ const RE normal(NULL); },
+ "NULL is not a valid simple regular expression");
- EXPECT_NONFATAL_FAILURE({
- const RE normal(".*(\\w+");
- }, "'(' is unsupported");
+ EXPECT_NONFATAL_FAILURE({ const RE normal(".*(\\w+"); },
+ "'(' is unsupported");
- EXPECT_NONFATAL_FAILURE({
- const RE invalid("^?");
- }, "'?' can only follow a repeatable token");
+ EXPECT_NONFATAL_FAILURE({ const RE invalid("^?"); },
+ "'?' can only follow a repeatable token");
}
// Tests RE::FullMatch().
@@ -894,7 +918,7 @@ TEST(RETest, PartialMatchWorks) {
#endif // GTEST_USES_POSIX_RE
-#if !GTEST_OS_WINDOWS_MOBILE
+#ifndef GTEST_OS_WINDOWS_MOBILE
TEST(CaptureTest, CapturesStdout) {
CaptureStdout();
@@ -955,14 +979,14 @@ TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) {
EXPECT_EQ(&i, t2.get());
}
-class NoDefaultContructor {
+class NoDefaultConstructor {
public:
- explicit NoDefaultContructor(const char*) {}
- NoDefaultContructor(const NoDefaultContructor&) {}
+ explicit NoDefaultConstructor(const char*) {}
+ NoDefaultConstructor(const NoDefaultConstructor&) = default;
};
TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) {
- ThreadLocal<NoDefaultContructor> bar(NoDefaultContructor("foo"));
+ ThreadLocal<NoDefaultConstructor> bar(NoDefaultConstructor("foo"));
bar.pointer();
}
@@ -987,7 +1011,7 @@ TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) {
EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer());
}
-#if GTEST_IS_THREADSAFE
+#ifdef GTEST_IS_THREADSAFE
void AddTwo(int* param) { *param += 2; }
@@ -1001,12 +1025,13 @@ TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) {
TEST(MutexDeathTest, 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();
- },
- "thread .*hold");
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ Mutex m;
+ { MutexLock lock(&m); }
+ m.AssertHeld();
+ },
+ "thread .*hold");
}
TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
@@ -1017,15 +1042,15 @@ TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
class AtomicCounterWithMutex {
public:
- explicit AtomicCounterWithMutex(Mutex* mutex) :
- value_(0), mutex_(mutex), random_(42) {}
+ explicit AtomicCounterWithMutex(Mutex* mutex)
+ : value_(0), mutex_(mutex), random_(42) {}
void Increment() {
MutexLock lock(mutex_);
int temp = value_;
{
// We need to put up a memory barrier to prevent reads and writes to
- // value_ rearranged with the call to SleepMilliseconds when observed
+ // value_ rearranged with the call to sleep_for when observed
// from other threads.
#if GTEST_HAS_PTHREAD
// On POSIX, locking a mutex puts up a memory barrier. We cannot use
@@ -1036,18 +1061,20 @@ class AtomicCounterWithMutex {
pthread_mutex_init(&memory_barrier_mutex, nullptr));
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex));
- SleepMilliseconds(static_cast<int>(random_.Generate(30)));
+ std::this_thread::sleep_for(
+ std::chrono::milliseconds(random_.Generate(30)));
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex));
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex));
-#elif GTEST_OS_WINDOWS
+#elif defined(GTEST_OS_WINDOWS)
// On Windows, performing an interlocked access puts up a memory barrier.
volatile LONG dummy = 0;
::InterlockedIncrement(&dummy);
- SleepMilliseconds(static_cast<int>(random_.Generate(30)));
+ std::this_thread::sleep_for(
+ std::chrono::milliseconds(random_.Generate(30)));
::InterlockedIncrement(&dummy);
#else
-# error "Memory barrier not implemented on this platform."
+#error "Memory barrier not implemented on this platform."
#endif // GTEST_HAS_PTHREAD
}
value_ = temp + 1;
@@ -1057,12 +1084,11 @@ class AtomicCounterWithMutex {
private:
volatile int value_;
Mutex* const mutex_; // Protects value_.
- Random random_;
+ Random random_;
};
void CountingThreadFunc(pair<AtomicCounterWithMutex*, int> param) {
- for (int i = 0; i < param.second; ++i)
- param.first->Increment();
+ 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.
@@ -1078,14 +1104,12 @@ TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
// 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),
- &threads_can_start));
+ counting_threads[i] = std::make_unique<ThreadType>(
+ &CountingThreadFunc, make_pair(&locked_counter, kCycleCount),
+ &threads_can_start);
}
threads_can_start.Notify();
- for (int i = 0; i < kThreadCount; ++i)
- counting_threads[i]->Join();
+ 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
@@ -1095,7 +1119,7 @@ TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
}
template <typename T>
-void RunFromThread(void (func)(T), T param) {
+void RunFromThread(void(func)(T), T param) {
ThreadWithParam<T> thread(func, param, nullptr);
thread.Join();
}
@@ -1124,14 +1148,14 @@ class DestructorCall {
public:
DestructorCall() {
invoked_ = false;
-#if GTEST_OS_WINDOWS
+#ifdef GTEST_OS_WINDOWS
wait_event_.Reset(::CreateEvent(NULL, TRUE, FALSE, NULL));
GTEST_CHECK_(wait_event_.Get() != NULL);
#endif
}
bool CheckDestroyed() const {
-#if GTEST_OS_WINDOWS
+#ifdef GTEST_OS_WINDOWS
if (::WaitForSingleObject(wait_event_.Get(), 1000) != WAIT_OBJECT_0)
return false;
#endif
@@ -1140,7 +1164,7 @@ class DestructorCall {
void ReportDestroyed() {
invoked_ = true;
-#if GTEST_OS_WINDOWS
+#ifdef GTEST_OS_WINDOWS
::SetEvent(wait_event_.Get());
#endif
}
@@ -1156,12 +1180,13 @@ class DestructorCall {
private:
bool invoked_;
-#if GTEST_OS_WINDOWS
+#ifdef GTEST_OS_WINDOWS
AutoHandle wait_event_;
#endif
static std::vector<DestructorCall*>* const list_;
- GTEST_DISALLOW_COPY_AND_ASSIGN_(DestructorCall);
+ DestructorCall(const DestructorCall&) = delete;
+ DestructorCall& operator=(const DestructorCall&) = delete;
};
std::vector<DestructorCall*>* const DestructorCall::list_ =
@@ -1255,12 +1280,12 @@ TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) {
#endif // GTEST_IS_THREADSAFE
-#if GTEST_OS_WINDOWS
+#ifdef GTEST_OS_WINDOWS
TEST(WindowsTypesTest, HANDLEIsVoidStar) {
StaticAssertTypeEq<HANDLE, void*>();
}
-#if GTEST_OS_WINDOWS_MINGW && !defined(__MINGW64_VERSION_MAJOR)
+#if defined(GTEST_OS_WINDOWS_MINGW) && !defined(__MINGW64_VERSION_MAJOR)
TEST(WindowsTypesTest, _CRITICAL_SECTIONIs_CRITICAL_SECTION) {
StaticAssertTypeEq<CRITICAL_SECTION, _CRITICAL_SECTION>();
}