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 "absl/log/log_entry.h"
17
18 #include <stddef.h>
19 #include <stdint.h>
20
21 #include <cstring>
22 #include <limits>
23 #include <string>
24 #include <type_traits>
25 #include <utility>
26 #include <vector>
27
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
30 #include "absl/base/attributes.h"
31 #include "absl/base/config.h"
32 #include "absl/base/log_severity.h"
33 #include "absl/log/internal/append_truncated.h"
34 #include "absl/log/internal/log_format.h"
35 #include "absl/log/internal/test_helpers.h"
36 #include "absl/strings/numbers.h"
37 #include "absl/strings/str_split.h"
38 #include "absl/strings/string_view.h"
39 #include "absl/time/civil_time.h"
40 #include "absl/time/time.h"
41 #include "absl/types/span.h"
42
43 namespace {
44 using ::absl::log_internal::LogEntryTestPeer;
45 using ::testing::Eq;
46 using ::testing::IsTrue;
47 using ::testing::StartsWith;
48 using ::testing::StrEq;
49
50 auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
51 new absl::log_internal::LogTestEnvironment);
52 } // namespace
53
54 namespace absl {
55 ABSL_NAMESPACE_BEGIN
56 namespace log_internal {
57
58 class LogEntryTestPeer {
59 public:
LogEntryTestPeer(absl::string_view base_filename,int line,bool prefix,absl::LogSeverity severity,absl::string_view timestamp,absl::LogEntry::tid_t tid,PrefixFormat format,absl::string_view text_message)60 LogEntryTestPeer(absl::string_view base_filename, int line, bool prefix,
61 absl::LogSeverity severity, absl::string_view timestamp,
62 absl::LogEntry::tid_t tid, PrefixFormat format,
63 absl::string_view text_message)
64 : format_{format}, buf_(15000, '\0') {
65 entry_.base_filename_ = base_filename;
66 entry_.line_ = line;
67 entry_.prefix_ = prefix;
68 entry_.severity_ = severity;
69 std::string time_err;
70 EXPECT_THAT(
71 absl::ParseTime("%Y-%m-%d%ET%H:%M:%E*S", timestamp,
72 absl::LocalTimeZone(), &entry_.timestamp_, &time_err),
73 IsTrue())
74 << "Failed to parse time " << timestamp << ": " << time_err;
75 entry_.tid_ = tid;
76 std::pair<absl::string_view, std::string> timestamp_bits =
77 absl::StrSplit(timestamp, absl::ByChar('.'));
78 EXPECT_THAT(absl::ParseCivilTime(timestamp_bits.first, &ci_.cs), IsTrue())
79 << "Failed to parse time " << timestamp_bits.first;
80 timestamp_bits.second.resize(9, '0');
81 int64_t nanos = 0;
82 EXPECT_THAT(absl::SimpleAtoi(timestamp_bits.second, &nanos), IsTrue())
83 << "Failed to parse time " << timestamp_bits.first;
84 ci_.subsecond = absl::Nanoseconds(nanos);
85
86 absl::Span<char> view = absl::MakeSpan(buf_);
87 view.remove_suffix(2);
88 entry_.prefix_len_ =
89 entry_.prefix_
90 ? log_internal::FormatLogPrefix(
91 entry_.log_severity(), entry_.timestamp(), entry_.tid(),
92 entry_.source_basename(), entry_.source_line(), format_, view)
93 : 0;
94
95 EXPECT_THAT(entry_.prefix_len_,
96 Eq(static_cast<size_t>(view.data() - buf_.data())));
97 log_internal::AppendTruncated(text_message, view);
98 view = absl::Span<char>(view.data(), view.size() + 2);
99 view[0] = '\n';
100 view[1] = '\0';
101 view.remove_prefix(2);
102 buf_.resize(static_cast<size_t>(view.data() - buf_.data()));
103 entry_.text_message_with_prefix_and_newline_and_nul_ = absl::MakeSpan(buf_);
104 }
105 LogEntryTestPeer(const LogEntryTestPeer&) = delete;
106 LogEntryTestPeer& operator=(const LogEntryTestPeer&) = delete;
107
FormatLogMessage() const108 std::string FormatLogMessage() const {
109 return log_internal::FormatLogMessage(
110 entry_.log_severity(), ci_.cs, ci_.subsecond, entry_.tid(),
111 entry_.source_basename(), entry_.source_line(), format_,
112 entry_.text_message());
113 }
FormatPrefixIntoSizedBuffer(size_t sz)114 std::string FormatPrefixIntoSizedBuffer(size_t sz) {
115 std::string str(sz, '\0');
116 absl::Span<char> buf(&str[0], str.size());
117 const size_t prefix_size = log_internal::FormatLogPrefix(
118 entry_.log_severity(), entry_.timestamp(), entry_.tid(),
119 entry_.source_basename(), entry_.source_line(), format_, buf);
120 EXPECT_THAT(prefix_size, Eq(static_cast<size_t>(buf.data() - str.data())));
121 str.resize(prefix_size);
122 return str;
123 }
entry() const124 const absl::LogEntry& entry() const { return entry_; }
125
126 private:
127 absl::LogEntry entry_;
128 PrefixFormat format_;
129 absl::TimeZone::CivilInfo ci_;
130 std::vector<char> buf_;
131 };
132
133 } // namespace log_internal
134 ABSL_NAMESPACE_END
135 } // namespace absl
136
137 namespace {
138 constexpr bool kUsePrefix = true, kNoPrefix = false;
139
TEST(LogEntryTest,Baseline)140 TEST(LogEntryTest, Baseline) {
141 LogEntryTestPeer entry("foo.cc", 1234, kUsePrefix, absl::LogSeverity::kInfo,
142 "2020-01-02T03:04:05.6789", 451,
143 absl::log_internal::PrefixFormat::kNotRaw,
144 "hello world");
145 EXPECT_THAT(entry.FormatLogMessage(),
146 Eq("I0102 03:04:05.678900 451 foo.cc:1234] hello world"));
147 EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
148 Eq("I0102 03:04:05.678900 451 foo.cc:1234] "));
149 for (size_t sz = strlen("I0102 03:04:05.678900 451 foo.cc:1234] ") + 20;
150 sz != std::numeric_limits<size_t>::max(); sz--)
151 EXPECT_THAT("I0102 03:04:05.678900 451 foo.cc:1234] ",
152 StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
153
154 EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline(),
155 Eq("I0102 03:04:05.678900 451 foo.cc:1234] hello world\n"));
156 EXPECT_THAT(
157 entry.entry().text_message_with_prefix_and_newline_c_str(),
158 StrEq("I0102 03:04:05.678900 451 foo.cc:1234] hello world\n"));
159 EXPECT_THAT(entry.entry().text_message_with_prefix(),
160 Eq("I0102 03:04:05.678900 451 foo.cc:1234] hello world"));
161 EXPECT_THAT(entry.entry().text_message(), Eq("hello world"));
162 }
163
TEST(LogEntryTest,NoPrefix)164 TEST(LogEntryTest, NoPrefix) {
165 LogEntryTestPeer entry("foo.cc", 1234, kNoPrefix, absl::LogSeverity::kInfo,
166 "2020-01-02T03:04:05.6789", 451,
167 absl::log_internal::PrefixFormat::kNotRaw,
168 "hello world");
169 EXPECT_THAT(entry.FormatLogMessage(),
170 Eq("I0102 03:04:05.678900 451 foo.cc:1234] hello world"));
171 // These methods are not responsible for honoring `prefix()`.
172 EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
173 Eq("I0102 03:04:05.678900 451 foo.cc:1234] "));
174 for (size_t sz = strlen("I0102 03:04:05.678900 451 foo.cc:1234] ") + 20;
175 sz != std::numeric_limits<size_t>::max(); sz--)
176 EXPECT_THAT("I0102 03:04:05.678900 451 foo.cc:1234] ",
177 StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
178
179 EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline(),
180 Eq("hello world\n"));
181 EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline_c_str(),
182 StrEq("hello world\n"));
183 EXPECT_THAT(entry.entry().text_message_with_prefix(), Eq("hello world"));
184 EXPECT_THAT(entry.entry().text_message(), Eq("hello world"));
185 }
186
TEST(LogEntryTest,EmptyFields)187 TEST(LogEntryTest, EmptyFields) {
188 LogEntryTestPeer entry("", 0, kUsePrefix, absl::LogSeverity::kInfo,
189 "2020-01-02T03:04:05", 0,
190 absl::log_internal::PrefixFormat::kNotRaw, "");
191 const std::string format_message = entry.FormatLogMessage();
192 EXPECT_THAT(format_message, Eq("I0102 03:04:05.000000 0 :0] "));
193 EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000), Eq(format_message));
194 for (size_t sz = format_message.size() + 20;
195 sz != std::numeric_limits<size_t>::max(); sz--)
196 EXPECT_THAT(format_message,
197 StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
198
199 EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline(),
200 Eq("I0102 03:04:05.000000 0 :0] \n"));
201 EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline_c_str(),
202 StrEq("I0102 03:04:05.000000 0 :0] \n"));
203 EXPECT_THAT(entry.entry().text_message_with_prefix(),
204 Eq("I0102 03:04:05.000000 0 :0] "));
205 EXPECT_THAT(entry.entry().text_message(), Eq(""));
206 }
207
TEST(LogEntryTest,NegativeFields)208 TEST(LogEntryTest, NegativeFields) {
209 // When Abseil's minimum C++ version is C++17, this conditional can be
210 // converted to a constexpr if and the static_cast below removed.
211 if (std::is_signed<absl::LogEntry::tid_t>::value) {
212 LogEntryTestPeer entry(
213 "foo.cc", -1234, kUsePrefix, absl::LogSeverity::kInfo,
214 "2020-01-02T03:04:05.6789", static_cast<absl::LogEntry::tid_t>(-451),
215 absl::log_internal::PrefixFormat::kNotRaw, "hello world");
216 EXPECT_THAT(entry.FormatLogMessage(),
217 Eq("I0102 03:04:05.678900 -451 foo.cc:-1234] hello world"));
218 EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
219 Eq("I0102 03:04:05.678900 -451 foo.cc:-1234] "));
220 for (size_t sz =
221 strlen("I0102 03:04:05.678900 -451 foo.cc:-1234] ") + 20;
222 sz != std::numeric_limits<size_t>::max(); sz--)
223 EXPECT_THAT("I0102 03:04:05.678900 -451 foo.cc:-1234] ",
224 StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
225
226 EXPECT_THAT(
227 entry.entry().text_message_with_prefix_and_newline(),
228 Eq("I0102 03:04:05.678900 -451 foo.cc:-1234] hello world\n"));
229 EXPECT_THAT(
230 entry.entry().text_message_with_prefix_and_newline_c_str(),
231 StrEq("I0102 03:04:05.678900 -451 foo.cc:-1234] hello world\n"));
232 EXPECT_THAT(entry.entry().text_message_with_prefix(),
233 Eq("I0102 03:04:05.678900 -451 foo.cc:-1234] hello world"));
234 EXPECT_THAT(entry.entry().text_message(), Eq("hello world"));
235 } else {
236 LogEntryTestPeer entry("foo.cc", -1234, kUsePrefix,
237 absl::LogSeverity::kInfo, "2020-01-02T03:04:05.6789",
238 451, absl::log_internal::PrefixFormat::kNotRaw,
239 "hello world");
240 EXPECT_THAT(entry.FormatLogMessage(),
241 Eq("I0102 03:04:05.678900 451 foo.cc:-1234] hello world"));
242 EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
243 Eq("I0102 03:04:05.678900 451 foo.cc:-1234] "));
244 for (size_t sz =
245 strlen("I0102 03:04:05.678900 451 foo.cc:-1234] ") + 20;
246 sz != std::numeric_limits<size_t>::max(); sz--)
247 EXPECT_THAT("I0102 03:04:05.678900 451 foo.cc:-1234] ",
248 StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
249
250 EXPECT_THAT(
251 entry.entry().text_message_with_prefix_and_newline(),
252 Eq("I0102 03:04:05.678900 451 foo.cc:-1234] hello world\n"));
253 EXPECT_THAT(
254 entry.entry().text_message_with_prefix_and_newline_c_str(),
255 StrEq("I0102 03:04:05.678900 451 foo.cc:-1234] hello world\n"));
256 EXPECT_THAT(entry.entry().text_message_with_prefix(),
257 Eq("I0102 03:04:05.678900 451 foo.cc:-1234] hello world"));
258 EXPECT_THAT(entry.entry().text_message(), Eq("hello world"));
259 }
260 }
261
TEST(LogEntryTest,LongFields)262 TEST(LogEntryTest, LongFields) {
263 LogEntryTestPeer entry(
264 "I am the very model of a modern Major-General / "
265 "I've information vegetable, animal, and mineral.",
266 2147483647, kUsePrefix, absl::LogSeverity::kInfo,
267 "2020-01-02T03:04:05.678967896789", 2147483647,
268 absl::log_internal::PrefixFormat::kNotRaw,
269 "I know the kings of England, and I quote the fights historical / "
270 "From Marathon to Waterloo, in order categorical.");
271 EXPECT_THAT(entry.FormatLogMessage(),
272 Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
273 "modern Major-General / I've information vegetable, animal, "
274 "and mineral.:2147483647] I know the kings of England, and I "
275 "quote the fights historical / From Marathon to Waterloo, in "
276 "order categorical."));
277 EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
278 Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
279 "modern Major-General / I've information vegetable, animal, "
280 "and mineral.:2147483647] "));
281 for (size_t sz =
282 strlen("I0102 03:04:05.678967 2147483647 I am the very model of a "
283 "modern Major-General / I've information vegetable, animal, "
284 "and mineral.:2147483647] ") +
285 20;
286 sz != std::numeric_limits<size_t>::max(); sz--)
287 EXPECT_THAT(
288 "I0102 03:04:05.678967 2147483647 I am the very model of a "
289 "modern Major-General / I've information vegetable, animal, "
290 "and mineral.:2147483647] ",
291 StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
292
293 EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline(),
294 Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
295 "modern Major-General / I've information vegetable, animal, "
296 "and mineral.:2147483647] I know the kings of England, and I "
297 "quote the fights historical / From Marathon to Waterloo, in "
298 "order categorical.\n"));
299 EXPECT_THAT(
300 entry.entry().text_message_with_prefix_and_newline_c_str(),
301 StrEq("I0102 03:04:05.678967 2147483647 I am the very model of a "
302 "modern Major-General / I've information vegetable, animal, "
303 "and mineral.:2147483647] I know the kings of England, and I "
304 "quote the fights historical / From Marathon to Waterloo, in "
305 "order categorical.\n"));
306 EXPECT_THAT(entry.entry().text_message_with_prefix(),
307 Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
308 "modern Major-General / I've information vegetable, animal, "
309 "and mineral.:2147483647] I know the kings of England, and I "
310 "quote the fights historical / From Marathon to Waterloo, in "
311 "order categorical."));
312 EXPECT_THAT(
313 entry.entry().text_message(),
314 Eq("I know the kings of England, and I quote the fights historical / "
315 "From Marathon to Waterloo, in order categorical."));
316 }
317
TEST(LogEntryTest,LongNegativeFields)318 TEST(LogEntryTest, LongNegativeFields) {
319 // When Abseil's minimum C++ version is C++17, this conditional can be
320 // converted to a constexpr if and the static_cast below removed.
321 if (std::is_signed<absl::LogEntry::tid_t>::value) {
322 LogEntryTestPeer entry(
323 "I am the very model of a modern Major-General / "
324 "I've information vegetable, animal, and mineral.",
325 -2147483647, kUsePrefix, absl::LogSeverity::kInfo,
326 "2020-01-02T03:04:05.678967896789",
327 static_cast<absl::LogEntry::tid_t>(-2147483647),
328 absl::log_internal::PrefixFormat::kNotRaw,
329 "I know the kings of England, and I quote the fights historical / "
330 "From Marathon to Waterloo, in order categorical.");
331 EXPECT_THAT(
332 entry.FormatLogMessage(),
333 Eq("I0102 03:04:05.678967 -2147483647 I am the very model of a "
334 "modern Major-General / I've information vegetable, animal, "
335 "and mineral.:-2147483647] I know the kings of England, and I "
336 "quote the fights historical / From Marathon to Waterloo, in "
337 "order categorical."));
338 EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
339 Eq("I0102 03:04:05.678967 -2147483647 I am the very model of a "
340 "modern Major-General / I've information vegetable, animal, "
341 "and mineral.:-2147483647] "));
342 for (size_t sz =
343 strlen(
344 "I0102 03:04:05.678967 -2147483647 I am the very model of a "
345 "modern Major-General / I've information vegetable, animal, "
346 "and mineral.:-2147483647] ") +
347 20;
348 sz != std::numeric_limits<size_t>::max(); sz--)
349 EXPECT_THAT(
350 "I0102 03:04:05.678967 -2147483647 I am the very model of a "
351 "modern Major-General / I've information vegetable, animal, "
352 "and mineral.:-2147483647] ",
353 StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
354
355 EXPECT_THAT(
356 entry.entry().text_message_with_prefix_and_newline(),
357 Eq("I0102 03:04:05.678967 -2147483647 I am the very model of a "
358 "modern Major-General / I've information vegetable, animal, "
359 "and mineral.:-2147483647] I know the kings of England, and I "
360 "quote the fights historical / From Marathon to Waterloo, in "
361 "order categorical.\n"));
362 EXPECT_THAT(
363 entry.entry().text_message_with_prefix_and_newline_c_str(),
364 StrEq("I0102 03:04:05.678967 -2147483647 I am the very model of a "
365 "modern Major-General / I've information vegetable, animal, "
366 "and mineral.:-2147483647] I know the kings of England, and I "
367 "quote the fights historical / From Marathon to Waterloo, in "
368 "order categorical.\n"));
369 EXPECT_THAT(
370 entry.entry().text_message_with_prefix(),
371 Eq("I0102 03:04:05.678967 -2147483647 I am the very model of a "
372 "modern Major-General / I've information vegetable, animal, "
373 "and mineral.:-2147483647] I know the kings of England, and I "
374 "quote the fights historical / From Marathon to Waterloo, in "
375 "order categorical."));
376 EXPECT_THAT(
377 entry.entry().text_message(),
378 Eq("I know the kings of England, and I quote the fights historical / "
379 "From Marathon to Waterloo, in order categorical."));
380 } else {
381 LogEntryTestPeer entry(
382 "I am the very model of a modern Major-General / "
383 "I've information vegetable, animal, and mineral.",
384 -2147483647, kUsePrefix, absl::LogSeverity::kInfo,
385 "2020-01-02T03:04:05.678967896789", 2147483647,
386 absl::log_internal::PrefixFormat::kNotRaw,
387 "I know the kings of England, and I quote the fights historical / "
388 "From Marathon to Waterloo, in order categorical.");
389 EXPECT_THAT(
390 entry.FormatLogMessage(),
391 Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
392 "modern Major-General / I've information vegetable, animal, "
393 "and mineral.:-2147483647] I know the kings of England, and I "
394 "quote the fights historical / From Marathon to Waterloo, in "
395 "order categorical."));
396 EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
397 Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
398 "modern Major-General / I've information vegetable, animal, "
399 "and mineral.:-2147483647] "));
400 for (size_t sz =
401 strlen(
402 "I0102 03:04:05.678967 2147483647 I am the very model of a "
403 "modern Major-General / I've information vegetable, animal, "
404 "and mineral.:-2147483647] ") +
405 20;
406 sz != std::numeric_limits<size_t>::max(); sz--)
407 EXPECT_THAT(
408 "I0102 03:04:05.678967 2147483647 I am the very model of a "
409 "modern Major-General / I've information vegetable, animal, "
410 "and mineral.:-2147483647] ",
411 StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
412
413 EXPECT_THAT(
414 entry.entry().text_message_with_prefix_and_newline(),
415 Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
416 "modern Major-General / I've information vegetable, animal, "
417 "and mineral.:-2147483647] I know the kings of England, and I "
418 "quote the fights historical / From Marathon to Waterloo, in "
419 "order categorical.\n"));
420 EXPECT_THAT(
421 entry.entry().text_message_with_prefix_and_newline_c_str(),
422 StrEq("I0102 03:04:05.678967 2147483647 I am the very model of a "
423 "modern Major-General / I've information vegetable, animal, "
424 "and mineral.:-2147483647] I know the kings of England, and I "
425 "quote the fights historical / From Marathon to Waterloo, in "
426 "order categorical.\n"));
427 EXPECT_THAT(
428 entry.entry().text_message_with_prefix(),
429 Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
430 "modern Major-General / I've information vegetable, animal, "
431 "and mineral.:-2147483647] I know the kings of England, and I "
432 "quote the fights historical / From Marathon to Waterloo, in "
433 "order categorical."));
434 EXPECT_THAT(
435 entry.entry().text_message(),
436 Eq("I know the kings of England, and I quote the fights historical / "
437 "From Marathon to Waterloo, in order categorical."));
438 }
439 }
440
TEST(LogEntryTest,Raw)441 TEST(LogEntryTest, Raw) {
442 LogEntryTestPeer entry("foo.cc", 1234, kUsePrefix, absl::LogSeverity::kInfo,
443 "2020-01-02T03:04:05.6789", 451,
444 absl::log_internal::PrefixFormat::kRaw, "hello world");
445 EXPECT_THAT(
446 entry.FormatLogMessage(),
447 Eq("I0102 03:04:05.678900 451 foo.cc:1234] RAW: hello world"));
448 EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
449 Eq("I0102 03:04:05.678900 451 foo.cc:1234] RAW: "));
450 for (size_t sz =
451 strlen("I0102 03:04:05.678900 451 foo.cc:1234] RAW: ") + 20;
452 sz != std::numeric_limits<size_t>::max(); sz--)
453 EXPECT_THAT("I0102 03:04:05.678900 451 foo.cc:1234] RAW: ",
454 StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
455
456 EXPECT_THAT(
457 entry.entry().text_message_with_prefix_and_newline(),
458 Eq("I0102 03:04:05.678900 451 foo.cc:1234] RAW: hello world\n"));
459 EXPECT_THAT(
460 entry.entry().text_message_with_prefix_and_newline_c_str(),
461 StrEq("I0102 03:04:05.678900 451 foo.cc:1234] RAW: hello world\n"));
462 EXPECT_THAT(
463 entry.entry().text_message_with_prefix(),
464 Eq("I0102 03:04:05.678900 451 foo.cc:1234] RAW: hello world"));
465 EXPECT_THAT(entry.entry().text_message(), Eq("hello world"));
466 }
467
468 } // namespace
469