Skip to content

Commit 1bd965e

Browse files
Improve Envoy QUICHE logging (envoyproxy#15549)
This PR makes a few small modifications to the Envoy platform implementation of the QUICHE logging code. Performance: conditions are no longer computed in QUICHE_LOG_IF unless the logging level is enabled. Debugging: logs now contain the file, line and function of the caller. Also, it is now possible to control the QUICHE verbosity threshold via an environment variable. Also, QUICHE_CHECH_GT and related macros will print out the value of the compared variables. Signed-off-by: David Schinazi <[email protected]>
1 parent ecf9011 commit 1bd965e

File tree

7 files changed

+145
-62
lines changed

7 files changed

+145
-62
lines changed

bazel/EXTERNAL_DEPS.md

+3
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ dependencies:
109109

110110
* `nghttp2`: set `ENVOY_NGHTTP2_TRACE` in the environment and run at `-l trace`.
111111

112+
* `QUICHE`: set `ENVOY_QUICHE_VERBOSITY=n` in the environment to display
113+
verbose logs up to level `n`.
114+
112115
# Distdir - prefetching dependencies
113116

114117
Usually Bazel downloads all dependencies during build time. But there is a

bazel/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,10 @@ bazel test //test/integration:protocol_integration_test --test_output=streamed \
619619
--test_arg="-l trace" --test_env="ENVOY_NGHTTP2_TRACE="
620620
```
621621

622+
Similarly, `QUICHE` verbose logs can be enabled by setting `ENVOY_QUICHE_VERBOSITY=n` in the
623+
environment where `n` is the desired verbosity level (e.g.
624+
`--test_env="ENVOY_QUICHE_VERBOSITY=2"`.
625+
622626
## Disabling optional features
623627

624628
The following optional features can be disabled on the Bazel build command-line:

source/docs/quiche_integration.md

+5
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,8 @@ When the aggregated buffered bytes goes above high watermark, its registered net
3535
As to Http::StreamEncoder::encodeHeaders()/encodeTrailers(), the accounting is done differently between Google QUIC and IETF QUIC:
3636
* In Google QUIC, encodeHeaders()/encodeTrailers() check the buffer size increase on header stream before and after writing headers/trailers. In QuicSession::OnCanWrite(), may drain header stream send buffer, so there we also check send buffer size decrease on header stream.
3737
* In IETF QUIC, encodeHeaders()/encodeTrailers() check the buffer size increase on the corresponding data stream which is similar to encodeData(). The buffered headers/trailers are only drained via QuicStream::OnCanWrite() so there is no need to check QuicSession::OnCanWrite.
38+
39+
### Debugging
40+
41+
QUICHE verbose logs (such as `QUICHE_VLOG(2)` for example) can be enabled by setting the `ENVOY_QUICHE_VERBOSITY` environment variable. For example, pass `--test_env="ENVOY_QUICHE_VERBOSITY=2"` to `bazel test`.
42+

source/extensions/quic_listeners/quiche/platform/quic_logging_impl.cc

+47-11
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,45 @@
77
#include "extensions/quic_listeners/quiche/platform/quic_logging_impl.h"
88

99
#include <atomic>
10+
#include <cstdlib>
1011

1112
#include "common/common/utility.h"
1213

1314
namespace quic {
1415

1516
namespace {
16-
std::atomic<int> g_verbosity_threshold;
17+
18+
// Helper class that allows getting and setting QUICHE log verbosity threshold.
19+
class QuicLogVerbosityManager {
20+
public:
21+
// Gets QUICHE log verbosity threshold.
22+
static int getThreshold() {
23+
return getSingleton()->verbosity_threshold_.load(std::memory_order_relaxed);
24+
}
25+
26+
// Sets QUICHE log verbosity threshold.
27+
static void setThreshold(int new_verbosity) {
28+
getSingleton()->verbosity_threshold_.store(new_verbosity, std::memory_order_relaxed);
29+
}
30+
31+
private:
32+
static QuicLogVerbosityManager* getSingleton() {
33+
static QuicLogVerbosityManager manager = QuicLogVerbosityManager();
34+
return &manager;
35+
}
36+
37+
explicit QuicLogVerbosityManager() {
38+
int verbosity = 0;
39+
const char* verbosity_str = std::getenv("ENVOY_QUICHE_VERBOSITY");
40+
if (verbosity_str != nullptr) {
41+
verbosity = atoi(verbosity_str);
42+
}
43+
verbosity_threshold_.store(verbosity, std::memory_order_relaxed);
44+
}
45+
46+
std::atomic<int> verbosity_threshold_;
47+
};
48+
1749
std::atomic<bool> g_dfatal_exit_disabled;
1850

1951
// Pointer to the global log sink, usually it is nullptr.
@@ -23,7 +55,16 @@ std::atomic<QuicLogSink*> g_quic_log_sink;
2355
absl::Mutex g_quic_log_sink_mutex;
2456
} // namespace
2557

26-
QuicLogEmitter::QuicLogEmitter(QuicLogLevel level) : level_(level), saved_errno_(errno) {}
58+
int getVerbosityLogThreshold() { return QuicLogVerbosityManager::getThreshold(); }
59+
60+
void setVerbosityLogThreshold(int new_verbosity) {
61+
QuicLogVerbosityManager::setThreshold(new_verbosity);
62+
}
63+
64+
QuicLogEmitter::QuicLogEmitter(QuicLogLevel level, const char* file_name, int line,
65+
const char* function_name)
66+
: level_(level), file_name_(file_name), line_(line), function_name_(function_name),
67+
saved_errno_(errno) {}
2768

2869
QuicLogEmitter::~QuicLogEmitter() {
2970
if (is_perror_) {
@@ -36,7 +77,8 @@ QuicLogEmitter::~QuicLogEmitter() {
3677
// the output.
3778
content.back() = '\0';
3879
}
39-
GetLogger().log(level_, "{}", content.c_str());
80+
GetLogger().log(::spdlog::source_loc(file_name_, line_, function_name_), level_, "{}",
81+
content.c_str());
4082

4183
// Normally there is no log sink and we can avoid acquiring the lock.
4284
if (g_quic_log_sink.load(std::memory_order_relaxed) != nullptr) {
@@ -61,15 +103,9 @@ QuicLogEmitter::~QuicLogEmitter() {
61103
}
62104
}
63105

64-
int GetVerbosityLogThreshold() { return g_verbosity_threshold.load(std::memory_order_relaxed); }
65-
66-
void SetVerbosityLogThreshold(int new_verbosity) {
67-
g_verbosity_threshold.store(new_verbosity, std::memory_order_relaxed);
68-
}
69-
70-
bool IsDFatalExitDisabled() { return g_dfatal_exit_disabled.load(std::memory_order_relaxed); }
106+
bool isDFatalExitDisabled() { return g_dfatal_exit_disabled.load(std::memory_order_relaxed); }
71107

72-
void SetDFatalExitDisabled(bool is_disabled) {
108+
void setDFatalExitDisabled(bool is_disabled) {
73109
g_dfatal_exit_disabled.store(is_disabled, std::memory_order_relaxed);
74110
}
75111

source/extensions/quic_listeners/quiche/platform/quic_logging_impl.h

+66-34
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,16 @@
3737
logstream
3838

3939
#define QUICHE_LOG_IF_IMPL(severity, condition) \
40-
QUICHE_LOG_IMPL_INTERNAL((condition) && quic::IsLogLevelEnabled(quic::severity), \
41-
quic::QuicLogEmitter(quic::severity).stream())
40+
QUICHE_LOG_IMPL_INTERNAL( \
41+
QUICHE_IS_LOG_LEVEL_ENABLED(severity) && (condition), \
42+
quic::QuicLogEmitter(quic::severity, __FILE__, __LINE__, __func__).stream())
4243

4344
#define QUICHE_LOG_IMPL(severity) QUICHE_LOG_IF_IMPL(severity, true)
4445

4546
#define QUICHE_VLOG_IF_IMPL(verbosity, condition) \
46-
QUICHE_LOG_IMPL_INTERNAL((condition) && quic::IsVerboseLogEnabled(verbosity), \
47-
quic::QuicLogEmitter(quic::INFO).stream())
47+
QUICHE_LOG_IMPL_INTERNAL( \
48+
quic::isVerboseLogEnabled(verbosity) && (condition), \
49+
quic::QuicLogEmitter(quic::INFO, __FILE__, __LINE__, __func__).stream())
4850

4951
#define QUICHE_VLOG_IMPL(verbosity) QUICHE_VLOG_IF_IMPL(verbosity, true)
5052

@@ -58,22 +60,29 @@
5860
#define QUICHE_LOG_EVERY_N_SEC_IMPL(severity, seconds) QUICHE_LOG_IMPL(severity)
5961

6062
#define QUICHE_PLOG_IMPL(severity) \
61-
QUICHE_LOG_IMPL_INTERNAL(quic::IsLogLevelEnabled(quic::severity), \
62-
quic::QuicLogEmitter(quic::severity).SetPerror().stream())
63+
QUICHE_LOG_IMPL_INTERNAL( \
64+
QUICHE_IS_LOG_LEVEL_ENABLED(severity), \
65+
quic::QuicLogEmitter(quic::severity, __FILE__, __LINE__, __func__).SetPerror().stream())
6366

64-
#define QUICHE_LOG_INFO_IS_ON_IMPL() quic::IsLogLevelEnabled(quic::INFO)
65-
#define QUICHE_LOG_WARNING_IS_ON_IMPL() quic::IsLogLevelEnabled(quic::WARNING)
66-
#define QUICHE_LOG_ERROR_IS_ON_IMPL() quic::IsLogLevelEnabled(quic::ERROR)
67+
#define QUICHE_LOG_INFO_IS_ON_IMPL() QUICHE_IS_LOG_LEVEL_ENABLED(INFO)
68+
#define QUICHE_LOG_WARNING_IS_ON_IMPL() QUICHE_IS_LOG_LEVEL_ENABLED(WARNING)
69+
#define QUICHE_LOG_ERROR_IS_ON_IMPL() QUICHE_IS_LOG_LEVEL_ENABLED(ERROR)
6770

68-
#define QUICHE_CHECK_IMPL(condition) \
69-
QUICHE_LOG_IF_IMPL(FATAL, ABSL_PREDICT_FALSE(!(condition))) << "CHECK failed: " #condition "."
71+
#define QUICHE_CHECK_INNER_IMPL(condition, details) \
72+
QUICHE_LOG_IF_IMPL(FATAL, ABSL_PREDICT_FALSE(!(condition))) << details << ". "
7073

71-
#define QUICHE_CHECK_GT_IMPL(a, b) QUICHE_CHECK_IMPL((a) > (b))
72-
#define QUICHE_CHECK_GE_IMPL(a, b) QUICHE_CHECK_IMPL((a) >= (b))
73-
#define QUICHE_CHECK_LT_IMPL(a, b) QUICHE_CHECK_IMPL((a) < (b))
74-
#define QUICHE_CHECK_LE_IMPL(a, b) QUICHE_CHECK_IMPL((a) <= (b))
75-
#define QUICHE_CHECK_NE_IMPL(a, b) QUICHE_CHECK_IMPL((a) != (b))
76-
#define QUICHE_CHECK_EQ_IMPL(a, b) QUICHE_CHECK_IMPL((a) == (b))
74+
#define QUICHE_CHECK_IMPL(condition) QUICHE_CHECK_INNER_IMPL(condition, "CHECK failed: " #condition)
75+
76+
#define QUICHE_CHECK_INNER_IMPL_OP(op, a, b) \
77+
QUICHE_CHECK_INNER_IMPL((a)op(b), \
78+
"CHECK failed: " #a " (=" << (a) << ") " #op " " #b " (=" << (b) << ")")
79+
80+
#define QUICHE_CHECK_GT_IMPL(a, b) QUICHE_CHECK_INNER_IMPL_OP(>, a, b)
81+
#define QUICHE_CHECK_GE_IMPL(a, b) QUICHE_CHECK_INNER_IMPL_OP(>=, a, b)
82+
#define QUICHE_CHECK_LT_IMPL(a, b) QUICHE_CHECK_INNER_IMPL_OP(<, a, b)
83+
#define QUICHE_CHECK_LE_IMPL(a, b) QUICHE_CHECK_INNER_IMPL_OP(<=, a, b)
84+
#define QUICHE_CHECK_NE_IMPL(a, b) QUICHE_CHECK_INNER_IMPL_OP(!=, a, b)
85+
#define QUICHE_CHECK_EQ_IMPL(a, b) QUICHE_CHECK_INNER_IMPL_OP(==, a, b)
7786

7887
#ifdef NDEBUG
7988
// Release build
@@ -87,6 +96,12 @@
8796
#define QUICHE_DLOG_INFO_IS_ON_IMPL() 0
8897
#define QUICHE_DLOG_EVERY_N_IMPL(severity, n) QUICHE_COMPILED_OUT_LOG(false)
8998
#define QUICHE_NOTREACHED_IMPL()
99+
#define QUICHE_DCHECK_GT_IMPL(a, b) QUICHE_COMPILED_OUT_LOG((a) > (b))
100+
#define QUICHE_DCHECK_GE_IMPL(a, b) QUICHE_COMPILED_OUT_LOG((a) >= (b))
101+
#define QUICHE_DCHECK_LT_IMPL(a, b) QUICHE_COMPILED_OUT_LOG((a) < (b))
102+
#define QUICHE_DCHECK_LE_IMPL(a, b) QUICHE_COMPILED_OUT_LOG((a) <= (b))
103+
#define QUICHE_DCHECK_NE_IMPL(a, b) QUICHE_COMPILED_OUT_LOG((a) != (b))
104+
#define QUICHE_DCHECK_EQ_IMPL(a, b) QUICHE_COMPILED_OUT_LOG((a) == (b))
90105
#else
91106
// Debug build
92107
#define QUICHE_DCHECK_IMPL(condition) QUICHE_CHECK_IMPL(condition)
@@ -97,21 +112,22 @@
97112
#define QUICHE_DLOG_INFO_IS_ON_IMPL() QUICHE_LOG_INFO_IS_ON_IMPL()
98113
#define QUICHE_DLOG_EVERY_N_IMPL(severity, n) QUICHE_LOG_EVERY_N_IMPL(severity, n)
99114
#define QUICHE_NOTREACHED_IMPL() NOT_REACHED_GCOVR_EXCL_LINE
115+
#define QUICHE_DCHECK_GT_IMPL(a, b) QUICHE_CHECK_GT_IMPL(a, b)
116+
#define QUICHE_DCHECK_GE_IMPL(a, b) QUICHE_CHECK_GE_IMPL(a, b)
117+
#define QUICHE_DCHECK_LT_IMPL(a, b) QUICHE_CHECK_LT_IMPL(a, b)
118+
#define QUICHE_DCHECK_LE_IMPL(a, b) QUICHE_CHECK_LE_IMPL(a, b)
119+
#define QUICHE_DCHECK_NE_IMPL(a, b) QUICHE_CHECK_NE_IMPL(a, b)
120+
#define QUICHE_DCHECK_EQ_IMPL(a, b) QUICHE_CHECK_EQ_IMPL(a, b)
100121
#endif
101122

102-
#define QUICHE_DCHECK_GE_IMPL(a, b) QUICHE_DCHECK_IMPL((a) >= (b))
103-
#define QUICHE_DCHECK_GT_IMPL(a, b) QUICHE_DCHECK_IMPL((a) > (b))
104-
#define QUICHE_DCHECK_LT_IMPL(a, b) QUICHE_DCHECK_IMPL((a) < (b))
105-
#define QUICHE_DCHECK_LE_IMPL(a, b) QUICHE_DCHECK_IMPL((a) <= (b))
106-
#define QUICHE_DCHECK_NE_IMPL(a, b) QUICHE_DCHECK_IMPL((a) != (b))
107-
#define QUICHE_DCHECK_EQ_IMPL(a, b) QUICHE_DCHECK_IMPL((a) == (b))
108-
109123
#define QUICHE_PREDICT_FALSE_IMPL(x) ABSL_PREDICT_FALSE(x)
110124

111125
namespace quic {
112126

113127
using QuicLogLevel = spdlog::level::level_enum;
114128

129+
static const QuicLogLevel TRACE = spdlog::level::trace;
130+
static const QuicLogLevel DEBUG = spdlog::level::debug;
115131
static const QuicLogLevel INFO = spdlog::level::info;
116132
static const QuicLogLevel WARNING = spdlog::level::warn;
117133
static const QuicLogLevel ERROR = spdlog::level::err;
@@ -126,7 +142,10 @@ static const QuicLogLevel DFATAL = FATAL;
126142

127143
class QuicLogEmitter {
128144
public:
129-
explicit QuicLogEmitter(QuicLogLevel level);
145+
// |file_name| and |function_name| MUST be valid for the lifetime of the QuicLogEmitter. This is
146+
// guaranteed when passing __FILE__ and __func__.
147+
explicit QuicLogEmitter(QuicLogLevel level, const char* file_name, int line,
148+
const char* function_name);
130149

131150
~QuicLogEmitter();
132151

@@ -139,6 +158,9 @@ class QuicLogEmitter {
139158

140159
private:
141160
const QuicLogLevel level_;
161+
const char* file_name_;
162+
int line_;
163+
const char* function_name_;
142164
const int saved_errno_;
143165
bool is_perror_ = false;
144166
std::ostringstream stream_;
@@ -157,17 +179,27 @@ inline spdlog::logger& GetLogger() {
157179
return Envoy::Logger::Registry::getLog(Envoy::Logger::Id::quic);
158180
}
159181

160-
inline bool IsLogLevelEnabled(QuicLogLevel level) { return level >= GetLogger().level(); }
161-
162-
int GetVerbosityLogThreshold();
163-
void SetVerbosityLogThreshold(int new_verbosity);
164-
165-
inline bool IsVerboseLogEnabled(int verbosity) {
166-
return IsLogLevelEnabled(INFO) && verbosity <= GetVerbosityLogThreshold();
182+
// This allows us to use QUICHE_CHECK(condition) from constexpr functions.
183+
#define QUICHE_IS_LOG_LEVEL_ENABLED(severity) quic::isLogLevelEnabled##severity()
184+
#define QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(severity) \
185+
inline bool isLogLevelEnabled##severity() { return quic::severity >= GetLogger().level(); }
186+
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(TRACE)
187+
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(DEBUG)
188+
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(INFO)
189+
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(WARNING)
190+
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(ERROR)
191+
QUICHE_IS_LOG_LEVEL_ENABLED_IMPL(DFATAL)
192+
inline bool constexpr isLogLevelEnabledFATAL() { return true; }
193+
194+
int getVerbosityLogThreshold();
195+
void setVerbosityLogThreshold(int new_verbosity);
196+
197+
inline bool isVerboseLogEnabled(int verbosity) {
198+
return QUICHE_IS_LOG_LEVEL_ENABLED(INFO) && verbosity <= getVerbosityLogThreshold();
167199
}
168200

169-
bool IsDFatalExitDisabled();
170-
void SetDFatalExitDisabled(bool is_disabled);
201+
bool isDFatalExitDisabled();
202+
void setDFatalExitDisabled(bool is_disabled);
171203

172204
// QuicLogSink is used to capture logs emitted from the QUICHE_LOG... macros.
173205
class QuicLogSink {

test/extensions/quic_listeners/quiche/platform/quic_mock_log_impl.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ class QuicEnvoyMockLog : public QuicLogSink {
5151
// behavior is restored.
5252
class ScopedDisableExitOnDFatal {
5353
public:
54-
ScopedDisableExitOnDFatal() : previous_value_(IsDFatalExitDisabled()) {
55-
SetDFatalExitDisabled(true);
54+
ScopedDisableExitOnDFatal() : previous_value_(isDFatalExitDisabled()) {
55+
setDFatalExitDisabled(true);
5656
}
5757

5858
ScopedDisableExitOnDFatal(const ScopedDisableExitOnDFatal&) = delete;
5959
ScopedDisableExitOnDFatal& operator=(const ScopedDisableExitOnDFatal&) = delete;
6060

61-
~ScopedDisableExitOnDFatal() { SetDFatalExitDisabled(previous_value_); }
61+
~ScopedDisableExitOnDFatal() { setDFatalExitDisabled(previous_value_); }
6262

6363
private:
6464
const bool previous_value_;

test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc

+17-14
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ namespace {
7474
class QuicPlatformTest : public testing::Test {
7575
protected:
7676
QuicPlatformTest()
77-
: log_level_(GetLogger().level()), verbosity_log_threshold_(GetVerbosityLogThreshold()) {
78-
SetVerbosityLogThreshold(0);
77+
: log_level_(GetLogger().level()), verbosity_log_threshold_(getVerbosityLogThreshold()) {
78+
setVerbosityLogThreshold(0);
7979
GetLogger().set_level(ERROR);
8080
}
8181

8282
~QuicPlatformTest() override {
83-
SetVerbosityLogThreshold(verbosity_log_threshold_);
83+
setVerbosityLogThreshold(verbosity_log_threshold_);
8484
GetLogger().set_level(log_level_);
8585
}
8686

@@ -312,12 +312,12 @@ TEST_F(QuicPlatformTest, QuicLog) {
312312
// Set QUIC log level to INFO, since VLOG is emitted at the INFO level.
313313
GetLogger().set_level(INFO);
314314

315-
ASSERT_EQ(0, GetVerbosityLogThreshold());
315+
ASSERT_EQ(0, getVerbosityLogThreshold());
316316

317317
QUIC_VLOG(1) << (i = 1);
318318
EXPECT_EQ(12, i);
319319

320-
SetVerbosityLogThreshold(1);
320+
setVerbosityLogThreshold(1);
321321

322322
EXPECT_LOG_CONTAINS("info", "i=1", QUIC_VLOG(1) << "i=" << (i = 1));
323323
EXPECT_EQ(1, i);
@@ -364,12 +364,12 @@ TEST_F(QuicPlatformTest, QuicDLog) {
364364
QUIC_DLOG_IF(INFO, true) << (i = 11);
365365
EXPECT_EQ(VALUE_BY_COMPILE_MODE(11, 0), i);
366366

367-
ASSERT_EQ(0, GetVerbosityLogThreshold());
367+
ASSERT_EQ(0, getVerbosityLogThreshold());
368368

369369
QUIC_DVLOG(1) << (i = 1);
370370
EXPECT_EQ(VALUE_BY_COMPILE_MODE(11, 0), i);
371371

372-
SetVerbosityLogThreshold(1);
372+
setVerbosityLogThreshold(1);
373373

374374
QUIC_DVLOG(1) << (i = 1);
375375
EXPECT_EQ(VALUE_BY_COMPILE_MODE(1, 0), i);
@@ -383,17 +383,20 @@ TEST_F(QuicPlatformTest, QuicDLog) {
383383

384384
#undef VALUE_BY_COMPILE_MODE
385385

386-
TEST_F(QuicPlatformTest, QuicCHECK) {
387-
CHECK(1 == 1);
388-
CHECK(1 == 1) << " 1 == 1 is forever true.";
386+
TEST_F(QuicPlatformTest, QuicheCheck) {
387+
QUICHE_CHECK(1 == 1);
388+
QUICHE_CHECK(1 == 1) << " 1 == 1 is forever true.";
389389

390-
EXPECT_DEBUG_DEATH({ DCHECK(false) << " Supposed to fail in debug mode."; },
390+
EXPECT_DEBUG_DEATH({ QUICHE_DCHECK(false) << " Supposed to fail in debug mode."; },
391391
"CHECK failed:.* Supposed to fail in debug mode.");
392-
EXPECT_DEBUG_DEATH({ DCHECK(false); }, "CHECK failed");
392+
EXPECT_DEBUG_DEATH({ QUICHE_DCHECK(false); }, "CHECK failed");
393393

394-
EXPECT_DEATH({ CHECK(false) << " Supposed to fail in all modes."; },
394+
EXPECT_DEATH({ QUICHE_CHECK(false) << " Supposed to fail in all modes."; },
395395
"CHECK failed:.* Supposed to fail in all modes.");
396-
EXPECT_DEATH({ CHECK(false); }, "CHECK failed");
396+
EXPECT_DEATH({ QUICHE_CHECK(false); }, "CHECK failed");
397+
EXPECT_DEATH({ QUICHE_CHECK_LT(1 + 1, 2); }, "CHECK failed: 1 \\+ 1 \\(=2\\) < 2 \\(=2\\)");
398+
EXPECT_DEBUG_DEATH({ QUICHE_DCHECK_NE(1 + 1, 2); },
399+
"CHECK failed: 1 \\+ 1 \\(=2\\) != 2 \\(=2\\)");
397400
}
398401

399402
// Test the behaviors of the cross products of

0 commit comments

Comments
 (0)