Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
00038 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
00039
00040 #include "gtest/internal/gtest-internal.h"
00041
00042 #include <stdio.h>
00043
00044 namespace testing {
00045 namespace internal {
00046
00047 GTEST_DECLARE_string_(internal_run_death_test);
00048
00049
00050 const char kDeathTestStyleFlag[] = "death_test_style";
00051 const char kDeathTestUseFork[] = "death_test_use_fork";
00052 const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
00053
00054 #if GTEST_HAS_DEATH_TEST
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 class GTEST_API_ DeathTest {
00070 public:
00071
00072
00073
00074
00075
00076
00077
00078
00079 static bool Create(const char* statement, const RE* regex,
00080 const char* file, int line, DeathTest** test);
00081 DeathTest();
00082 virtual ~DeathTest() { }
00083
00084
00085 class ReturnSentinel {
00086 public:
00087 explicit ReturnSentinel(DeathTest* test) : test_(test) { }
00088 ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
00089 private:
00090 DeathTest* const test_;
00091 GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
00092 } GTEST_ATTRIBUTE_UNUSED_;
00093
00094
00095
00096
00097
00098
00099 enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
00100
00101
00102 enum AbortReason {
00103 TEST_ENCOUNTERED_RETURN_STATEMENT,
00104 TEST_THREW_EXCEPTION,
00105 TEST_DID_NOT_DIE
00106 };
00107
00108
00109 virtual TestRole AssumeRole() = 0;
00110
00111
00112 virtual int Wait() = 0;
00113
00114
00115
00116
00117
00118
00119
00120
00121 virtual bool Passed(bool exit_status_ok) = 0;
00122
00123
00124 virtual void Abort(AbortReason reason) = 0;
00125
00126
00127
00128 static const char* LastMessage();
00129
00130 static void set_last_death_test_message(const std::string& message);
00131
00132 private:
00133
00134 static std::string last_death_test_message_;
00135
00136 GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
00137 };
00138
00139
00140 class DeathTestFactory {
00141 public:
00142 virtual ~DeathTestFactory() { }
00143 virtual bool Create(const char* statement, const RE* regex,
00144 const char* file, int line, DeathTest** test) = 0;
00145 };
00146
00147
00148 class DefaultDeathTestFactory : public DeathTestFactory {
00149 public:
00150 virtual bool Create(const char* statement, const RE* regex,
00151 const char* file, int line, DeathTest** test);
00152 };
00153
00154
00155
00156 GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
00157
00158
00159
00160 # if GTEST_HAS_EXCEPTIONS
00161 # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
00162 try { \
00163 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
00164 } catch (const ::std::exception& gtest_exception) { \
00165 fprintf(\
00166 stderr, \
00167 "\n%s: Caught std::exception-derived exception escaping the " \
00168 "death test statement. Exception message: %s\n", \
00169 ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
00170 gtest_exception.what()); \
00171 fflush(stderr); \
00172 death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
00173 } catch (...) { \
00174 death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
00175 }
00176
00177 # else
00178 # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
00179 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
00180
00181 # endif
00182
00183
00184
00185 # define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
00186 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
00187 if (::testing::internal::AlwaysTrue()) { \
00188 const ::testing::internal::RE& gtest_regex = (regex); \
00189 ::testing::internal::DeathTest* gtest_dt; \
00190 if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \
00191 __FILE__, __LINE__, >est_dt)) { \
00192 goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
00193 } \
00194 if (gtest_dt != NULL) { \
00195 ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
00196 gtest_dt_ptr(gtest_dt); \
00197 switch (gtest_dt->AssumeRole()) { \
00198 case ::testing::internal::DeathTest::OVERSEE_TEST: \
00199 if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
00200 goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
00201 } \
00202 break; \
00203 case ::testing::internal::DeathTest::EXECUTE_TEST: { \
00204 ::testing::internal::DeathTest::ReturnSentinel \
00205 gtest_sentinel(gtest_dt); \
00206 GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
00207 gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
00208 break; \
00209 } \
00210 default: \
00211 break; \
00212 } \
00213 } \
00214 } else \
00215 GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
00216 fail(::testing::internal::DeathTest::LastMessage())
00217
00218
00219
00220
00221
00222
00223
00224 # define GTEST_EXECUTE_STATEMENT_(statement, regex) \
00225 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
00226 if (::testing::internal::AlwaysTrue()) { \
00227 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
00228 } else \
00229 ::testing::Message()
00230
00231
00232
00233
00234 class InternalRunDeathTestFlag {
00235 public:
00236 InternalRunDeathTestFlag(const std::string& a_file,
00237 int a_line,
00238 int an_index,
00239 int a_write_fd)
00240 : file_(a_file), line_(a_line), index_(an_index),
00241 write_fd_(a_write_fd) {}
00242
00243 ~InternalRunDeathTestFlag() {
00244 if (write_fd_ >= 0)
00245 posix::Close(write_fd_);
00246 }
00247
00248 const std::string& file() const { return file_; }
00249 int line() const { return line_; }
00250 int index() const { return index_; }
00251 int write_fd() const { return write_fd_; }
00252
00253 private:
00254 std::string file_;
00255 int line_;
00256 int index_;
00257 int write_fd_;
00258
00259 GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
00260 };
00261
00262
00263
00264
00265 InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
00266
00267 #else // GTEST_HAS_DEATH_TEST
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 # define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
00302 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
00303 if (::testing::internal::AlwaysTrue()) { \
00304 GTEST_LOG_(WARNING) \
00305 << "Death tests are not supported on this platform.\n" \
00306 << "Statement '" #statement "' cannot be verified."; \
00307 } else if (::testing::internal::AlwaysFalse()) { \
00308 ::testing::internal::RE::PartialMatch(".*", (regex)); \
00309 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
00310 terminator; \
00311 } else \
00312 ::testing::Message()
00313
00314 #endif // GTEST_HAS_DEATH_TEST
00315
00316 }
00317 }
00318
00319 #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_