diff --git a/BUILD.gn b/BUILD.gn index 5e9f832216..f81ad5f509 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -123,6 +123,10 @@ config("common_inherited_config") { defines += [ "WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS" ] } + if (rtc_disable_check_msg) { + defines += [ "RTC_DISABLE_CHECK_MSG" ] + } + # Some tests need to declare their own trace event handlers. If this define is # not set, the first time TRACE_EVENT_* is called it will store the return # value for the current handler in an static variable, so that subsequent diff --git a/common_audio/BUILD.gn b/common_audio/BUILD.gn index 7c5d8b0ced..7170000740 100644 --- a/common_audio/BUILD.gn +++ b/common_audio/BUILD.gn @@ -366,6 +366,7 @@ if (rtc_include_tests) { "../rtc_base/system:arch", "../system_wrappers:cpu_features_api", "../test:fileutils", + "../test:rtc_expect_death", "../test:test_main", "../test:test_support", "//testing/gtest", diff --git a/common_audio/channel_buffer_unittest.cc b/common_audio/channel_buffer_unittest.cc index 7d45e7cde9..8ec42346d1 100644 --- a/common_audio/channel_buffer_unittest.cc +++ b/common_audio/channel_buffer_unittest.cc @@ -11,6 +11,7 @@ #include "common_audio/channel_buffer.h" #include "test/gtest.h" +#include "test/testsupport/rtc_expect_death.h" namespace webrtc { @@ -54,12 +55,12 @@ TEST(IFChannelBufferTest, SettingNumChannelsOfOneChannelBufferSetsTheOther) { #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) TEST(ChannelBufferTest, SetNumChannelsDeathTest) { ChannelBuffer chb(kNumFrames, kMono); - EXPECT_DEATH(chb.set_num_channels(kStereo), "num_channels"); + RTC_EXPECT_DEATH(chb.set_num_channels(kStereo), "num_channels"); } TEST(IFChannelBufferTest, SetNumChannelsDeathTest) { IFChannelBuffer ifchb(kNumFrames, kMono); - EXPECT_DEATH(ifchb.ibuf()->set_num_channels(kStereo), "num_channels"); + RTC_EXPECT_DEATH(ifchb.ibuf()->set_num_channels(kStereo), "num_channels"); } #endif diff --git a/common_audio/resampler/push_resampler_unittest.cc b/common_audio/resampler/push_resampler_unittest.cc index 8b0d5485b6..61b9725b3a 100644 --- a/common_audio/resampler/push_resampler_unittest.cc +++ b/common_audio/resampler/push_resampler_unittest.cc @@ -12,6 +12,7 @@ #include "rtc_base/checks.h" // RTC_DCHECK_IS_ON #include "test/gtest.h" +#include "test/testsupport/rtc_expect_death.h" // Quality testing of PushResampler is handled through output_mixer_unittest.cc. @@ -32,19 +33,20 @@ TEST(PushResamplerTest, VerifiesInputParameters) { #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) TEST(PushResamplerTest, VerifiesBadInputParameters1) { PushResampler resampler; - EXPECT_DEATH(resampler.InitializeIfNeeded(-1, 16000, 1), - "src_sample_rate_hz"); + RTC_EXPECT_DEATH(resampler.InitializeIfNeeded(-1, 16000, 1), + "src_sample_rate_hz"); } TEST(PushResamplerTest, VerifiesBadInputParameters2) { PushResampler resampler; - EXPECT_DEATH(resampler.InitializeIfNeeded(16000, -1, 1), - "dst_sample_rate_hz"); + RTC_EXPECT_DEATH(resampler.InitializeIfNeeded(16000, -1, 1), + "dst_sample_rate_hz"); } TEST(PushResamplerTest, VerifiesBadInputParameters3) { PushResampler resampler; - EXPECT_DEATH(resampler.InitializeIfNeeded(16000, 16000, 0), "num_channels"); + RTC_EXPECT_DEATH(resampler.InitializeIfNeeded(16000, 16000, 0), + "num_channels"); } #endif diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn index deb685f8a6..4b9d20b179 100644 --- a/modules/audio_coding/BUILD.gn +++ b/modules/audio_coding/BUILD.gn @@ -2123,6 +2123,7 @@ if (rtc_include_tests) { "../../test:audio_codec_mocks", "../../test:field_trial", "../../test:fileutils", + "../../test:rtc_expect_death", "../../test:rtp_test_utils", "../../test:test_common", "../../test:test_support", diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc index ab84c781e8..9dca4cdfc1 100644 --- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc +++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc @@ -54,6 +54,7 @@ #include "test/mock_audio_decoder.h" #include "test/mock_audio_encoder.h" #include "test/testsupport/file_utils.h" +#include "test/testsupport/rtc_expect_death.h" using ::testing::_; using ::testing::AtLeast; @@ -272,8 +273,8 @@ TEST_F(AudioCodingModuleTestOldApi, VerifyOutputFrame) { TEST_F(AudioCodingModuleTestOldApi, FailOnZeroDesiredFrequency) { AudioFrame audio_frame; bool muted; - EXPECT_DEATH(acm_->PlayoutData10Ms(0, &audio_frame, &muted), - "dst_sample_rate_hz"); + RTC_EXPECT_DEATH(acm_->PlayoutData10Ms(0, &audio_frame, &muted), + "dst_sample_rate_hz"); } #endif diff --git a/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc b/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc index 6dda86277f..085deb1609 100644 --- a/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc +++ b/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc @@ -18,6 +18,7 @@ #include "rtc_base/numerics/safe_conversions.h" #include "test/gtest.h" #include "test/mock_audio_encoder.h" +#include "test/testsupport/rtc_expect_death.h" using ::testing::_; using ::testing::InSequence; @@ -441,7 +442,7 @@ class AudioEncoderCngDeathTest : public AudioEncoderCngTest { } void TryWrongNumCoefficients(int num) { - EXPECT_DEATH( + RTC_EXPECT_DEATH( [&] { auto config = MakeCngConfig(); config.num_cng_coefficients = num; @@ -454,9 +455,9 @@ class AudioEncoderCngDeathTest : public AudioEncoderCngTest { TEST_F(AudioEncoderCngDeathTest, WrongFrameSize) { CreateCng(MakeCngConfig()); num_audio_samples_10ms_ *= 2; // 20 ms frame. - EXPECT_DEATH(Encode(), ""); + RTC_EXPECT_DEATH(Encode(), ""); num_audio_samples_10ms_ = 0; // Zero samples. - EXPECT_DEATH(Encode(), ""); + RTC_EXPECT_DEATH(Encode(), ""); } TEST_F(AudioEncoderCngDeathTest, WrongNumCoefficientsA) { @@ -474,16 +475,16 @@ TEST_F(AudioEncoderCngDeathTest, WrongNumCoefficientsC) { TEST_F(AudioEncoderCngDeathTest, NullSpeechEncoder) { auto config = MakeCngConfig(); config.speech_encoder = nullptr; - EXPECT_DEATH(CreateCng(std::move(config)), ""); + RTC_EXPECT_DEATH(CreateCng(std::move(config)), ""); } TEST_F(AudioEncoderCngDeathTest, StereoEncoder) { EXPECT_CALL(*mock_encoder_, NumChannels()).WillRepeatedly(Return(2)); - EXPECT_DEATH(CreateCng(MakeCngConfig()), "Invalid configuration"); + RTC_EXPECT_DEATH(CreateCng(MakeCngConfig()), "Invalid configuration"); } TEST_F(AudioEncoderCngDeathTest, StereoConfig) { - EXPECT_DEATH( + RTC_EXPECT_DEATH( [&] { auto config = MakeCngConfig(); config.num_channels = 2; @@ -498,8 +499,8 @@ TEST_F(AudioEncoderCngDeathTest, EncoderFrameSizeTooLarge) { .WillRepeatedly(Return(7U)); for (int i = 0; i < 6; ++i) Encode(); - EXPECT_DEATH(Encode(), - "Frame size cannot be larger than 60 ms when using VAD/CNG."); + RTC_EXPECT_DEATH( + Encode(), "Frame size cannot be larger than 60 ms when using VAD/CNG."); } #endif // GTEST_HAS_DEATH_TEST diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc b/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc index 22e9a7f500..648a88d021 100644 --- a/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc +++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc @@ -17,6 +17,7 @@ #include "rtc_base/numerics/safe_conversions.h" #include "test/gtest.h" #include "test/mock_audio_encoder.h" +#include "test/testsupport/rtc_expect_death.h" using ::testing::_; using ::testing::InSequence; @@ -285,17 +286,17 @@ class AudioEncoderCopyRedDeathTest : public AudioEncoderCopyRedTest { TEST_F(AudioEncoderCopyRedDeathTest, WrongFrameSize) { num_audio_samples_10ms *= 2; // 20 ms frame. - EXPECT_DEATH(Encode(), ""); + RTC_EXPECT_DEATH(Encode(), ""); num_audio_samples_10ms = 0; // Zero samples. - EXPECT_DEATH(Encode(), ""); + RTC_EXPECT_DEATH(Encode(), ""); } TEST_F(AudioEncoderCopyRedDeathTest, NullSpeechEncoder) { AudioEncoderCopyRed* red = NULL; AudioEncoderCopyRed::Config config; config.speech_encoder = NULL; - EXPECT_DEATH(red = new AudioEncoderCopyRed(std::move(config)), - "Speech encoder not provided."); + RTC_EXPECT_DEATH(red = new AudioEncoderCopyRed(std::move(config)), + "Speech encoder not provided."); // The delete operation is needed to avoid leak reports from memcheck. delete red; } diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn index 9e6ee75451..a0f6124eb0 100644 --- a/modules/audio_processing/BUILD.gn +++ b/modules/audio_processing/BUILD.gn @@ -448,6 +448,7 @@ if (rtc_include_tests) { "../../system_wrappers", "../../system_wrappers:cpu_features_api", "../../test:fileutils", + "../../test:rtc_expect_death", "../../test:test_support", "../audio_coding:neteq_input_audio_tools", "aec:aec_core", diff --git a/modules/audio_processing/audio_buffer_unittest.cc b/modules/audio_processing/audio_buffer_unittest.cc index 402e5c4065..7cb51ca5f1 100644 --- a/modules/audio_processing/audio_buffer_unittest.cc +++ b/modules/audio_processing/audio_buffer_unittest.cc @@ -11,7 +11,9 @@ #include "modules/audio_processing/audio_buffer.h" #include + #include "test/gtest.h" +#include "test/testsupport/rtc_expect_death.h" namespace webrtc { @@ -41,7 +43,7 @@ TEST(AudioBufferTest, SetNumChannelsSetsChannelBuffersNumChannels) { TEST(AudioBufferTest, SetNumChannelsDeathTest) { AudioBuffer ab(kSampleRateHz, kMono, kSampleRateHz, kMono, kSampleRateHz, kMono); - EXPECT_DEATH(ab.set_num_channels(kStereo), "num_channels"); + RTC_EXPECT_DEATH(ab.set_num_channels(kStereo), "num_channels"); } #endif diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index d626adde12..41e553c7bc 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -1168,6 +1168,7 @@ if (rtc_include_tests) { "buffer_unittest.cc", "byte_buffer_unittest.cc", "byte_order_unittest.cc", + "checks_unittest.cc", "copy_on_write_buffer_unittest.cc", "critical_section_unittest.cc", "event_tracer_unittest.cc", diff --git a/rtc_base/checks.cc b/rtc_base/checks.cc index 34a1b72e66..e5fc2ed416 100644 --- a/rtc_base/checks.cc +++ b/rtc_base/checks.cc @@ -59,6 +59,7 @@ void AppendFormat(std::string* s, const char* fmt, ...) { namespace rtc { namespace webrtc_checks_impl { +#if RTC_CHECK_MSG_ENABLED // Reads one argument from args, appends it to s and advances fmt. // Returns true iff an argument was sucessfully parsed. bool ParseArg(va_list* args, const CheckArgType** fmt, std::string* s) { @@ -162,6 +163,32 @@ RTC_NORETURN void FatalLog(const char* file, #endif abort(); } +#else // RTC_CHECK_MSG_ENABLED +RTC_NORETURN void FatalLog(const char* file, int line) { + std::string s; + AppendFormat(&s, + "\n\n" + "#\n" + "# Fatal error in: %s, line %d\n" + "# last system error: %u\n" + "# Check failed.\n" + "# ", + file, line, LAST_SYSTEM_ERROR); + const char* output = s.c_str(); + +#if defined(WEBRTC_ANDROID) + __android_log_print(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, "%s\n", output); +#endif + + fflush(stdout); + fprintf(stderr, "%s", output); + fflush(stderr); +#if defined(WEBRTC_WIN) + DebugBreak(); +#endif + abort(); +} +#endif // RTC_CHECK_MSG_ENABLED } // namespace webrtc_checks_impl } // namespace rtc @@ -170,7 +197,11 @@ RTC_NORETURN void FatalLog(const char* file, RTC_NORETURN void rtc_FatalMessage(const char* file, int line, const char* msg) { +#if RTC_CHECK_MSG_ENABLED static constexpr rtc::webrtc_checks_impl::CheckArgType t[] = { rtc::webrtc_checks_impl::CheckArgType::kEnd}; - FatalLog(file, line, msg, t); + rtc::webrtc_checks_impl::FatalLog(file, line, msg, t); +#else + rtc::webrtc_checks_impl::FatalLog(file, line); +#endif } diff --git a/rtc_base/checks.h b/rtc_base/checks.h index 17d32cb19a..8d361cf05d 100644 --- a/rtc_base/checks.h +++ b/rtc_base/checks.h @@ -37,6 +37,18 @@ RTC_NORETURN void rtc_FatalMessage(const char* file, int line, const char* msg); } // extern "C" #endif +#ifdef RTC_DISABLE_CHECK_MSG +#define RTC_CHECK_MSG_ENABLED 0 +#else +#define RTC_CHECK_MSG_ENABLED 1 +#endif + +#if RTC_CHECK_MSG_ENABLED +#define RTC_CHECK_EVAL_MESSAGE(message) message +#else +#define RTC_CHECK_EVAL_MESSAGE(message) "" +#endif + #ifdef __cplusplus // C++ version. @@ -109,11 +121,15 @@ enum class CheckArgType : int8_t { kCheckOp, }; +#if RTC_CHECK_MSG_ENABLED RTC_NORETURN RTC_EXPORT void FatalLog(const char* file, int line, const char* message, const CheckArgType* fmt, ...); +#else +RTC_NORETURN RTC_EXPORT void FatalLog(const char* file, int line); +#endif // Wrapper for log arguments. Only ever make values of this type with the // MakeVal() functions. @@ -214,6 +230,7 @@ class LogStreamer<> final { return LogStreamer(MakeVal(arg), this); } +#if RTC_CHECK_MSG_ENABLED template RTC_NORETURN RTC_FORCE_INLINE static void Call(const char* file, const int line, @@ -232,6 +249,13 @@ class LogStreamer<> final { CheckArgType::kEnd}; FatalLog(file, line, message, t, args.GetVal()...); } +#else + template + RTC_NORETURN RTC_FORCE_INLINE static void Call(const char* file, + const int line) { + FatalLog(file, line); + } +#endif }; // Inductive case: We've already seen at least one << argument. The most recent @@ -258,6 +282,7 @@ class LogStreamer final { return LogStreamer(MakeVal(arg), this); } +#if RTC_CHECK_MSG_ENABLED template RTC_NORETURN RTC_FORCE_INLINE void Call(const char* file, const int line, @@ -273,6 +298,13 @@ class LogStreamer final { const Us&... args) const { prior_->CallCheckOp(file, line, message, arg_, args...); } +#else + template + RTC_NORETURN RTC_FORCE_INLINE void Call(const char* file, + const int line) const { + prior_->Call(file, line); + } +#endif private: // The most recent argument. @@ -292,8 +324,12 @@ class FatalLogCall final { template RTC_NORETURN RTC_FORCE_INLINE void operator&( const LogStreamer& streamer) { +#if RTC_CHECK_MSG_ENABLED isCheckOp ? streamer.CallCheckOp(file_, line_, message_) : streamer.Call(file_, line_, message_); +#else + streamer.Call(file_, line_); +#endif } private: @@ -301,6 +337,7 @@ class FatalLogCall final { int line_; const char* message_; }; + } // namespace webrtc_checks_impl // The actual stream used isn't important. We reference |ignored| in the code @@ -326,19 +363,37 @@ class FatalLogCall final { // // We make sure RTC_CHECK et al. always evaluates |condition|, as // doing RTC_CHECK(FunctionWithSideEffect()) is a common idiom. +// +// RTC_CHECK_OP is a helper macro for binary operators. +// Don't use this macro directly in your code, use RTC_CHECK_EQ et al below. +#if RTC_CHECK_MSG_ENABLED #define RTC_CHECK(condition) \ while (!(condition)) \ rtc::webrtc_checks_impl::FatalLogCall(__FILE__, __LINE__, \ #condition) & \ rtc::webrtc_checks_impl::LogStreamer<>() -// Helper macro for binary operators. -// Don't use this macro directly in your code, use RTC_CHECK_EQ et al below. #define RTC_CHECK_OP(name, op, val1, val2) \ while (!rtc::Safe##name((val1), (val2))) \ rtc::webrtc_checks_impl::FatalLogCall(__FILE__, __LINE__, \ #val1 " " #op " " #val2) & \ rtc::webrtc_checks_impl::LogStreamer<>() << (val1) << (val2) +#else +#define RTC_CHECK(condition) \ + while (!(condition)) \ + true \ + ? rtc::webrtc_checks_impl::FatalLogCall(__FILE__, __LINE__, "") & \ + rtc::webrtc_checks_impl::LogStreamer<>() \ + : rtc::webrtc_checks_impl::FatalLogCall("", 0, "") & \ + rtc::webrtc_checks_impl::LogStreamer<>() + +#define RTC_CHECK_OP(name, op, val1, val2) \ + while (!rtc::Safe##name((val1), (val2))) \ + true ? rtc::webrtc_checks_impl::FatalLogCall(__FILE__, __LINE__, "") & \ + rtc::webrtc_checks_impl::LogStreamer<>() \ + : rtc::webrtc_checks_impl::FatalLogCall("", 0, "") & \ + rtc::webrtc_checks_impl::LogStreamer<>() +#endif #define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(Eq, ==, val1, val2) #define RTC_CHECK_NE(val1, val2) RTC_CHECK_OP(Ne, !=, val1, val2) @@ -391,11 +446,12 @@ inline T CheckedDivExact(T a, T b) { // C version. Lacks many features compared to the C++ version, but usage // guidelines are the same. -#define RTC_CHECK(condition) \ - do { \ - if (!(condition)) { \ - rtc_FatalMessage(__FILE__, __LINE__, "CHECK failed: " #condition); \ - } \ +#define RTC_CHECK(condition) \ + do { \ + if (!(condition)) { \ + rtc_FatalMessage(__FILE__, __LINE__, \ + RTC_CHECK_EVAL_MESSAGE("CHECK failed: " #condition)); \ + } \ } while (0) #define RTC_CHECK_EQ(a, b) RTC_CHECK((a) == (b)) @@ -405,11 +461,12 @@ inline T CheckedDivExact(T a, T b) { #define RTC_CHECK_GE(a, b) RTC_CHECK((a) >= (b)) #define RTC_CHECK_GT(a, b) RTC_CHECK((a) > (b)) -#define RTC_DCHECK(condition) \ - do { \ - if (RTC_DCHECK_IS_ON && !(condition)) { \ - rtc_FatalMessage(__FILE__, __LINE__, "DCHECK failed: " #condition); \ - } \ +#define RTC_DCHECK(condition) \ + do { \ + if (RTC_DCHECK_IS_ON && !(condition)) { \ + rtc_FatalMessage(__FILE__, __LINE__, \ + RTC_CHECK_EVAL_MESSAGE("DCHECK failed: " #condition)); \ + } \ } while (0) #define RTC_DCHECK_EQ(a, b) RTC_DCHECK((a) == (b)) diff --git a/rtc_base/checks_unittest.cc b/rtc_base/checks_unittest.cc new file mode 100644 index 0000000000..e6e094e597 --- /dev/null +++ b/rtc_base/checks_unittest.cc @@ -0,0 +1,73 @@ +/* + * Copyright 2019 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rtc_base/checks.h" + +#include "test/gtest.h" + +TEST(ChecksTest, ExpressionNotEvaluatedWhenCheckPassing) { + int i = 0; + RTC_CHECK(true) << "i=" << ++i; + RTC_CHECK_EQ(i, 0) << "Previous check passed, but i was incremented!"; +} + +#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) +TEST(ChecksTest, Checks) { +#if RTC_CHECK_MSG_ENABLED + EXPECT_DEATH(FATAL() << "message", + "\n\n#\n" + "# Fatal error in: \\S+, line \\w+\n" + "# last system error: \\w+\n" + "# Check failed: FATAL\\(\\)\n" + "# message"); + + int a = 1, b = 2; + EXPECT_DEATH(RTC_CHECK_EQ(a, b) << 1 << 2u, + "\n\n#\n" + "# Fatal error in: \\S+, line \\w+\n" + "# last system error: \\w+\n" + "# Check failed: a == b \\(1 vs. 2\\)\n" + "# 12"); + RTC_CHECK_EQ(5, 5); + + RTC_CHECK(true) << "Shouldn't crash" << 1; + EXPECT_DEATH(RTC_CHECK(false) << "Hi there!", + "\n\n#\n" + "# Fatal error in: \\S+, line \\w+\n" + "# last system error: \\w+\n" + "# Check failed: false\n" + "# Hi there!"); +#else + EXPECT_DEATH(FATAL() << "message", + "\n\n#\n" + "# Fatal error in: \\S+, line \\w+\n" + "# last system error: \\w+\n" + "# Check failed.\n" + "# "); + + int a = 1, b = 2; + EXPECT_DEATH(RTC_CHECK_EQ(a, b) << 1 << 2u, + "\n\n#\n" + "# Fatal error in: \\S+, line \\w+\n" + "# last system error: \\w+\n" + "# Check failed.\n" + "# "); + RTC_CHECK_EQ(5, 5); + + RTC_CHECK(true) << "Shouldn't crash" << 1; + EXPECT_DEATH(RTC_CHECK(false) << "Hi there!", + "\n\n#\n" + "# Fatal error in: \\S+, line \\w+\n" + "# last system error: \\w+\n" + "# Check failed.\n" + "# "); +#endif // RTC_CHECK_MSG_ENABLED +} +#endif // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) diff --git a/rtc_base/logging_unittest.cc b/rtc_base/logging_unittest.cc index f17291fdc5..969ffebcf7 100644 --- a/rtc_base/logging_unittest.cc +++ b/rtc_base/logging_unittest.cc @@ -200,34 +200,6 @@ TEST(LogTest, SingleStream) { EXPECT_EQ(sev, LogMessage::GetLogToStream(nullptr)); } -#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) -TEST(LogTest, Checks) { - EXPECT_DEATH(FATAL() << "message", - "\n\n#\n" - "# Fatal error in: \\S+, line \\w+\n" - "# last system error: \\w+\n" - "# Check failed: FATAL\\(\\)\n" - "# message"); - - int a = 1, b = 2; - EXPECT_DEATH(RTC_CHECK_EQ(a, b) << 1 << 2u, - "\n\n#\n" - "# Fatal error in: \\S+, line \\w+\n" - "# last system error: \\w+\n" - "# Check failed: a == b \\(1 vs. 2\\)\n" - "# 12"); - RTC_CHECK_EQ(5, 5); - - RTC_CHECK(true) << "Shouldn't crash" << 1; - EXPECT_DEATH(RTC_CHECK(false) << "Hi there!", - "\n\n#\n" - "# Fatal error in: \\S+, line \\w+\n" - "# last system error: \\w+\n" - "# Check failed: false\n" - "# Hi there!"); -} -#endif - // Test using multiple log streams. The INFO stream should get the INFO message, // the VERBOSE stream should get the INFO and the VERBOSE. // We should restore the correct global state at the end. diff --git a/system_wrappers/BUILD.gn b/system_wrappers/BUILD.gn index f32cafe6d0..2f30a16395 100644 --- a/system_wrappers/BUILD.gn +++ b/system_wrappers/BUILD.gn @@ -173,6 +173,7 @@ if (rtc_include_tests) { ":system_wrappers", "../rtc_base:checks", "../rtc_base:rtc_base_approved", + "../test:rtc_expect_death", "../test:test_main", "../test:test_support", "//testing/gtest", diff --git a/system_wrappers/source/field_trial_unittest.cc b/system_wrappers/source/field_trial_unittest.cc index f6819486eb..67b841df4c 100644 --- a/system_wrappers/source/field_trial_unittest.cc +++ b/system_wrappers/source/field_trial_unittest.cc @@ -11,6 +11,7 @@ #include "rtc_base/checks.h" #include "test/gtest.h" +#include "test/testsupport/rtc_expect_death.h" namespace webrtc { namespace field_trial { @@ -28,23 +29,24 @@ TEST(FieldTrialValidationTest, AcceptsValidInputs) { TEST(FieldTrialValidationTest, RejectsBadInputs) { // Bad delimiters - EXPECT_DEATH(InitFieldTrialsFromString("Audio/EnabledVideo/Disabled/"), - "Invalid field trials string:"); - EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled//Video/Disabled/"), - "Invalid field trials string:"); - EXPECT_DEATH(InitFieldTrialsFromString("/Audio/Enabled/Video/Disabled/"), - "Invalid field trials string:"); - EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled/Video/Disabled"), - "Invalid field trials string:"); - EXPECT_DEATH( + RTC_EXPECT_DEATH(InitFieldTrialsFromString("Audio/EnabledVideo/Disabled/"), + "Invalid field trials string:"); + RTC_EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled//Video/Disabled/"), + "Invalid field trials string:"); + RTC_EXPECT_DEATH(InitFieldTrialsFromString("/Audio/Enabled/Video/Disabled/"), + "Invalid field trials string:"); + RTC_EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled/Video/Disabled"), + "Invalid field trials string:"); + RTC_EXPECT_DEATH( InitFieldTrialsFromString("Audio/Enabled/Video/Disabled/garbage"), "Invalid field trials string:"); // Duplicate trials with different values is not fine - EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled/Audio/Disabled/"), - "Invalid field trials string:"); - EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled/B/C/Audio/Disabled/"), - "Invalid field trials string:"); + RTC_EXPECT_DEATH(InitFieldTrialsFromString("Audio/Enabled/Audio/Disabled/"), + "Invalid field trials string:"); + RTC_EXPECT_DEATH( + InitFieldTrialsFromString("Audio/Enabled/B/C/Audio/Disabled/"), + "Invalid field trials string:"); } #endif // GTEST_HAS_DEATH_TEST && RTC_DCHECK_IS_ON && !defined(WEBRTC_ANDROID) // && !defined(WEBRTC_EXCLUDE_FIELD_TRIAL_DEFAULT) diff --git a/test/BUILD.gn b/test/BUILD.gn index 0c30e7f641..1a1147fe90 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -385,6 +385,7 @@ if (rtc_include_tests) { ":fileutils", ":fileutils_unittests", ":perf_test", + ":rtc_expect_death", ":rtp_test_utils", ":test_main", ":test_support", @@ -714,6 +715,16 @@ rtc_library("encoder_settings") { ] } +rtc_library("rtc_expect_death") { + testonly = true + sources = [ + "testsupport/rtc_expect_death.h", + ] + deps = [ + ":test_support", + ] +} + rtc_library("test_common") { testonly = true sources = [ diff --git a/test/testsupport/perf_test_unittest.cc b/test/testsupport/perf_test_unittest.cc index ecc4258594..8202471923 100644 --- a/test/testsupport/perf_test_unittest.cc +++ b/test/testsupport/perf_test_unittest.cc @@ -15,6 +15,7 @@ #include #include "test/gtest.h" +#include "test/testsupport/rtc_expect_death.h" namespace { @@ -113,16 +114,18 @@ TEST_F(PerfDeathTest, TestFiniteResultError) { const double kNan = std::numeric_limits::quiet_NaN(); const double kInf = std::numeric_limits::infinity(); - EXPECT_DEATH(PrintResult("a", "b", "c", kNan, "d", false), "finit"); - EXPECT_DEATH(PrintResult("a", "b", "c", kInf, "d", false), "finit"); + RTC_EXPECT_DEATH(PrintResult("a", "b", "c", kNan, "d", false), "finit"); + RTC_EXPECT_DEATH(PrintResult("a", "b", "c", kInf, "d", false), "finit"); - EXPECT_DEATH(PrintResultMeanAndError("a", "b", "c", kNan, 1, "d", false), ""); - EXPECT_DEATH(PrintResultMeanAndError("a", "b", "c", 1, kInf, "d", false), ""); + RTC_EXPECT_DEATH(PrintResultMeanAndError("a", "b", "c", kNan, 1, "d", false), + ""); + RTC_EXPECT_DEATH(PrintResultMeanAndError("a", "b", "c", 1, kInf, "d", false), + ""); const double kNanList[] = {kNan, kNan}; - EXPECT_DEATH(PrintResultList("a", "b", "c", kNanList, "d", false), ""); + RTC_EXPECT_DEATH(PrintResultList("a", "b", "c", kNanList, "d", false), ""); const double kInfList[] = {0, kInf}; - EXPECT_DEATH(PrintResultList("a", "b", "c", kInfList, "d", false), ""); + RTC_EXPECT_DEATH(PrintResultList("a", "b", "c", kInfList, "d", false), ""); } #endif diff --git a/test/testsupport/rtc_expect_death.h b/test/testsupport/rtc_expect_death.h new file mode 100644 index 0000000000..5941e12bd2 --- /dev/null +++ b/test/testsupport/rtc_expect_death.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef TEST_TESTSUPPORT_RTC_EXPECT_DEATH_H_ +#define TEST_TESTSUPPORT_RTC_EXPECT_DEATH_H_ + +#include "test/gtest.h" + +#if RTC_CHECK_MSG_ENABLED +#define RTC_EXPECT_DEATH(statement, regex) EXPECT_DEATH(statement, regex) +#else +// If RTC_CHECKs messages are disabled we can't validate failure message +#define RTC_EXPECT_DEATH(statement, regex) EXPECT_DEATH(statement, "") +#endif + +#endif // TEST_TESTSUPPORT_RTC_EXPECT_DEATH_H_ diff --git a/webrtc.gni b/webrtc.gni index 2aefe251b1..56a1b0deca 100644 --- a/webrtc.gni +++ b/webrtc.gni @@ -248,6 +248,10 @@ declare_args() { # Set this to true to disable trace events. rtc_disable_trace_events = false + + # Set this to true to disable detailed error message and logging for + # RTC_CHECKs. + rtc_disable_check_msg = false } # Make it possible to provide custom locations for some libraries (move these