1 //
2 // Copyright 2022 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 #include <math.h>
17
18 #include <iomanip>
19 #include <limits>
20 #include <sstream>
21 #include <string>
22 #include <type_traits>
23
24 #ifdef __ANDROID__
25 #include <android/api-level.h>
26 #endif
27 #include "gmock/gmock.h"
28 #include "gtest/gtest.h"
29 #include "absl/log/internal/config.h"
30 #include "absl/log/internal/test_matchers.h"
31 #include "absl/log/log.h"
32 #include "absl/log/scoped_mock_log.h"
33 #include "absl/strings/match.h"
34 #include "absl/strings/str_cat.h"
35 #include "absl/strings/string_view.h"
36
37 namespace {
38 using ::absl::log_internal::MatchesOstream;
39 using ::absl::log_internal::TextMessage;
40 using ::absl::log_internal::TextPrefix;
41
42 using ::testing::AllOf;
43 using ::testing::AnyOf;
44 using ::testing::Eq;
45 using ::testing::IsEmpty;
46 using ::testing::Truly;
47 using ::testing::Types;
48
49 using ::testing::Each;
50 using ::testing::Ge;
51 using ::testing::Le;
52 using ::testing::SizeIs;
53
54 // Some aspects of formatting streamed data (e.g. pointer handling) are
55 // implementation-defined. Others are buggy in supported implementations.
56 // These tests validate that the formatting matches that performed by a
57 // `std::ostream` and also that the result is one of a list of expected formats.
58
ComparisonStream()59 std::ostringstream ComparisonStream() {
60 std::ostringstream str;
61 str.setf(std::ios_base::showbase | std::ios_base::boolalpha |
62 std::ios_base::internal);
63 return str;
64 }
65
TEST(LogFormatTest,NoMessage)66 TEST(LogFormatTest, NoMessage) {
67 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
68
69 const int log_line = __LINE__ + 1;
70 auto do_log = [] { LOG(INFO); };
71
72 EXPECT_CALL(
73 test_sink,
74 Send(AllOf(
75 TextMessage(MatchesOstream(ComparisonStream())),
76 TextPrefix(Truly([=](absl::string_view msg) {
77 return absl::EndsWith(
78 msg, absl::StrCat(" log_format_test.cc:", log_line, "] "));
79 })),
80 TextMessage(IsEmpty()), ENCODED_MESSAGE(EqualsProto(R"pb()pb")))));
81
82 test_sink.StartCapturingLogs();
83 do_log();
84 }
85
86 template <typename T>
87 class CharLogFormatTest : public testing::Test {};
88 using CharTypes = Types<char, signed char, unsigned char>;
89 TYPED_TEST_SUITE(CharLogFormatTest, CharTypes);
90
TYPED_TEST(CharLogFormatTest,Printable)91 TYPED_TEST(CharLogFormatTest, Printable) {
92 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
93
94 const TypeParam value = 'x';
95 auto comparison_stream = ComparisonStream();
96 comparison_stream << value;
97
98 EXPECT_CALL(
99 test_sink,
100 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
101 TextMessage(Eq("x")),
102 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "x" })pb")))));
103
104 test_sink.StartCapturingLogs();
105 LOG(INFO) << value;
106 }
107
TYPED_TEST(CharLogFormatTest,Unprintable)108 TYPED_TEST(CharLogFormatTest, Unprintable) {
109 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
110
111 constexpr auto value = static_cast<TypeParam>(0xeeu);
112 auto comparison_stream = ComparisonStream();
113 comparison_stream << value;
114
115 EXPECT_CALL(
116 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
117 TextMessage(Eq("\xee")),
118 ENCODED_MESSAGE(EqualsProto(R"pb(value {
119 str: "\xee"
120 })pb")))));
121
122 test_sink.StartCapturingLogs();
123 LOG(INFO) << value;
124 }
125
126 template <typename T>
127 class UnsignedIntLogFormatTest : public testing::Test {};
128 using UnsignedIntTypes = Types<unsigned short, unsigned int, // NOLINT
129 unsigned long, unsigned long long>; // NOLINT
130 TYPED_TEST_SUITE(UnsignedIntLogFormatTest, UnsignedIntTypes);
131
TYPED_TEST(UnsignedIntLogFormatTest,Positive)132 TYPED_TEST(UnsignedIntLogFormatTest, Positive) {
133 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
134
135 const TypeParam value = 224;
136 auto comparison_stream = ComparisonStream();
137 comparison_stream << value;
138
139 EXPECT_CALL(
140 test_sink,
141 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
142 TextMessage(Eq("224")),
143 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "224" })pb")))));
144
145 test_sink.StartCapturingLogs();
146 LOG(INFO) << value;
147 }
148
TYPED_TEST(UnsignedIntLogFormatTest,BitfieldPositive)149 TYPED_TEST(UnsignedIntLogFormatTest, BitfieldPositive) {
150 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
151
152 const struct {
153 TypeParam bits : 6;
154 } value{42};
155 auto comparison_stream = ComparisonStream();
156 comparison_stream << value.bits;
157
158 EXPECT_CALL(
159 test_sink,
160 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
161 TextMessage(Eq("42")),
162 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "42" })pb")))));
163
164 test_sink.StartCapturingLogs();
165 LOG(INFO) << value.bits;
166 }
167
168 template <typename T>
169 class SignedIntLogFormatTest : public testing::Test {};
170 using SignedIntTypes =
171 Types<signed short, signed int, signed long, signed long long>; // NOLINT
172 TYPED_TEST_SUITE(SignedIntLogFormatTest, SignedIntTypes);
173
TYPED_TEST(SignedIntLogFormatTest,Positive)174 TYPED_TEST(SignedIntLogFormatTest, Positive) {
175 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
176
177 const TypeParam value = 224;
178 auto comparison_stream = ComparisonStream();
179 comparison_stream << value;
180
181 EXPECT_CALL(
182 test_sink,
183 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
184 TextMessage(Eq("224")),
185 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "224" })pb")))));
186
187 test_sink.StartCapturingLogs();
188 LOG(INFO) << value;
189 }
190
TYPED_TEST(SignedIntLogFormatTest,Negative)191 TYPED_TEST(SignedIntLogFormatTest, Negative) {
192 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
193
194 const TypeParam value = -112;
195 auto comparison_stream = ComparisonStream();
196 comparison_stream << value;
197
198 EXPECT_CALL(
199 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
200 TextMessage(Eq("-112")),
201 ENCODED_MESSAGE(EqualsProto(R"pb(value {
202 str: "-112"
203 })pb")))));
204
205 test_sink.StartCapturingLogs();
206 LOG(INFO) << value;
207 }
208
TYPED_TEST(SignedIntLogFormatTest,BitfieldPositive)209 TYPED_TEST(SignedIntLogFormatTest, BitfieldPositive) {
210 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
211
212 const struct {
213 TypeParam bits : 6;
214 } value{21};
215 auto comparison_stream = ComparisonStream();
216 comparison_stream << value.bits;
217
218 EXPECT_CALL(
219 test_sink,
220 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
221 TextMessage(Eq("21")),
222 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "21" })pb")))));
223
224 test_sink.StartCapturingLogs();
225 LOG(INFO) << value.bits;
226 }
227
TYPED_TEST(SignedIntLogFormatTest,BitfieldNegative)228 TYPED_TEST(SignedIntLogFormatTest, BitfieldNegative) {
229 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
230
231 const struct {
232 TypeParam bits : 6;
233 } value{-21};
234 auto comparison_stream = ComparisonStream();
235 comparison_stream << value.bits;
236
237 EXPECT_CALL(
238 test_sink,
239 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
240 TextMessage(Eq("-21")),
241 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "-21" })pb")))));
242
243 test_sink.StartCapturingLogs();
244 LOG(INFO) << value.bits;
245 }
246
247 // Ignore these test cases on GCC due to "is too small to hold all values ..."
248 // warning.
249 #if !defined(__GNUC__) || defined(__clang__)
250 // The implementation may choose a signed or unsigned integer type to represent
251 // this enum, so it may be tested by either `UnsignedEnumLogFormatTest` or
252 // `SignedEnumLogFormatTest`.
253 enum MyUnsignedEnum {
254 MyUnsignedEnum_ZERO = 0,
255 MyUnsignedEnum_FORTY_TWO = 42,
256 MyUnsignedEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
257 };
258 enum MyUnsignedIntEnum : unsigned int {
259 MyUnsignedIntEnum_ZERO = 0,
260 MyUnsignedIntEnum_FORTY_TWO = 42,
261 MyUnsignedIntEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
262 };
263
264 template <typename T>
265 class UnsignedEnumLogFormatTest : public testing::Test {};
266 using UnsignedEnumTypes = std::conditional<
267 std::is_signed<std::underlying_type<MyUnsignedEnum>::type>::value,
268 Types<MyUnsignedIntEnum>, Types<MyUnsignedEnum, MyUnsignedIntEnum>>::type;
269 TYPED_TEST_SUITE(UnsignedEnumLogFormatTest, UnsignedEnumTypes);
270
TYPED_TEST(UnsignedEnumLogFormatTest,Positive)271 TYPED_TEST(UnsignedEnumLogFormatTest, Positive) {
272 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
273
274 const TypeParam value = static_cast<TypeParam>(224);
275 auto comparison_stream = ComparisonStream();
276 comparison_stream << value;
277
278 EXPECT_CALL(
279 test_sink,
280 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
281 TextMessage(Eq("224")),
282 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "224" })pb")))));
283
284 test_sink.StartCapturingLogs();
285 LOG(INFO) << value;
286 }
287
TYPED_TEST(UnsignedEnumLogFormatTest,BitfieldPositive)288 TYPED_TEST(UnsignedEnumLogFormatTest, BitfieldPositive) {
289 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
290
291 const struct {
292 TypeParam bits : 6;
293 } value{static_cast<TypeParam>(42)};
294 auto comparison_stream = ComparisonStream();
295 comparison_stream << value.bits;
296
297 EXPECT_CALL(
298 test_sink,
299 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
300 TextMessage(Eq("42")),
301 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "42" })pb")))));
302
303 test_sink.StartCapturingLogs();
304 LOG(INFO) << value.bits;
305 }
306
307 enum MySignedEnum {
308 MySignedEnum_NEGATIVE_ONE_HUNDRED_TWELVE = -112,
309 MySignedEnum_NEGATIVE_TWENTY_ONE = -21,
310 MySignedEnum_ZERO = 0,
311 MySignedEnum_TWENTY_ONE = 21,
312 MySignedEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
313 };
314 enum MySignedIntEnum : signed int {
315 MySignedIntEnum_NEGATIVE_ONE_HUNDRED_TWELVE = -112,
316 MySignedIntEnum_NEGATIVE_TWENTY_ONE = -21,
317 MySignedIntEnum_ZERO = 0,
318 MySignedIntEnum_TWENTY_ONE = 21,
319 MySignedIntEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
320 };
321
322 template <typename T>
323 class SignedEnumLogFormatTest : public testing::Test {};
324 using SignedEnumTypes = std::conditional<
325 std::is_signed<std::underlying_type<MyUnsignedEnum>::type>::value,
326 Types<MyUnsignedEnum, MySignedEnum, MySignedIntEnum>,
327 Types<MySignedEnum, MySignedIntEnum>>::type;
328 TYPED_TEST_SUITE(SignedEnumLogFormatTest, SignedEnumTypes);
329
TYPED_TEST(SignedEnumLogFormatTest,Positive)330 TYPED_TEST(SignedEnumLogFormatTest, Positive) {
331 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
332
333 const TypeParam value = static_cast<TypeParam>(224);
334 auto comparison_stream = ComparisonStream();
335 comparison_stream << value;
336
337 EXPECT_CALL(
338 test_sink,
339 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
340 TextMessage(Eq("224")),
341 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "224" })pb")))));
342
343 test_sink.StartCapturingLogs();
344 LOG(INFO) << value;
345 }
346
TYPED_TEST(SignedEnumLogFormatTest,Negative)347 TYPED_TEST(SignedEnumLogFormatTest, Negative) {
348 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
349
350 const TypeParam value = static_cast<TypeParam>(-112);
351 auto comparison_stream = ComparisonStream();
352 comparison_stream << value;
353
354 EXPECT_CALL(
355 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
356 TextMessage(Eq("-112")),
357 ENCODED_MESSAGE(EqualsProto(R"pb(value {
358 str: "-112"
359 })pb")))));
360
361 test_sink.StartCapturingLogs();
362 LOG(INFO) << value;
363 }
364
TYPED_TEST(SignedEnumLogFormatTest,BitfieldPositive)365 TYPED_TEST(SignedEnumLogFormatTest, BitfieldPositive) {
366 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
367
368 const struct {
369 TypeParam bits : 6;
370 } value{static_cast<TypeParam>(21)};
371 auto comparison_stream = ComparisonStream();
372 comparison_stream << value.bits;
373
374 EXPECT_CALL(
375 test_sink,
376 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
377 TextMessage(Eq("21")),
378 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "21" })pb")))));
379
380 test_sink.StartCapturingLogs();
381 LOG(INFO) << value.bits;
382 }
383
TYPED_TEST(SignedEnumLogFormatTest,BitfieldNegative)384 TYPED_TEST(SignedEnumLogFormatTest, BitfieldNegative) {
385 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
386
387 const struct {
388 TypeParam bits : 6;
389 } value{static_cast<TypeParam>(-21)};
390 auto comparison_stream = ComparisonStream();
391 comparison_stream << value.bits;
392
393 EXPECT_CALL(
394 test_sink,
395 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
396 TextMessage(Eq("-21")),
397 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "-21" })pb")))));
398
399 test_sink.StartCapturingLogs();
400 LOG(INFO) << value.bits;
401 }
402 #endif
403
TEST(FloatLogFormatTest,Positive)404 TEST(FloatLogFormatTest, Positive) {
405 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
406
407 const float value = 6.02e23f;
408 auto comparison_stream = ComparisonStream();
409 comparison_stream << value;
410
411 EXPECT_CALL(test_sink,
412 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
413 TextMessage(Eq("6.02e+23")),
414 ENCODED_MESSAGE(EqualsProto(R"pb(value {
415 str: "6.02e+23"
416 })pb")))));
417
418 test_sink.StartCapturingLogs();
419 LOG(INFO) << value;
420 }
421
TEST(FloatLogFormatTest,Negative)422 TEST(FloatLogFormatTest, Negative) {
423 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
424
425 const float value = -6.02e23f;
426 auto comparison_stream = ComparisonStream();
427 comparison_stream << value;
428
429 EXPECT_CALL(test_sink,
430 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
431 TextMessage(Eq("-6.02e+23")),
432 ENCODED_MESSAGE(EqualsProto(R"pb(value {
433 str: "-6.02e+23"
434 })pb")))));
435
436 test_sink.StartCapturingLogs();
437 LOG(INFO) << value;
438 }
439
TEST(FloatLogFormatTest,NegativeExponent)440 TEST(FloatLogFormatTest, NegativeExponent) {
441 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
442
443 const float value = 6.02e-23f;
444 auto comparison_stream = ComparisonStream();
445 comparison_stream << value;
446
447 EXPECT_CALL(test_sink,
448 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
449 TextMessage(Eq("6.02e-23")),
450 ENCODED_MESSAGE(EqualsProto(R"pb(value {
451 str: "6.02e-23"
452 })pb")))));
453
454 test_sink.StartCapturingLogs();
455 LOG(INFO) << value;
456 }
457
TEST(DoubleLogFormatTest,Positive)458 TEST(DoubleLogFormatTest, Positive) {
459 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
460
461 const double value = 6.02e23;
462 auto comparison_stream = ComparisonStream();
463 comparison_stream << value;
464
465 EXPECT_CALL(test_sink,
466 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
467 TextMessage(Eq("6.02e+23")),
468 ENCODED_MESSAGE(EqualsProto(R"pb(value {
469 str: "6.02e+23"
470 })pb")))));
471
472 test_sink.StartCapturingLogs();
473 LOG(INFO) << value;
474 }
475
TEST(DoubleLogFormatTest,Negative)476 TEST(DoubleLogFormatTest, Negative) {
477 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
478
479 const double value = -6.02e23;
480 auto comparison_stream = ComparisonStream();
481 comparison_stream << value;
482
483 EXPECT_CALL(test_sink,
484 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
485 TextMessage(Eq("-6.02e+23")),
486 ENCODED_MESSAGE(EqualsProto(R"pb(value {
487 str: "-6.02e+23"
488 })pb")))));
489
490 test_sink.StartCapturingLogs();
491 LOG(INFO) << value;
492 }
493
TEST(DoubleLogFormatTest,NegativeExponent)494 TEST(DoubleLogFormatTest, NegativeExponent) {
495 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
496
497 const double value = 6.02e-23;
498 auto comparison_stream = ComparisonStream();
499 comparison_stream << value;
500
501 EXPECT_CALL(test_sink,
502 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
503 TextMessage(Eq("6.02e-23")),
504 ENCODED_MESSAGE(EqualsProto(R"pb(value {
505 str: "6.02e-23"
506 })pb")))));
507
508 test_sink.StartCapturingLogs();
509 LOG(INFO) << value;
510 }
511
512 template <typename T>
513 class FloatingPointLogFormatTest : public testing::Test {};
514 using FloatingPointTypes = Types<float, double>;
515 TYPED_TEST_SUITE(FloatingPointLogFormatTest, FloatingPointTypes);
516
TYPED_TEST(FloatingPointLogFormatTest,Zero)517 TYPED_TEST(FloatingPointLogFormatTest, Zero) {
518 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
519
520 const TypeParam value = 0.0;
521 auto comparison_stream = ComparisonStream();
522 comparison_stream << value;
523
524 EXPECT_CALL(
525 test_sink,
526 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
527 TextMessage(Eq("0")),
528 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "0" })pb")))));
529
530 test_sink.StartCapturingLogs();
531 LOG(INFO) << value;
532 }
533
TYPED_TEST(FloatingPointLogFormatTest,Integer)534 TYPED_TEST(FloatingPointLogFormatTest, Integer) {
535 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
536
537 const TypeParam value = 1.0;
538 auto comparison_stream = ComparisonStream();
539 comparison_stream << value;
540
541 EXPECT_CALL(
542 test_sink,
543 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
544 TextMessage(Eq("1")),
545 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "1" })pb")))));
546
547 test_sink.StartCapturingLogs();
548 LOG(INFO) << value;
549 }
550
TYPED_TEST(FloatingPointLogFormatTest,Infinity)551 TYPED_TEST(FloatingPointLogFormatTest, Infinity) {
552 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
553
554 const TypeParam value = std::numeric_limits<TypeParam>::infinity();
555 auto comparison_stream = ComparisonStream();
556 comparison_stream << value;
557
558 EXPECT_CALL(
559 test_sink,
560 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
561 TextMessage(AnyOf(Eq("inf"), Eq("Inf"))),
562 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "inf" })pb")))));
563
564 test_sink.StartCapturingLogs();
565 LOG(INFO) << value;
566 }
567
TYPED_TEST(FloatingPointLogFormatTest,NegativeInfinity)568 TYPED_TEST(FloatingPointLogFormatTest, NegativeInfinity) {
569 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
570
571 const TypeParam value = -std::numeric_limits<TypeParam>::infinity();
572 auto comparison_stream = ComparisonStream();
573 comparison_stream << value;
574
575 EXPECT_CALL(
576 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
577 TextMessage(AnyOf(Eq("-inf"), Eq("-Inf"))),
578 ENCODED_MESSAGE(EqualsProto(R"pb(value {
579 str: "-inf"
580 })pb")))));
581
582 test_sink.StartCapturingLogs();
583 LOG(INFO) << value;
584 }
585
TYPED_TEST(FloatingPointLogFormatTest,NaN)586 TYPED_TEST(FloatingPointLogFormatTest, NaN) {
587 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
588
589 const TypeParam value = std::numeric_limits<TypeParam>::quiet_NaN();
590 auto comparison_stream = ComparisonStream();
591 comparison_stream << value;
592
593 EXPECT_CALL(
594 test_sink,
595 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
596 TextMessage(AnyOf(Eq("nan"), Eq("NaN"))),
597 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "nan" })pb")))));
598 test_sink.StartCapturingLogs();
599 LOG(INFO) << value;
600 }
601
TYPED_TEST(FloatingPointLogFormatTest,NegativeNaN)602 TYPED_TEST(FloatingPointLogFormatTest, NegativeNaN) {
603 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
604
605 const TypeParam value =
606 std::copysign(std::numeric_limits<TypeParam>::quiet_NaN(), -1.0);
607 auto comparison_stream = ComparisonStream();
608 comparison_stream << value;
609
610 EXPECT_CALL(
611 test_sink,
612 Send(AllOf(
613 TextMessage(MatchesOstream(comparison_stream)),
614 TextMessage(AnyOf(Eq("-nan"), Eq("nan"), Eq("NaN"), Eq("-nan(ind)"))),
615 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "-nan" })pb")))));
616
617 test_sink.StartCapturingLogs();
618 LOG(INFO) << value;
619 }
620
621 template <typename T>
622 class VoidPtrLogFormatTest : public testing::Test {};
623 using VoidPtrTypes = Types<void *, const void *>;
624 TYPED_TEST_SUITE(VoidPtrLogFormatTest, VoidPtrTypes);
625
TYPED_TEST(VoidPtrLogFormatTest,Null)626 TYPED_TEST(VoidPtrLogFormatTest, Null) {
627 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
628
629 const TypeParam value = nullptr;
630 auto comparison_stream = ComparisonStream();
631 comparison_stream << value;
632
633 EXPECT_CALL(
634 test_sink,
635 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
636 TextMessage(AnyOf(Eq("(nil)"), Eq("0"), Eq("0x0"),
637 Eq("00000000"), Eq("0000000000000000"))))));
638
639 test_sink.StartCapturingLogs();
640 LOG(INFO) << value;
641 }
642
TYPED_TEST(VoidPtrLogFormatTest,NonNull)643 TYPED_TEST(VoidPtrLogFormatTest, NonNull) {
644 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
645
646 const TypeParam value = reinterpret_cast<TypeParam>(0xdeadbeefULL);
647 auto comparison_stream = ComparisonStream();
648 comparison_stream << value;
649
650 EXPECT_CALL(test_sink,
651 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
652 TextMessage(AnyOf(Eq("0xdeadbeef"), Eq("DEADBEEF"),
653 Eq("00000000DEADBEEF"))),
654 ENCODED_MESSAGE(EqualsProto(R"pb(value {
655 str: "0xdeadbeef"
656 })pb")))));
657
658 test_sink.StartCapturingLogs();
659 LOG(INFO) << value;
660 }
661
662 template <typename T>
663 class VolatileVoidPtrLogFormatTest : public testing::Test {};
664 using VolatileVoidPtrTypes = Types<volatile void *, const volatile void *>;
665 TYPED_TEST_SUITE(VolatileVoidPtrLogFormatTest, VolatileVoidPtrTypes);
666
TYPED_TEST(VolatileVoidPtrLogFormatTest,Null)667 TYPED_TEST(VolatileVoidPtrLogFormatTest, Null) {
668 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
669
670 const TypeParam value = nullptr;
671 auto comparison_stream = ComparisonStream();
672 comparison_stream << value;
673
674 EXPECT_CALL(
675 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
676 TextMessage(Eq("false")),
677 ENCODED_MESSAGE(EqualsProto(R"pb(value {
678 str: "false"
679 })pb")))));
680
681 test_sink.StartCapturingLogs();
682 LOG(INFO) << value;
683 }
684
TYPED_TEST(VolatileVoidPtrLogFormatTest,NonNull)685 TYPED_TEST(VolatileVoidPtrLogFormatTest, NonNull) {
686 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
687
688 const TypeParam value = reinterpret_cast<TypeParam>(0xdeadbeefLL);
689 auto comparison_stream = ComparisonStream();
690 comparison_stream << value;
691
692 EXPECT_CALL(
693 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
694 TextMessage(Eq("true")),
695 ENCODED_MESSAGE(EqualsProto(R"pb(value {
696 str: "true"
697 })pb")))));
698
699 test_sink.StartCapturingLogs();
700 LOG(INFO) << value;
701 }
702
703 template <typename T>
704 class CharPtrLogFormatTest : public testing::Test {};
705 using CharPtrTypes = Types<char *, const char *>;
706 TYPED_TEST_SUITE(CharPtrLogFormatTest, CharPtrTypes);
707
TYPED_TEST(CharPtrLogFormatTest,Null)708 TYPED_TEST(CharPtrLogFormatTest, Null) {
709 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
710
711 // Streaming `([cv] char *)nullptr` into a `std::ostream` is UB, and some C++
712 // standard library implementations choose to crash. We take measures to log
713 // something useful instead of crashing, even when that differs from the
714 // standard library in use (and thus the behavior of `std::ostream`).
715 const TypeParam value = nullptr;
716
717 EXPECT_CALL(
718 test_sink,
719 Send(AllOf(
720 // `MatchesOstream` deliberately omitted since we deliberately differ.
721 TextMessage(Eq("(null)")),
722 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "(null)" })pb")))));
723
724 test_sink.StartCapturingLogs();
725 LOG(INFO) << value;
726 }
727
TYPED_TEST(CharPtrLogFormatTest,NonNull)728 TYPED_TEST(CharPtrLogFormatTest, NonNull) {
729 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
730
731 char data[] = "value";
732 const TypeParam value = data;
733 auto comparison_stream = ComparisonStream();
734 comparison_stream << value;
735
736 EXPECT_CALL(
737 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
738 TextMessage(Eq("value")),
739 ENCODED_MESSAGE(EqualsProto(R"pb(value {
740 str: "value"
741 })pb")))));
742
743 test_sink.StartCapturingLogs();
744 LOG(INFO) << value;
745 }
746
TEST(BoolLogFormatTest,True)747 TEST(BoolLogFormatTest, True) {
748 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
749
750 const bool value = true;
751 auto comparison_stream = ComparisonStream();
752 comparison_stream << value;
753
754 EXPECT_CALL(
755 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
756 TextMessage(Eq("true")),
757 ENCODED_MESSAGE(EqualsProto(R"pb(value {
758 str: "true"
759 })pb")))));
760
761 test_sink.StartCapturingLogs();
762 LOG(INFO) << value;
763 }
764
TEST(BoolLogFormatTest,False)765 TEST(BoolLogFormatTest, False) {
766 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
767
768 const bool value = false;
769 auto comparison_stream = ComparisonStream();
770 comparison_stream << value;
771
772 EXPECT_CALL(
773 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
774 TextMessage(Eq("false")),
775 ENCODED_MESSAGE(EqualsProto(R"pb(value {
776 str: "false"
777 })pb")))));
778
779 test_sink.StartCapturingLogs();
780 LOG(INFO) << value;
781 }
782
TEST(LogFormatTest,StringLiteral)783 TEST(LogFormatTest, StringLiteral) {
784 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
785
786 auto comparison_stream = ComparisonStream();
787 comparison_stream << "value";
788
789 EXPECT_CALL(test_sink,
790 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
791 TextMessage(Eq("value")),
792 ENCODED_MESSAGE(EqualsProto(R"pb(value {
793 literal: "value"
794 })pb")))));
795
796 test_sink.StartCapturingLogs();
797 LOG(INFO) << "value";
798 }
799
TEST(LogFormatTest,CharArray)800 TEST(LogFormatTest, CharArray) {
801 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
802
803 char value[] = "value";
804 auto comparison_stream = ComparisonStream();
805 comparison_stream << value;
806
807 EXPECT_CALL(
808 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
809 TextMessage(Eq("value")),
810 ENCODED_MESSAGE(EqualsProto(R"pb(value {
811 str: "value"
812 })pb")))));
813
814 test_sink.StartCapturingLogs();
815 LOG(INFO) << value;
816 }
817
818 class CustomClass {};
operator <<(std::ostream & os,const CustomClass &)819 std::ostream& operator<<(std::ostream& os, const CustomClass&) {
820 return os << "CustomClass{}";
821 }
822
TEST(LogFormatTest,Custom)823 TEST(LogFormatTest, Custom) {
824 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
825
826 CustomClass value;
827 auto comparison_stream = ComparisonStream();
828 comparison_stream << value;
829
830 EXPECT_CALL(test_sink,
831 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
832 TextMessage(Eq("CustomClass{}")),
833 ENCODED_MESSAGE(EqualsProto(R"pb(value {
834 str: "CustomClass{}"
835 })pb")))));
836 test_sink.StartCapturingLogs();
837 LOG(INFO) << value;
838 }
839
840 class CustomClassNonCopyable {
841 public:
842 CustomClassNonCopyable() = default;
843 CustomClassNonCopyable(const CustomClassNonCopyable&) = delete;
844 CustomClassNonCopyable& operator=(const CustomClassNonCopyable&) = delete;
845 };
operator <<(std::ostream & os,const CustomClassNonCopyable &)846 std::ostream& operator<<(std::ostream& os, const CustomClassNonCopyable&) {
847 return os << "CustomClassNonCopyable{}";
848 }
849
TEST(LogFormatTest,CustomNonCopyable)850 TEST(LogFormatTest, CustomNonCopyable) {
851 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
852
853 CustomClassNonCopyable value;
854 auto comparison_stream = ComparisonStream();
855 comparison_stream << value;
856
857 EXPECT_CALL(
858 test_sink,
859 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
860 TextMessage(Eq("CustomClassNonCopyable{}")),
861 ENCODED_MESSAGE(EqualsProto(
862 R"pb(value { str: "CustomClassNonCopyable{}" })pb")))));
863
864 test_sink.StartCapturingLogs();
865 LOG(INFO) << value;
866 }
867
TEST(ManipulatorLogFormatTest,BoolAlphaTrue)868 TEST(ManipulatorLogFormatTest, BoolAlphaTrue) {
869 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
870
871 const bool value = true;
872 auto comparison_stream = ComparisonStream();
873 comparison_stream << std::noboolalpha << value << " " //
874 << std::boolalpha << value << " " //
875 << std::noboolalpha << value;
876
877 EXPECT_CALL(test_sink,
878 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
879 TextMessage(Eq("1 true 1")),
880 ENCODED_MESSAGE(EqualsProto(
881 R"pb(value { str: "1" }
882 value { literal: " " }
883 value { str: "true" }
884 value { literal: " " }
885 value { str: "1" })pb")))));
886
887 test_sink.StartCapturingLogs();
888 LOG(INFO) << std::noboolalpha << value << " " //
889 << std::boolalpha << value << " " //
890 << std::noboolalpha << value;
891 }
892
TEST(ManipulatorLogFormatTest,BoolAlphaFalse)893 TEST(ManipulatorLogFormatTest, BoolAlphaFalse) {
894 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
895
896 const bool value = false;
897 auto comparison_stream = ComparisonStream();
898 comparison_stream << std::noboolalpha << value << " " //
899 << std::boolalpha << value << " " //
900 << std::noboolalpha << value;
901
902 EXPECT_CALL(test_sink,
903 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
904 TextMessage(Eq("0 false 0")),
905 ENCODED_MESSAGE(EqualsProto(
906 R"pb(value { str: "0" }
907 value { literal: " " }
908 value { str: "false" }
909 value { literal: " " }
910 value { str: "0" })pb")))));
911
912 test_sink.StartCapturingLogs();
913 LOG(INFO) << std::noboolalpha << value << " " //
914 << std::boolalpha << value << " " //
915 << std::noboolalpha << value;
916 }
917
TEST(ManipulatorLogFormatTest,ShowPoint)918 TEST(ManipulatorLogFormatTest, ShowPoint) {
919 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
920
921 const double value = 77.0;
922 auto comparison_stream = ComparisonStream();
923 comparison_stream << std::noshowpoint << value << " " //
924 << std::showpoint << value << " " //
925 << std::noshowpoint << value;
926
927 EXPECT_CALL(
928 test_sink,
929 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
930 TextMessage(Eq("77 77.0000 77")),
931 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" }
932 value { literal: " " }
933 value { str: "77.0000" }
934 value { literal: " " }
935 value { str: "77" })pb")))));
936
937 test_sink.StartCapturingLogs();
938 LOG(INFO) << std::noshowpoint << value << " " //
939 << std::showpoint << value << " " //
940 << std::noshowpoint << value;
941 }
942
TEST(ManipulatorLogFormatTest,ShowPos)943 TEST(ManipulatorLogFormatTest, ShowPos) {
944 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
945
946 const int value = 77;
947 auto comparison_stream = ComparisonStream();
948 comparison_stream << std::noshowpos << value << " " //
949 << std::showpos << value << " " //
950 << std::noshowpos << value;
951
952 EXPECT_CALL(
953 test_sink,
954 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
955 TextMessage(Eq("77 +77 77")),
956 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" }
957 value { literal: " " }
958 value { str: "+77" }
959 value { literal: " " }
960 value { str: "77" })pb")))));
961
962 test_sink.StartCapturingLogs();
963 LOG(INFO) << std::noshowpos << value << " " //
964 << std::showpos << value << " " //
965 << std::noshowpos << value;
966 }
967
TEST(ManipulatorLogFormatTest,UppercaseFloat)968 TEST(ManipulatorLogFormatTest, UppercaseFloat) {
969 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
970
971 const double value = 7.7e7;
972 auto comparison_stream = ComparisonStream();
973 comparison_stream << std::nouppercase << value << " " //
974 << std::uppercase << value << " " //
975 << std::nouppercase << value;
976
977 EXPECT_CALL(test_sink,
978 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
979 TextMessage(Eq("7.7e+07 7.7E+07 7.7e+07")),
980 ENCODED_MESSAGE(EqualsProto(
981 R"pb(value { str: "7.7e+07" }
982 value { literal: " " }
983 value { str: "7.7E+07" }
984 value { literal: " " }
985 value { str: "7.7e+07" })pb")))));
986
987 test_sink.StartCapturingLogs();
988 LOG(INFO) << std::nouppercase << value << " " //
989 << std::uppercase << value << " " //
990 << std::nouppercase << value;
991 }
992
TEST(ManipulatorLogFormatTest,Hex)993 TEST(ManipulatorLogFormatTest, Hex) {
994 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
995
996 const int value = 0x77;
997 auto comparison_stream = ComparisonStream();
998 comparison_stream << std::hex << value;
999
1000 EXPECT_CALL(
1001 test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1002 TextMessage(Eq("0x77")),
1003 ENCODED_MESSAGE(EqualsProto(R"pb(value {
1004 str: "0x77"
1005 })pb")))));
1006 test_sink.StartCapturingLogs();
1007 LOG(INFO) << std::hex << value;
1008 }
1009
TEST(ManipulatorLogFormatTest,Oct)1010 TEST(ManipulatorLogFormatTest, Oct) {
1011 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1012
1013 const int value = 077;
1014 auto comparison_stream = ComparisonStream();
1015 comparison_stream << std::oct << value;
1016
1017 EXPECT_CALL(
1018 test_sink,
1019 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1020 TextMessage(Eq("077")),
1021 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "077" })pb")))));
1022
1023 test_sink.StartCapturingLogs();
1024 LOG(INFO) << std::oct << value;
1025 }
1026
TEST(ManipulatorLogFormatTest,Dec)1027 TEST(ManipulatorLogFormatTest, Dec) {
1028 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1029
1030 const int value = 77;
1031 auto comparison_stream = ComparisonStream();
1032 comparison_stream << std::hex << std::dec << value;
1033
1034 EXPECT_CALL(
1035 test_sink,
1036 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1037 TextMessage(Eq("77")),
1038 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" })pb")))));
1039
1040 test_sink.StartCapturingLogs();
1041 LOG(INFO) << std::hex << std::dec << value;
1042 }
1043
TEST(ManipulatorLogFormatTest,ShowbaseHex)1044 TEST(ManipulatorLogFormatTest, ShowbaseHex) {
1045 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1046
1047 const int value = 0x77;
1048 auto comparison_stream = ComparisonStream();
1049 comparison_stream << std::hex //
1050 << std::noshowbase << value << " " //
1051 << std::showbase << value << " " //
1052 << std::noshowbase << value;
1053
1054 EXPECT_CALL(
1055 test_sink,
1056 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1057 TextMessage(Eq("77 0x77 77")),
1058 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" }
1059 value { literal: " " }
1060 value { str: "0x77" }
1061 value { literal: " " }
1062 value { str: "77" })pb")))));
1063
1064 test_sink.StartCapturingLogs();
1065 LOG(INFO) << std::hex //
1066 << std::noshowbase << value << " " //
1067 << std::showbase << value << " " //
1068 << std::noshowbase << value;
1069 }
1070
TEST(ManipulatorLogFormatTest,ShowbaseOct)1071 TEST(ManipulatorLogFormatTest, ShowbaseOct) {
1072 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1073
1074 const int value = 077;
1075 auto comparison_stream = ComparisonStream();
1076 comparison_stream << std::oct //
1077 << std::noshowbase << value << " " //
1078 << std::showbase << value << " " //
1079 << std::noshowbase << value;
1080
1081 EXPECT_CALL(
1082 test_sink,
1083 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1084 TextMessage(Eq("77 077 77")),
1085 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" }
1086 value { literal: " " }
1087 value { str: "077" }
1088 value { literal: " " }
1089 value { str: "77" })pb")))));
1090
1091 test_sink.StartCapturingLogs();
1092 LOG(INFO) << std::oct //
1093 << std::noshowbase << value << " " //
1094 << std::showbase << value << " " //
1095 << std::noshowbase << value;
1096 }
1097
TEST(ManipulatorLogFormatTest,UppercaseHex)1098 TEST(ManipulatorLogFormatTest, UppercaseHex) {
1099 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1100
1101 const int value = 0xbeef;
1102 auto comparison_stream = ComparisonStream();
1103 comparison_stream //
1104 << std::hex //
1105 << std::nouppercase << value << " " //
1106 << std::uppercase << value << " " //
1107 << std::nouppercase << value;
1108
1109 EXPECT_CALL(test_sink,
1110 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1111 TextMessage(Eq("0xbeef 0XBEEF 0xbeef")),
1112 ENCODED_MESSAGE(EqualsProto(
1113 R"pb(value { str: "0xbeef" }
1114 value { literal: " " }
1115 value { str: "0XBEEF" }
1116 value { literal: " " }
1117 value { str: "0xbeef" })pb")))));
1118
1119 test_sink.StartCapturingLogs();
1120 LOG(INFO) << std::hex //
1121 << std::nouppercase << value << " " //
1122 << std::uppercase << value << " " //
1123 << std::nouppercase << value;
1124 }
1125
TEST(ManipulatorLogFormatTest,FixedFloat)1126 TEST(ManipulatorLogFormatTest, FixedFloat) {
1127 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1128
1129 const double value = 7.7e7;
1130 auto comparison_stream = ComparisonStream();
1131 comparison_stream << std::fixed << value;
1132
1133 EXPECT_CALL(
1134 test_sink,
1135 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1136 TextMessage(Eq("77000000.000000")),
1137 ENCODED_MESSAGE(EqualsProto(R"pb(value {
1138 str: "77000000.000000"
1139 })pb")))));
1140
1141 test_sink.StartCapturingLogs();
1142 LOG(INFO) << std::fixed << value;
1143 }
1144
TEST(ManipulatorLogFormatTest,ScientificFloat)1145 TEST(ManipulatorLogFormatTest, ScientificFloat) {
1146 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1147
1148 const double value = 7.7e7;
1149 auto comparison_stream = ComparisonStream();
1150 comparison_stream << std::scientific << value;
1151
1152 EXPECT_CALL(test_sink,
1153 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1154 TextMessage(Eq("7.700000e+07")),
1155 ENCODED_MESSAGE(EqualsProto(R"pb(value {
1156 str: "7.700000e+07"
1157 })pb")))));
1158
1159 test_sink.StartCapturingLogs();
1160 LOG(INFO) << std::scientific << value;
1161 }
1162
1163 #if defined(__BIONIC__) && (!defined(__ANDROID_API__) || __ANDROID_API__ < 22)
1164 // Bionic doesn't support `%a` until API 22, so this prints 'a' even if the
1165 // C++ standard library implements it correctly (by forwarding to printf).
1166 #elif defined(__GLIBCXX__) && __cplusplus < 201402L
1167 // libstdc++ shipped C++11 support without `std::hexfloat`.
1168 #else
TEST(ManipulatorLogFormatTest,FixedAndScientificFloat)1169 TEST(ManipulatorLogFormatTest, FixedAndScientificFloat) {
1170 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1171
1172 const double value = 7.7e7;
1173 auto comparison_stream = ComparisonStream();
1174 comparison_stream << std::setiosflags(std::ios_base::scientific |
1175 std::ios_base::fixed)
1176 << value;
1177
1178 EXPECT_CALL(
1179 test_sink,
1180 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1181 TextMessage(AnyOf(Eq("0x1.25bb50p+26"), Eq("0x1.25bb5p+26"),
1182 Eq("0x1.25bb500000000p+26"))),
1183 ENCODED_MESSAGE(EqualsProto(R"pb(
1184 value { str: "0x1.25bb5p+26" })pb")))));
1185
1186 test_sink.StartCapturingLogs();
1187
1188 // This combination should mean the same thing as `std::hexfloat`.
1189 LOG(INFO) << std::setiosflags(std::ios_base::scientific |
1190 std::ios_base::fixed)
1191 << value;
1192 }
1193 #endif
1194
1195 #if defined(__BIONIC__) && (!defined(__ANDROID_API__) || __ANDROID_API__ < 22)
1196 // Bionic doesn't support `%a` until API 22, so this prints 'a' even if the C++
1197 // standard library supports `std::hexfloat` (by forwarding to printf).
1198 #elif defined(__GLIBCXX__) && __cplusplus < 201402L
1199 // libstdc++ shipped C++11 support without `std::hexfloat`.
1200 #else
TEST(ManipulatorLogFormatTest,HexfloatFloat)1201 TEST(ManipulatorLogFormatTest, HexfloatFloat) {
1202 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1203
1204 const double value = 7.7e7;
1205 auto comparison_stream = ComparisonStream();
1206 comparison_stream << std::hexfloat << value;
1207
1208 EXPECT_CALL(
1209 test_sink,
1210 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1211 TextMessage(AnyOf(Eq("0x1.25bb50p+26"), Eq("0x1.25bb5p+26"),
1212 Eq("0x1.25bb500000000p+26"))),
1213 ENCODED_MESSAGE(EqualsProto(R"pb(
1214 value { str: "0x1.25bb5p+26" })pb")))));
1215
1216 test_sink.StartCapturingLogs();
1217 LOG(INFO) << std::hexfloat << value;
1218 }
1219 #endif
1220
TEST(ManipulatorLogFormatTest,DefaultFloatFloat)1221 TEST(ManipulatorLogFormatTest, DefaultFloatFloat) {
1222 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1223
1224 const double value = 7.7e7;
1225 auto comparison_stream = ComparisonStream();
1226 comparison_stream << std::hexfloat << std::defaultfloat << value;
1227
1228 EXPECT_CALL(test_sink,
1229 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1230 TextMessage(Eq("7.7e+07")),
1231 ENCODED_MESSAGE(EqualsProto(R"pb(value {
1232 str: "7.7e+07"
1233 })pb")))));
1234
1235 test_sink.StartCapturingLogs();
1236 LOG(INFO) << std::hexfloat << std::defaultfloat << value;
1237 }
1238
TEST(ManipulatorLogFormatTest,Ends)1239 TEST(ManipulatorLogFormatTest, Ends) {
1240 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1241
1242 auto comparison_stream = ComparisonStream();
1243 comparison_stream << std::ends;
1244
1245 EXPECT_CALL(
1246 test_sink,
1247 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1248 TextMessage(Eq(absl::string_view("\0", 1))),
1249 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "\0" })pb")))));
1250
1251 test_sink.StartCapturingLogs();
1252 LOG(INFO) << std::ends;
1253 }
1254
TEST(ManipulatorLogFormatTest,Endl)1255 TEST(ManipulatorLogFormatTest, Endl) {
1256 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1257
1258 auto comparison_stream = ComparisonStream();
1259 comparison_stream << std::endl;
1260
1261 EXPECT_CALL(test_sink,
1262 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1263 TextMessage(Eq("\n")))));
1264
1265 test_sink.StartCapturingLogs();
1266 LOG(INFO) << std::endl;
1267 }
1268
TEST(ManipulatorLogFormatTest,SetIosFlags)1269 TEST(ManipulatorLogFormatTest, SetIosFlags) {
1270 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1271
1272 const int value = 0x77;
1273 auto comparison_stream = ComparisonStream();
1274 comparison_stream << std::resetiosflags(std::ios_base::basefield)
1275 << std::setiosflags(std::ios_base::hex) << value << " " //
1276 << std::resetiosflags(std::ios_base::basefield)
1277 << std::setiosflags(std::ios_base::dec) << value;
1278
1279 EXPECT_CALL(
1280 test_sink,
1281 Send(AllOf(
1282 TextMessage(MatchesOstream(comparison_stream)),
1283 TextMessage(Eq("0x77 119")),
1284 // `std::setiosflags` and `std::resetiosflags` aren't manipulators.
1285 // We're unable to distinguish their return type(s) from arbitrary
1286 // user-defined types and thus don't suppress the empty str value.
1287 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "0x77" }
1288 value { literal: " " }
1289 value { str: "119" }
1290 )pb")))));
1291
1292 test_sink.StartCapturingLogs();
1293 LOG(INFO) << std::resetiosflags(std::ios_base::basefield)
1294 << std::setiosflags(std::ios_base::hex) << value << " " //
1295 << std::resetiosflags(std::ios_base::basefield)
1296 << std::setiosflags(std::ios_base::dec) << value;
1297 }
1298
TEST(ManipulatorLogFormatTest,SetBase)1299 TEST(ManipulatorLogFormatTest, SetBase) {
1300 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1301
1302 const int value = 0x77;
1303 auto comparison_stream = ComparisonStream();
1304 comparison_stream << std::setbase(16) << value << " " //
1305 << std::setbase(0) << value;
1306
1307 EXPECT_CALL(
1308 test_sink,
1309 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1310 TextMessage(Eq("0x77 119")),
1311 // `std::setbase` isn't a manipulator. We're unable to
1312 // distinguish its return type from arbitrary user-defined
1313 // types and thus don't suppress the empty str value.
1314 ENCODED_MESSAGE(EqualsProto(
1315 R"pb(value { str: "0x77" }
1316 value { literal: " " }
1317 value { str: "119" })pb")))));
1318
1319 test_sink.StartCapturingLogs();
1320 LOG(INFO) << std::setbase(16) << value << " " //
1321 << std::setbase(0) << value;
1322 }
1323
TEST(ManipulatorLogFormatTest,SetPrecision)1324 TEST(ManipulatorLogFormatTest, SetPrecision) {
1325 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1326
1327 const double value = 6.022140857e23;
1328 auto comparison_stream = ComparisonStream();
1329 comparison_stream << std::setprecision(4) << value;
1330
1331 EXPECT_CALL(
1332 test_sink,
1333 Send(AllOf(
1334 TextMessage(MatchesOstream(comparison_stream)),
1335 TextMessage(Eq("6.022e+23")),
1336 // `std::setprecision` isn't a manipulator. We're unable to
1337 // distinguish its return type from arbitrary user-defined
1338 // types and thus don't suppress the empty str value.
1339 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "6.022e+23" })pb")))));
1340
1341 test_sink.StartCapturingLogs();
1342 LOG(INFO) << std::setprecision(4) << value;
1343 }
1344
TEST(ManipulatorLogFormatTest,SetPrecisionOverflow)1345 TEST(ManipulatorLogFormatTest, SetPrecisionOverflow) {
1346 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1347
1348 const double value = 6.022140857e23;
1349 auto comparison_stream = ComparisonStream();
1350 comparison_stream << std::setprecision(200) << value;
1351
1352 EXPECT_CALL(
1353 test_sink,
1354 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1355 TextMessage(Eq("602214085700000015187968")),
1356 ENCODED_MESSAGE(EqualsProto(
1357 R"pb(value { str: "602214085700000015187968" })pb")))));
1358
1359 test_sink.StartCapturingLogs();
1360 LOG(INFO) << std::setprecision(200) << value;
1361 }
1362
TEST(ManipulatorLogFormatTest,SetW)1363 TEST(ManipulatorLogFormatTest, SetW) {
1364 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1365
1366 const int value = 77;
1367 auto comparison_stream = ComparisonStream();
1368 comparison_stream << std::setw(8) << value;
1369
1370 EXPECT_CALL(
1371 test_sink,
1372 Send(AllOf(
1373 TextMessage(MatchesOstream(comparison_stream)),
1374 TextMessage(Eq(" 77")),
1375 // `std::setw` isn't a manipulator. We're unable to
1376 // distinguish its return type from arbitrary user-defined
1377 // types and thus don't suppress the empty str value.
1378 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: " 77" })pb")))));
1379
1380 test_sink.StartCapturingLogs();
1381 LOG(INFO) << std::setw(8) << value;
1382 }
1383
TEST(ManipulatorLogFormatTest,Left)1384 TEST(ManipulatorLogFormatTest, Left) {
1385 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1386
1387 const int value = -77;
1388 auto comparison_stream = ComparisonStream();
1389 comparison_stream << std::left << std::setw(8) << value;
1390
1391 EXPECT_CALL(test_sink,
1392 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1393 TextMessage(Eq("-77 ")),
1394 ENCODED_MESSAGE(EqualsProto(R"pb(value {
1395 str: "-77 "
1396 })pb")))));
1397
1398 test_sink.StartCapturingLogs();
1399 LOG(INFO) << std::left << std::setw(8) << value;
1400 }
1401
TEST(ManipulatorLogFormatTest,Right)1402 TEST(ManipulatorLogFormatTest, Right) {
1403 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1404
1405 const int value = -77;
1406 auto comparison_stream = ComparisonStream();
1407 comparison_stream << std::right << std::setw(8) << value;
1408
1409 EXPECT_CALL(test_sink,
1410 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1411 TextMessage(Eq(" -77")),
1412 ENCODED_MESSAGE(EqualsProto(R"pb(value {
1413 str: " -77"
1414 })pb")))));
1415
1416 test_sink.StartCapturingLogs();
1417 LOG(INFO) << std::right << std::setw(8) << value;
1418 }
1419
TEST(ManipulatorLogFormatTest,Internal)1420 TEST(ManipulatorLogFormatTest, Internal) {
1421 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1422
1423 const int value = -77;
1424 auto comparison_stream = ComparisonStream();
1425 comparison_stream << std::internal << std::setw(8) << value;
1426
1427 EXPECT_CALL(test_sink,
1428 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1429 TextMessage(Eq("- 77")),
1430 ENCODED_MESSAGE(EqualsProto(R"pb(value {
1431 str: "- 77"
1432 })pb")))));
1433
1434 test_sink.StartCapturingLogs();
1435 LOG(INFO) << std::internal << std::setw(8) << value;
1436 }
1437
TEST(ManipulatorLogFormatTest,SetFill)1438 TEST(ManipulatorLogFormatTest, SetFill) {
1439 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1440
1441 const int value = 77;
1442 auto comparison_stream = ComparisonStream();
1443 comparison_stream << std::setfill('0') << std::setw(8) << value;
1444
1445 EXPECT_CALL(test_sink,
1446 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1447 TextMessage(Eq("00000077")),
1448 // `std::setfill` isn't a manipulator. We're
1449 // unable to distinguish its return
1450 // type from arbitrary user-defined types and
1451 // thus don't suppress the empty str value.
1452 ENCODED_MESSAGE(EqualsProto(R"pb(value {
1453 str: "00000077"
1454 })pb")))));
1455
1456 test_sink.StartCapturingLogs();
1457 LOG(INFO) << std::setfill('0') << std::setw(8) << value;
1458 }
1459
1460 class FromCustomClass {};
operator <<(std::ostream & os,const FromCustomClass &)1461 std::ostream& operator<<(std::ostream& os, const FromCustomClass&) {
1462 return os << "FromCustomClass{}" << std::hex;
1463 }
1464
TEST(ManipulatorLogFormatTest,FromCustom)1465 TEST(ManipulatorLogFormatTest, FromCustom) {
1466 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1467
1468 FromCustomClass value;
1469 auto comparison_stream = ComparisonStream();
1470 comparison_stream << value << " " << 0x77;
1471
1472 EXPECT_CALL(test_sink,
1473 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1474 TextMessage(Eq("FromCustomClass{} 0x77")),
1475 ENCODED_MESSAGE(EqualsProto(
1476 R"pb(value { str: "FromCustomClass{}" }
1477 value { literal: " " }
1478 value { str: "0x77" })pb")))));
1479
1480 test_sink.StartCapturingLogs();
1481 LOG(INFO) << value << " " << 0x77;
1482 }
1483
1484 class StreamsNothing {};
operator <<(std::ostream & os,const StreamsNothing &)1485 std::ostream& operator<<(std::ostream& os, const StreamsNothing&) { return os; }
1486
TEST(ManipulatorLogFormatTest,CustomClassStreamsNothing)1487 TEST(ManipulatorLogFormatTest, CustomClassStreamsNothing) {
1488 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1489
1490 StreamsNothing value;
1491 auto comparison_stream = ComparisonStream();
1492 comparison_stream << value << 77;
1493
1494 EXPECT_CALL(
1495 test_sink,
1496 Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1497 TextMessage(Eq("77")),
1498 ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" })pb")))));
1499
1500 test_sink.StartCapturingLogs();
1501 LOG(INFO) << value << 77;
1502 }
1503
1504 // Tests that verify the behavior when more data are streamed into a `LOG`
1505 // statement than fit in the buffer.
1506 // Structured logging scenario is tested in other unit tests since the output is
1507 // significantly different.
TEST(OverflowTest,TruncatesStrings)1508 TEST(OverflowTest, TruncatesStrings) {
1509 absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1510
1511 // This message is too long and should be truncated to some unspecified size
1512 // no greater than the buffer size but not too much less either. It should be
1513 // truncated rather than discarded.
1514 constexpr size_t buffer_size = 15000;
1515
1516 EXPECT_CALL(test_sink,
1517 Send(TextMessage(
1518 AllOf(SizeIs(AllOf(Ge(buffer_size - 256), Le(buffer_size))),
1519 Each(Eq('x'))))));
1520
1521 test_sink.StartCapturingLogs();
1522 LOG(INFO) << std::string(2 * buffer_size, 'x');
1523 }
1524
1525 } // namespace
1526