diff options
author | zhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925> | 2009-03-06 01:20:15 +0000 |
---|---|---|
committer | zhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925> | 2009-03-06 01:20:15 +0000 |
commit | 4984c93490eeeb7d3d1979b30a39a21cad07cba5 (patch) | |
tree | ca3c2306a370dda3388a4cbd34d22331debaec87 /test | |
parent | 0af0709b02899f9177db55eba7929e65e5834b29 (diff) | |
download | googletest-4984c93490eeeb7d3d1979b30a39a21cad07cba5.tar.gz googletest-4984c93490eeeb7d3d1979b30a39a21cad07cba5.tar.bz2 googletest-4984c93490eeeb7d3d1979b30a39a21cad07cba5.zip |
Implements death tests on Windows (by Vlad Losev); enables POSIX regex on Mac and Cygwin; fixes build issue on some Linux versions due to PATH_MAX.
Diffstat (limited to 'test')
-rw-r--r-- | test/gtest-death-test_test.cc | 268 | ||||
-rw-r--r-- | test/gtest-port_test.cc | 38 | ||||
-rw-r--r-- | test/gtest_output_test_.cc | 11 | ||||
-rw-r--r-- | test/gtest_output_test_golden_win.txt | 21 |
4 files changed, 313 insertions, 25 deletions
diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 6d8a3f89..4151ef0e 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -36,8 +36,16 @@ #if GTEST_HAS_DEATH_TEST -#include <stdio.h> +#if GTEST_OS_WINDOWS +#include <direct.h> // For chdir(). +#else #include <unistd.h> +#include <limits> // For std::numeric_limits. +#endif // GTEST_OS_WINDOWS + +#include <limits.h> +#include <signal.h> +#include <stdio.h> #include <gtest/gtest-spi.h> // Indicates that this translation unit is part of Google Test's @@ -49,8 +57,13 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ +using testing::Message; + using testing::internal::DeathTest; using testing::internal::DeathTestFactory; +using testing::internal::GetLastSystemErrorMessage; +using testing::internal::ParseNaturalNumber; +using testing::internal::String; namespace testing { namespace internal { @@ -88,6 +101,7 @@ class TestForDeathTest : public testing::Test { // A static member function that's expected to die. static void StaticMemberFunction() { fprintf(stderr, "%s", "death inside StaticMemberFunction()."); + fflush(stderr); // We call _exit() instead of exit(), as the former is a direct // system call and thus safer in the presence of threads. exit() // will invoke user-defined exit-hooks, which may do dangerous @@ -99,6 +113,7 @@ class TestForDeathTest : public testing::Test { void MemberFunction() { if (should_die_) { fprintf(stderr, "%s", "death inside MemberFunction()."); + fflush(stderr); _exit(1); } } @@ -165,6 +180,21 @@ int DieInDebugElse12(int* sideeffect) { return 12; } +#if GTEST_OS_WINDOWS + +// Tests the ExitedWithCode predicate. +TEST(ExitStatusPredicateTest, ExitedWithCode) { + // On Windows, the process's exit code is the same as its exit status, + // so the predicate just compares the its input with its parameter. + EXPECT_TRUE(testing::ExitedWithCode(0)(0)); + EXPECT_TRUE(testing::ExitedWithCode(1)(1)); + EXPECT_TRUE(testing::ExitedWithCode(42)(42)); + EXPECT_FALSE(testing::ExitedWithCode(0)(1)); + EXPECT_FALSE(testing::ExitedWithCode(1)(0)); +} + +#else + // Returns the exit status of a process that calls _exit(2) with a // given exit code. This is a helper function for the // ExitStatusPredicateTest test suite. @@ -222,6 +252,8 @@ TEST(ExitStatusPredicateTest, KilledBySignal) { EXPECT_FALSE(pred_kill(status_segv)); } +#endif // GTEST_OS_WINDOWS + // Tests that the death test macros expand to code which may or may not // be followed by operator<<, and that in either case the complete text // comprises only a single C++ statement. @@ -248,6 +280,7 @@ TEST_F(TestForDeathTest, SingleStatement) { void DieWithEmbeddedNul() { fprintf(stderr, "Hello%cworld.\n", '\0'); + fflush(stderr); _exit(1); } @@ -263,6 +296,13 @@ TEST_F(TestForDeathTest, DISABLED_EmbeddedNulInMessage) { // Tests that death test macros expand to code which interacts well with switch // statements. TEST_F(TestForDeathTest, SwitchStatement) { +// Microsoft compiler usually complains about switch statements without +// case labels. We suppress that warning for this test. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4065) +#endif // _MSC_VER + switch (0) default: ASSERT_DEATH(_exit(1), "") << "exit in default switch handler"; @@ -270,6 +310,10 @@ TEST_F(TestForDeathTest, SwitchStatement) { switch (0) case 0: EXPECT_DEATH(_exit(1), "") << "exit in switch case"; + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER } // Tests that a static member function can be used in a "fast" style @@ -287,15 +331,23 @@ TEST_F(TestForDeathTest, MemberFunctionFastStyle) { EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); } +void ChangeToRootDir() { +#if GTEST_OS_WINDOWS + _chdir("\\"); +#else + chdir("/"); +#endif // GTEST_OS_WINDOWS +} + // Tests that death tests work even if the current directory has been // changed. TEST_F(TestForDeathTest, FastDeathTestInChangedDir) { testing::GTEST_FLAG(death_test_style) = "fast"; - chdir("/"); + ChangeToRootDir(); EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); - chdir("/"); + ChangeToRootDir(); ASSERT_DEATH(_exit(1), ""); } @@ -322,10 +374,10 @@ TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) { TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; - chdir("/"); + ChangeToRootDir(); EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); - chdir("/"); + ChangeToRootDir(); ASSERT_DEATH(_exit(1), ""); } @@ -346,6 +398,8 @@ void SetPthreadFlag() { } // namespace +#if !GTEST_OS_WINDOWS + TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { if (!testing::GTEST_FLAG(death_test_use_fork)) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; @@ -356,6 +410,8 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { } } +#endif // !GTEST_OS_WINDOWS + // Tests that a method of another class can be used in a death test. TEST_F(TestForDeathTest, MethodOfAnotherClass) { const MayDie x(true); @@ -537,6 +593,30 @@ void ExpectDebugDeathHelper(bool* aborted) { *aborted = false; } +#if GTEST_OS_WINDOWS +TEST(TestForPopUps, DoesNotShowPopUpOnAbort) { + printf("This test should be considered failing if it shows " + "any pop-up dialogs.\n"); + fflush(stdout); + + EXPECT_DEATH({ + testing::GTEST_FLAG(catch_exceptions) = false; + abort(); + }, ""); +} + +TEST(TestForPopUps, DoesNotShowPopUpOnThrow) { + printf("This test should be considered failing if it shows " + "any pop-up dialogs.\n"); + fflush(stdout); + + EXPECT_DEATH({ + testing::GTEST_FLAG(catch_exceptions) = false; + throw 1; + }, ""); +} +#endif // GTEST_OS_WINDOWS + // Tests that EXPECT_DEBUG_DEATH in debug mode does not abort // the function. TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) { @@ -566,18 +646,38 @@ TEST_F(TestForDeathTest, AssertDebugDeathAborts) { static void TestExitMacros() { EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); - EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; - ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; + +#if GTEST_OS_WINDOWS + EXPECT_EXIT({ + testing::GTEST_FLAG(catch_exceptions) = false; + *static_cast<int*>(NULL) = 1; + }, testing::ExitedWithCode(0xC0000005), "") << "foo"; EXPECT_NONFATAL_FAILURE({ // NOLINT - EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") - << "This failure is expected."; + EXPECT_EXIT({ + testing::GTEST_FLAG(catch_exceptions) = false; + *static_cast<int*>(NULL) = 1; + }, testing::ExitedWithCode(0), "") << "This failure is expected."; }, "This failure is expected."); + // Of all signals effects on the process exit code, only those of SIGABRT + // are documented on Windows. + // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. + EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), ""); +#else + EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; + ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; + EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") << "This failure is expected, too."; }, "This failure is expected, too."); +#endif // GTEST_OS_WINDOWS + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") + << "This failure is expected."; + }, "This failure is expected."); } TEST_F(TestForDeathTest, ExitMacros) { @@ -873,6 +973,156 @@ TEST(StreamingAssertionsDeathTest, DeathTest) { }, "expected failure"); } +// Tests that GetLastSystemErrorMessage returns an empty string when the +// last error is 0 and non-empty string when it is non-zero. +TEST(GetLastSystemErrorMessageTest, GetLastSystemErrorMessageWorks) { +#if GTEST_OS_WINDOWS + ::SetLastError(ERROR_FILE_NOT_FOUND); + EXPECT_STRNE("", GetLastSystemErrorMessage().c_str()); + ::SetLastError(0); + EXPECT_STREQ("", GetLastSystemErrorMessage().c_str()); +#else + errno = ENOENT; + EXPECT_STRNE("", GetLastSystemErrorMessage().c_str()); + errno = 0; + EXPECT_STREQ("", GetLastSystemErrorMessage().c_str()); +#endif +} + +#if GTEST_OS_WINDOWS +TEST(AutoHandleTest, AutoHandleWorks) { + HANDLE handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + + // Tests that the AutoHandle is correctly initialized with a handle. + testing::internal::AutoHandle auto_handle(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that Reset assigns INVALID_HANDLE_VALUE. + // Note that this cannot verify whether the original handle is closed. + auto_handle.Reset(); + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle.Get()); + + // Tests that Reset assigns the new handle. + // Note that this cannot verify whether the original handle is closed. + handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, handle); + auto_handle.Reset(handle); + EXPECT_EQ(handle, auto_handle.Get()); + + // Tests that AutoHandle contains INVALID_HANDLE_VALUE by default. + testing::internal::AutoHandle auto_handle2; + EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle2.Get()); +} +#endif // GTEST_OS_WINDOWS + +#if GTEST_OS_WINDOWS +typedef unsigned __int64 BiggestParsable; +typedef signed __int64 BiggestSignedParsable; +const BiggestParsable kBiggestParsableMax = ULLONG_MAX; +const BiggestParsable kBiggestSignedParsableMax = LLONG_MAX; +#else +typedef unsigned long long BiggestParsable; +typedef signed long long BiggestSignedParsable; +const BiggestParsable kBiggestParsableMax = + ::std::numeric_limits<BiggestParsable>::max(); +const BiggestSignedParsable kBiggestSignedParsableMax = + ::std::numeric_limits<BiggestSignedParsable>::max(); +#endif // GTEST_OS_WINDOWS + +TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { + BiggestParsable result = 0; + + // Rejects non-numbers. + EXPECT_FALSE(ParseNaturalNumber(String("non-number string"), &result)); + + // Rejects numbers with whitespace prefix. + EXPECT_FALSE(ParseNaturalNumber(String(" 123"), &result)); + + // Rejects negative numbers. + EXPECT_FALSE(ParseNaturalNumber(String("-123"), &result)); + + // Rejects numbers starting with a plus sign. + EXPECT_FALSE(ParseNaturalNumber(String("+123"), &result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) { + BiggestParsable result = 0; + + EXPECT_FALSE(ParseNaturalNumber(String("99999999999999999999999"), &result)); + + signed char char_result = 0; + EXPECT_FALSE(ParseNaturalNumber(String("200"), &char_result)); + errno = 0; +} + +TEST(ParseNaturalNumberTest, AcceptsValidNumbers) { + BiggestParsable result = 0; + + result = 0; + ASSERT_TRUE(ParseNaturalNumber(String("123"), &result)); + EXPECT_EQ(123, result); + + // Check 0 as an edge case. + result = 1; + ASSERT_TRUE(ParseNaturalNumber(String("0"), &result)); + EXPECT_EQ(0, result); + + result = 1; + ASSERT_TRUE(ParseNaturalNumber(String("00000"), &result)); + EXPECT_EQ(0, result); +} + +TEST(ParseNaturalNumberTest, AcceptsTypeLimits) { + Message msg; + msg << kBiggestParsableMax; + + BiggestParsable result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg.GetString(), &result)); + EXPECT_EQ(kBiggestParsableMax, result); + + Message msg2; + msg2 << kBiggestSignedParsableMax; + + BiggestSignedParsable signed_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg2.GetString(), &signed_result)); + EXPECT_EQ(kBiggestSignedParsableMax, signed_result); + + Message msg3; + msg3 << INT_MAX; + + int int_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg3.GetString(), &int_result)); + EXPECT_EQ(INT_MAX, int_result); + + Message msg4; + msg4 << UINT_MAX; + + unsigned int uint_result = 0; + EXPECT_TRUE(ParseNaturalNumber(msg4.GetString(), &uint_result)); + EXPECT_EQ(UINT_MAX, uint_result); +} + +TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { + short short_result = 0; + ASSERT_TRUE(ParseNaturalNumber(String("123"), &short_result)); + EXPECT_EQ(123, short_result); + + signed char char_result = 0; + ASSERT_TRUE(ParseNaturalNumber(String("123"), &char_result)); + EXPECT_EQ(123, char_result); +} + +#if GTEST_OS_WINDOWS +TEST(EnvironmentTest, HandleFitsIntoSizeT) { + // TODO(vladl@google.com): Remove this test after this condition is verified + // in a static assertion in gtest-death-test.cc in the function + // GetStatusFileDescriptor. + ASSERT_TRUE(sizeof(HANDLE) <= sizeof(size_t)); +} +#endif // GTEST_OS_WINDOWS + #endif // GTEST_HAS_DEATH_TEST // Tests that a test case whose name ends with "DeathTest" works fine diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 40d36bd1..0bda6f5e 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -80,13 +80,15 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) { TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { const bool a_false_condition = false; - EXPECT_DEATH(GTEST_CHECK_(a_false_condition) << "Extra info", + const char regex[] = #ifdef _MSC_VER - "gtest-port_test\\.cc\\([0-9]+\\):" + "gtest-port_test\\.cc\\(\\d+\\):" #else - "gtest-port_test\\.cc:[0-9]+" + "gtest-port_test\\.cc:[0-9]+" #endif // _MSC_VER - ".*a_false_condition.*Extra info.*"); + ".*a_false_condition.*Extra info.*"; + + EXPECT_DEATH(GTEST_CHECK_(a_false_condition) << "Extra info", regex); } TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { @@ -575,25 +577,25 @@ TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) { // Tests RE's implicit constructors. TEST(RETest, ImplicitConstructorWorks) { - const RE empty = ""; + const RE empty(""); EXPECT_STREQ("", empty.pattern()); - const RE simple = "hello"; + const RE simple("hello"); EXPECT_STREQ("hello", simple.pattern()); } // Tests that RE's constructors reject invalid regular expressions. TEST(RETest, RejectsInvalidRegex) { EXPECT_NONFATAL_FAILURE({ - const RE normal = NULL; + const RE normal(NULL); }, "NULL is not a valid simple regular expression"); EXPECT_NONFATAL_FAILURE({ - const RE normal = ".*(\\w+"; + const RE normal(".*(\\w+"); }, "'(' is unsupported"); EXPECT_NONFATAL_FAILURE({ - const RE invalid = "^?"; + const RE invalid("^?"); }, "'?' can only follow a repeatable token"); } @@ -603,10 +605,10 @@ TEST(RETest, FullMatchWorks) { EXPECT_TRUE(RE::FullMatch("", empty)); EXPECT_FALSE(RE::FullMatch("a", empty)); - const RE re1 = "a"; + const RE re1("a"); EXPECT_TRUE(RE::FullMatch("a", re1)); - const RE re = "a.*z"; + const RE re("a.*z"); EXPECT_TRUE(RE::FullMatch("az", re)); EXPECT_TRUE(RE::FullMatch("axyz", re)); EXPECT_FALSE(RE::FullMatch("baz", re)); @@ -615,11 +617,11 @@ TEST(RETest, FullMatchWorks) { // Tests RE::PartialMatch(). TEST(RETest, PartialMatchWorks) { - const RE empty = ""; + const RE empty(""); EXPECT_TRUE(RE::PartialMatch("", empty)); EXPECT_TRUE(RE::PartialMatch("a", empty)); - const RE re = "a.*z"; + const RE re("a.*z"); EXPECT_TRUE(RE::PartialMatch("az", re)); EXPECT_TRUE(RE::PartialMatch("axyz", re)); EXPECT_TRUE(RE::PartialMatch("baz", re)); @@ -629,5 +631,15 @@ TEST(RETest, PartialMatchWorks) { #endif // GTEST_USES_POSIX_RE +#if GTEST_HAS_STD_STRING + +TEST(CaptureStderrTest, CapturesStdErr) { + CaptureStderr(); + fprintf(stderr, "abc"); + ASSERT_EQ("abc", GetCapturedStderr()); +} + +#endif // GTEST_HAS_STD_STRING + } // namespace internal } // namespace testing diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index a8ffa412..90d89b94 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -988,7 +988,18 @@ int main(int argc, char **argv) { if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { // Skip the usual output capturing if we're running as the child // process of an threadsafe-style death test. +#if GTEST_OS_WINDOWS +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) +#endif // _MSC_VER + freopen("nul:", "w", stdout); +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER +#else freopen("/dev/null", "w", stdout); +#endif // GTEST_OS_WINDOWS return RUN_ALL_TESTS(); } #endif // GTEST_HAS_DEATH_TEST diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 77903ba1..d8bb622b 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -5,10 +5,25 @@ gtest_output_test_.cc:#: error: Value of: false Expected: true gtest_output_test_.cc:#: error: Value of: 3 Expected: 2 -[==========] Running 52 tests from 21 test cases. +[==========] Running 57 tests from 26 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. +[----------] 1 test from ADeathTest +[ RUN ] ADeathTest.ShouldRunFirst +[ OK ] ADeathTest.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/0, where TypeParam = int +[ RUN ] ATypedDeathTest/0.ShouldRunFirst +[ OK ] ATypedDeathTest/0.ShouldRunFirst +[----------] 1 test from ATypedDeathTest/1, where TypeParam = double +[ RUN ] ATypedDeathTest/1.ShouldRunFirst +[ OK ] ATypedDeathTest/1.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int +[ RUN ] My/ATypeParamDeathTest/0.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/0.ShouldRunFirst +[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double +[ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst +[ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst [----------] 2 tests from PassingTest [ RUN ] PassingTest.PassingTest1 [ OK ] PassingTest.PassingTest1 @@ -445,8 +460,8 @@ Expected non-fatal failure. FooEnvironment::TearDown() called. gtest_output_test_.cc:#: error: Failed Expected fatal failure. -[==========] 52 tests from 21 test cases ran. -[ PASSED ] 16 tests. +[==========] 57 tests from 26 test cases ran. +[ PASSED ] 21 tests. [ FAILED ] 36 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine |