1*8f0ba417SAndroid Build Coastguard Worker /*
2*8f0ba417SAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
3*8f0ba417SAndroid Build Coastguard Worker *
4*8f0ba417SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8f0ba417SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8f0ba417SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8f0ba417SAndroid Build Coastguard Worker *
8*8f0ba417SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8f0ba417SAndroid Build Coastguard Worker *
10*8f0ba417SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8f0ba417SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8f0ba417SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8f0ba417SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8f0ba417SAndroid Build Coastguard Worker * limitations under the License.
15*8f0ba417SAndroid Build Coastguard Worker */
16*8f0ba417SAndroid Build Coastguard Worker
17*8f0ba417SAndroid Build Coastguard Worker #include "logging_splitters.h"
18*8f0ba417SAndroid Build Coastguard Worker
19*8f0ba417SAndroid Build Coastguard Worker #include <string>
20*8f0ba417SAndroid Build Coastguard Worker #include <vector>
21*8f0ba417SAndroid Build Coastguard Worker
22*8f0ba417SAndroid Build Coastguard Worker #include <android-base/silent_death_test.h>
23*8f0ba417SAndroid Build Coastguard Worker #include <android-base/strings.h>
24*8f0ba417SAndroid Build Coastguard Worker #include <gtest/gtest.h>
25*8f0ba417SAndroid Build Coastguard Worker
26*8f0ba417SAndroid Build Coastguard Worker using logging_splitters_DeathTest = SilentDeathTest;
27*8f0ba417SAndroid Build Coastguard Worker
28*8f0ba417SAndroid Build Coastguard Worker namespace android {
29*8f0ba417SAndroid Build Coastguard Worker namespace base {
30*8f0ba417SAndroid Build Coastguard Worker
TestNewlineSplitter(const std::string & input,const std::vector<std::string> & expected_output)31*8f0ba417SAndroid Build Coastguard Worker void TestNewlineSplitter(const std::string& input,
32*8f0ba417SAndroid Build Coastguard Worker const std::vector<std::string>& expected_output) {
33*8f0ba417SAndroid Build Coastguard Worker std::vector<std::string> output;
34*8f0ba417SAndroid Build Coastguard Worker auto logger_function = [&](const char* msg, int length) {
35*8f0ba417SAndroid Build Coastguard Worker if (length == -1) {
36*8f0ba417SAndroid Build Coastguard Worker output.push_back(msg);
37*8f0ba417SAndroid Build Coastguard Worker } else {
38*8f0ba417SAndroid Build Coastguard Worker output.push_back(std::string(msg, length));
39*8f0ba417SAndroid Build Coastguard Worker }
40*8f0ba417SAndroid Build Coastguard Worker };
41*8f0ba417SAndroid Build Coastguard Worker SplitByLines(input.c_str(), logger_function);
42*8f0ba417SAndroid Build Coastguard Worker
43*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(expected_output, output);
44*8f0ba417SAndroid Build Coastguard Worker }
45*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,NewlineSplitter_EmptyString)46*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, NewlineSplitter_EmptyString) {
47*8f0ba417SAndroid Build Coastguard Worker TestNewlineSplitter("", std::vector<std::string>{""});
48*8f0ba417SAndroid Build Coastguard Worker }
49*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,NewlineSplitter_BasicString)50*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, NewlineSplitter_BasicString) {
51*8f0ba417SAndroid Build Coastguard Worker TestNewlineSplitter("normal string", std::vector<std::string>{"normal string"});
52*8f0ba417SAndroid Build Coastguard Worker }
53*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,NewlineSplitter_ormalBasicStringTrailingNewline)54*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, NewlineSplitter_ormalBasicStringTrailingNewline) {
55*8f0ba417SAndroid Build Coastguard Worker TestNewlineSplitter("normal string\n", std::vector<std::string>{"normal string", ""});
56*8f0ba417SAndroid Build Coastguard Worker }
57*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,NewlineSplitter_MultilineTrailing)58*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, NewlineSplitter_MultilineTrailing) {
59*8f0ba417SAndroid Build Coastguard Worker TestNewlineSplitter("normal string\nsecond string\nthirdstring",
60*8f0ba417SAndroid Build Coastguard Worker std::vector<std::string>{"normal string", "second string", "thirdstring"});
61*8f0ba417SAndroid Build Coastguard Worker }
62*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,NewlineSplitter_MultilineTrailingNewline)63*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, NewlineSplitter_MultilineTrailingNewline) {
64*8f0ba417SAndroid Build Coastguard Worker TestNewlineSplitter(
65*8f0ba417SAndroid Build Coastguard Worker "normal string\nsecond string\nthirdstring\n",
66*8f0ba417SAndroid Build Coastguard Worker std::vector<std::string>{"normal string", "second string", "thirdstring", ""});
67*8f0ba417SAndroid Build Coastguard Worker }
68*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,NewlineSplitter_MultilineEmbeddedNewlines)69*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, NewlineSplitter_MultilineEmbeddedNewlines) {
70*8f0ba417SAndroid Build Coastguard Worker TestNewlineSplitter(
71*8f0ba417SAndroid Build Coastguard Worker "normal string\n\n\nsecond string\n\nthirdstring\n",
72*8f0ba417SAndroid Build Coastguard Worker std::vector<std::string>{"normal string", "", "", "second string", "", "thirdstring", ""});
73*8f0ba417SAndroid Build Coastguard Worker }
74*8f0ba417SAndroid Build Coastguard Worker
TestLogdChunkSplitter(const std::string & tag,const std::string & file,const std::string & input,const std::vector<std::string> & expected_output)75*8f0ba417SAndroid Build Coastguard Worker void TestLogdChunkSplitter(const std::string& tag, const std::string& file,
76*8f0ba417SAndroid Build Coastguard Worker const std::string& input,
77*8f0ba417SAndroid Build Coastguard Worker const std::vector<std::string>& expected_output) {
78*8f0ba417SAndroid Build Coastguard Worker std::vector<std::string> output;
79*8f0ba417SAndroid Build Coastguard Worker auto logger_function = [&](LogId, LogSeverity, const char*, const char* msg) {
80*8f0ba417SAndroid Build Coastguard Worker output.push_back(msg);
81*8f0ba417SAndroid Build Coastguard Worker };
82*8f0ba417SAndroid Build Coastguard Worker
83*8f0ba417SAndroid Build Coastguard Worker SplitByLogdChunks(MAIN, FATAL, tag.c_str(), file.empty() ? nullptr : file.c_str(), 1000,
84*8f0ba417SAndroid Build Coastguard Worker input.c_str(), logger_function);
85*8f0ba417SAndroid Build Coastguard Worker
86*8f0ba417SAndroid Build Coastguard Worker auto return_lengths = [&] {
87*8f0ba417SAndroid Build Coastguard Worker std::string sizes;
88*8f0ba417SAndroid Build Coastguard Worker sizes += "expected_output sizes:";
89*8f0ba417SAndroid Build Coastguard Worker for (const auto& string : expected_output) {
90*8f0ba417SAndroid Build Coastguard Worker sizes += " " + std::to_string(string.size());
91*8f0ba417SAndroid Build Coastguard Worker }
92*8f0ba417SAndroid Build Coastguard Worker sizes += "\noutput sizes:";
93*8f0ba417SAndroid Build Coastguard Worker for (const auto& string : output) {
94*8f0ba417SAndroid Build Coastguard Worker sizes += " " + std::to_string(string.size());
95*8f0ba417SAndroid Build Coastguard Worker }
96*8f0ba417SAndroid Build Coastguard Worker return sizes;
97*8f0ba417SAndroid Build Coastguard Worker };
98*8f0ba417SAndroid Build Coastguard Worker
99*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(expected_output, output) << return_lengths();
100*8f0ba417SAndroid Build Coastguard Worker }
101*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,LogdChunkSplitter_EmptyString)102*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_EmptyString) {
103*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter("tag", "", "", std::vector<std::string>{""});
104*8f0ba417SAndroid Build Coastguard Worker }
105*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,LogdChunkSplitter_BasicString)106*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_BasicString) {
107*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter("tag", "", "normal string", std::vector<std::string>{"normal string"});
108*8f0ba417SAndroid Build Coastguard Worker }
109*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,LogdChunkSplitter_NormalBasicStringTrailingNewline)110*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_NormalBasicStringTrailingNewline) {
111*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter("tag", "", "normal string\n", std::vector<std::string>{"normal string\n"});
112*8f0ba417SAndroid Build Coastguard Worker }
113*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,LogdChunkSplitter_MultilineTrailing)114*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_MultilineTrailing) {
115*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter("tag", "", "normal string\nsecond string\nthirdstring",
116*8f0ba417SAndroid Build Coastguard Worker std::vector<std::string>{"normal string\nsecond string\nthirdstring"});
117*8f0ba417SAndroid Build Coastguard Worker }
118*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,LogdChunkSplitter_MultilineTrailingNewline)119*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_MultilineTrailingNewline) {
120*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter("tag", "", "normal string\nsecond string\nthirdstring\n",
121*8f0ba417SAndroid Build Coastguard Worker std::vector<std::string>{"normal string\nsecond string\nthirdstring\n"});
122*8f0ba417SAndroid Build Coastguard Worker }
123*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,LogdChunkSplitter_MultilineEmbeddedNewlines)124*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_MultilineEmbeddedNewlines) {
125*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter(
126*8f0ba417SAndroid Build Coastguard Worker "tag", "", "normal string\n\n\nsecond string\n\nthirdstring\n",
127*8f0ba417SAndroid Build Coastguard Worker std::vector<std::string>{"normal string\n\n\nsecond string\n\nthirdstring\n"});
128*8f0ba417SAndroid Build Coastguard Worker }
129*8f0ba417SAndroid Build Coastguard Worker
130*8f0ba417SAndroid Build Coastguard Worker // This test should return the same string, the logd logger itself will truncate down to size.
131*8f0ba417SAndroid Build Coastguard Worker // This has historically been the behavior both in libbase and liblog.
TEST(logging_splitters,LogdChunkSplitter_HugeLineNoNewline)132*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_HugeLineNoNewline) {
133*8f0ba417SAndroid Build Coastguard Worker auto long_string = std::string(LOGGER_ENTRY_MAX_PAYLOAD, 'x');
134*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(LOGGER_ENTRY_MAX_PAYLOAD, static_cast<int>(long_string.size()));
135*8f0ba417SAndroid Build Coastguard Worker
136*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter("tag", "", long_string, std::vector{long_string});
137*8f0ba417SAndroid Build Coastguard Worker }
138*8f0ba417SAndroid Build Coastguard Worker
ReduceToMaxSize(const std::string & tag,const std::string & string)139*8f0ba417SAndroid Build Coastguard Worker std::string ReduceToMaxSize(const std::string& tag, const std::string& string) {
140*8f0ba417SAndroid Build Coastguard Worker return string.substr(0, LOGGER_ENTRY_MAX_PAYLOAD - tag.size() - 35);
141*8f0ba417SAndroid Build Coastguard Worker }
142*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,LogdChunkSplitter_MultipleHugeLineNoNewline)143*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_MultipleHugeLineNoNewline) {
144*8f0ba417SAndroid Build Coastguard Worker auto long_string_x = std::string(LOGGER_ENTRY_MAX_PAYLOAD, 'x');
145*8f0ba417SAndroid Build Coastguard Worker auto long_string_y = std::string(LOGGER_ENTRY_MAX_PAYLOAD, 'y');
146*8f0ba417SAndroid Build Coastguard Worker auto long_string_z = std::string(LOGGER_ENTRY_MAX_PAYLOAD, 'z');
147*8f0ba417SAndroid Build Coastguard Worker
148*8f0ba417SAndroid Build Coastguard Worker auto long_strings = long_string_x + '\n' + long_string_y + '\n' + long_string_z;
149*8f0ba417SAndroid Build Coastguard Worker
150*8f0ba417SAndroid Build Coastguard Worker std::string tag = "tag";
151*8f0ba417SAndroid Build Coastguard Worker std::vector expected = {ReduceToMaxSize(tag, long_string_x), ReduceToMaxSize(tag, long_string_y),
152*8f0ba417SAndroid Build Coastguard Worker long_string_z};
153*8f0ba417SAndroid Build Coastguard Worker
154*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter(tag, "", long_strings, expected);
155*8f0ba417SAndroid Build Coastguard Worker }
156*8f0ba417SAndroid Build Coastguard Worker
157*8f0ba417SAndroid Build Coastguard Worker // With a ~4k buffer, we should print 2 long strings per logger call.
TEST(logging_splitters,LogdChunkSplitter_Multiple2kLines)158*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_Multiple2kLines) {
159*8f0ba417SAndroid Build Coastguard Worker std::vector expected = {
160*8f0ba417SAndroid Build Coastguard Worker std::string(2000, 'a') + '\n' + std::string(2000, 'b'),
161*8f0ba417SAndroid Build Coastguard Worker std::string(2000, 'c') + '\n' + std::string(2000, 'd'),
162*8f0ba417SAndroid Build Coastguard Worker std::string(2000, 'e') + '\n' + std::string(2000, 'f'),
163*8f0ba417SAndroid Build Coastguard Worker };
164*8f0ba417SAndroid Build Coastguard Worker
165*8f0ba417SAndroid Build Coastguard Worker auto long_strings = Join(expected, '\n');
166*8f0ba417SAndroid Build Coastguard Worker
167*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter("tag", "", long_strings, expected);
168*8f0ba417SAndroid Build Coastguard Worker }
169*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,LogdChunkSplitter_ExactSizedLines)170*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_ExactSizedLines) {
171*8f0ba417SAndroid Build Coastguard Worker const char* tag = "tag";
172*8f0ba417SAndroid Build Coastguard Worker ptrdiff_t max_size = LOGGER_ENTRY_MAX_PAYLOAD - strlen(tag) - 35;
173*8f0ba417SAndroid Build Coastguard Worker auto long_string_a = std::string(max_size, 'a');
174*8f0ba417SAndroid Build Coastguard Worker auto long_string_b = std::string(max_size, 'b');
175*8f0ba417SAndroid Build Coastguard Worker auto long_string_c = std::string(max_size, 'c');
176*8f0ba417SAndroid Build Coastguard Worker
177*8f0ba417SAndroid Build Coastguard Worker auto long_strings = long_string_a + '\n' + long_string_b + '\n' + long_string_c;
178*8f0ba417SAndroid Build Coastguard Worker
179*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter(tag, "", long_strings,
180*8f0ba417SAndroid Build Coastguard Worker std::vector{long_string_a, long_string_b, long_string_c});
181*8f0ba417SAndroid Build Coastguard Worker }
182*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,LogdChunkSplitter_UnderEqualOver)183*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_UnderEqualOver) {
184*8f0ba417SAndroid Build Coastguard Worker std::string tag = "tag";
185*8f0ba417SAndroid Build Coastguard Worker ptrdiff_t max_size = LOGGER_ENTRY_MAX_PAYLOAD - tag.size() - 35;
186*8f0ba417SAndroid Build Coastguard Worker
187*8f0ba417SAndroid Build Coastguard Worker auto first_string_size = 1000;
188*8f0ba417SAndroid Build Coastguard Worker auto first_string = std::string(first_string_size, 'a');
189*8f0ba417SAndroid Build Coastguard Worker auto second_string_size = max_size - first_string_size - 1;
190*8f0ba417SAndroid Build Coastguard Worker auto second_string = std::string(second_string_size, 'b');
191*8f0ba417SAndroid Build Coastguard Worker
192*8f0ba417SAndroid Build Coastguard Worker auto exact_string = std::string(max_size, 'c');
193*8f0ba417SAndroid Build Coastguard Worker
194*8f0ba417SAndroid Build Coastguard Worker auto large_string = std::string(max_size + 50, 'd');
195*8f0ba417SAndroid Build Coastguard Worker
196*8f0ba417SAndroid Build Coastguard Worker auto final_string = std::string("final string!\n\nfinal \n \n final \n");
197*8f0ba417SAndroid Build Coastguard Worker
198*8f0ba417SAndroid Build Coastguard Worker std::vector expected = {first_string + '\n' + second_string, exact_string,
199*8f0ba417SAndroid Build Coastguard Worker ReduceToMaxSize(tag, large_string), final_string};
200*8f0ba417SAndroid Build Coastguard Worker
201*8f0ba417SAndroid Build Coastguard Worker std::vector input_strings = {first_string + '\n' + second_string, exact_string, large_string,
202*8f0ba417SAndroid Build Coastguard Worker final_string};
203*8f0ba417SAndroid Build Coastguard Worker auto long_strings = Join(input_strings, '\n');
204*8f0ba417SAndroid Build Coastguard Worker
205*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter(tag, "", long_strings, expected);
206*8f0ba417SAndroid Build Coastguard Worker }
207*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,LogdChunkSplitter_WithFile)208*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_WithFile) {
209*8f0ba417SAndroid Build Coastguard Worker std::string tag = "tag";
210*8f0ba417SAndroid Build Coastguard Worker std::string file = "/path/to/myfile.cpp";
211*8f0ba417SAndroid Build Coastguard Worker int line = 1000;
212*8f0ba417SAndroid Build Coastguard Worker auto file_header = StringPrintf("%s:%d] ", file.c_str(), line);
213*8f0ba417SAndroid Build Coastguard Worker ptrdiff_t max_size = LOGGER_ENTRY_MAX_PAYLOAD - tag.size() - 35;
214*8f0ba417SAndroid Build Coastguard Worker
215*8f0ba417SAndroid Build Coastguard Worker auto first_string_size = 1000;
216*8f0ba417SAndroid Build Coastguard Worker auto first_string = std::string(first_string_size, 'a');
217*8f0ba417SAndroid Build Coastguard Worker auto second_string_size = max_size - first_string_size - 1 - 2 * file_header.size();
218*8f0ba417SAndroid Build Coastguard Worker auto second_string = std::string(second_string_size, 'b');
219*8f0ba417SAndroid Build Coastguard Worker
220*8f0ba417SAndroid Build Coastguard Worker auto exact_string = std::string(max_size - file_header.size(), 'c');
221*8f0ba417SAndroid Build Coastguard Worker
222*8f0ba417SAndroid Build Coastguard Worker auto large_string = std::string(max_size + 50, 'd');
223*8f0ba417SAndroid Build Coastguard Worker
224*8f0ba417SAndroid Build Coastguard Worker auto final_string = std::string("final string!");
225*8f0ba417SAndroid Build Coastguard Worker
226*8f0ba417SAndroid Build Coastguard Worker std::vector expected = {
227*8f0ba417SAndroid Build Coastguard Worker file_header + first_string + '\n' + file_header + second_string, file_header + exact_string,
228*8f0ba417SAndroid Build Coastguard Worker file_header + ReduceToMaxSize(file_header + tag, large_string), file_header + final_string};
229*8f0ba417SAndroid Build Coastguard Worker
230*8f0ba417SAndroid Build Coastguard Worker std::vector input_strings = {first_string + '\n' + second_string, exact_string, large_string,
231*8f0ba417SAndroid Build Coastguard Worker final_string};
232*8f0ba417SAndroid Build Coastguard Worker auto long_strings = Join(input_strings, '\n');
233*8f0ba417SAndroid Build Coastguard Worker
234*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter(tag, file, long_strings, expected);
235*8f0ba417SAndroid Build Coastguard Worker }
236*8f0ba417SAndroid Build Coastguard Worker
237*8f0ba417SAndroid Build Coastguard Worker // We set max_size based off of tag, so if it's too large, the buffer will be sized wrong.
238*8f0ba417SAndroid Build Coastguard Worker // We could recover from this, but it's certainly an error for someone to attempt to use a tag this
239*8f0ba417SAndroid Build Coastguard Worker // large, so we abort instead.
TEST_F(logging_splitters_DeathTest,LogdChunkSplitter_TooLongTag)240*8f0ba417SAndroid Build Coastguard Worker TEST_F(logging_splitters_DeathTest, LogdChunkSplitter_TooLongTag) {
241*8f0ba417SAndroid Build Coastguard Worker auto long_tag = std::string(5000, 'x');
242*8f0ba417SAndroid Build Coastguard Worker auto logger_function = [](LogId, LogSeverity, const char*, const char*) {};
243*8f0ba417SAndroid Build Coastguard Worker ASSERT_DEATH(
244*8f0ba417SAndroid Build Coastguard Worker SplitByLogdChunks(MAIN, ERROR, long_tag.c_str(), nullptr, 0, "message", logger_function), "");
245*8f0ba417SAndroid Build Coastguard Worker }
246*8f0ba417SAndroid Build Coastguard Worker
247*8f0ba417SAndroid Build Coastguard Worker // We do handle excessively large file names correctly however.
TEST(logging_splitters,LogdChunkSplitter_TooLongFile)248*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, LogdChunkSplitter_TooLongFile) {
249*8f0ba417SAndroid Build Coastguard Worker auto long_file = std::string(5000, 'x');
250*8f0ba417SAndroid Build Coastguard Worker std::string tag = "tag";
251*8f0ba417SAndroid Build Coastguard Worker
252*8f0ba417SAndroid Build Coastguard Worker std::vector expected = {ReduceToMaxSize(tag, long_file), ReduceToMaxSize(tag, long_file)};
253*8f0ba417SAndroid Build Coastguard Worker
254*8f0ba417SAndroid Build Coastguard Worker TestLogdChunkSplitter(tag, long_file, "can't see me\nor me", expected);
255*8f0ba417SAndroid Build Coastguard Worker }
256*8f0ba417SAndroid Build Coastguard Worker
TestStderrOutputGenerator(const char * tag,const char * file,int line,const char * message,const std::string & expected)257*8f0ba417SAndroid Build Coastguard Worker void TestStderrOutputGenerator(const char* tag, const char* file, int line, const char* message,
258*8f0ba417SAndroid Build Coastguard Worker const std::string& expected) {
259*8f0ba417SAndroid Build Coastguard Worker // All log messages will show "01-01 00:00:00.000"...
260*8f0ba417SAndroid Build Coastguard Worker struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
261*8f0ba417SAndroid Build Coastguard Worker // ...provided we're in the right time zone.
262*8f0ba417SAndroid Build Coastguard Worker putenv(const_cast<char*>("TZ=UTC"));
263*8f0ba417SAndroid Build Coastguard Worker tzset();
264*8f0ba417SAndroid Build Coastguard Worker
265*8f0ba417SAndroid Build Coastguard Worker int pid = 1234; // All log messages will have 1234 for their PID.
266*8f0ba417SAndroid Build Coastguard Worker uint64_t tid = 4321; // All log messages will have 4321 for their TID.
267*8f0ba417SAndroid Build Coastguard Worker
268*8f0ba417SAndroid Build Coastguard Worker auto result = StderrOutputGenerator(ts, pid, tid, ERROR, tag, file, line, message);
269*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(expected, result);
270*8f0ba417SAndroid Build Coastguard Worker }
271*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,StderrOutputGenerator_Basic)272*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, StderrOutputGenerator_Basic) {
273*8f0ba417SAndroid Build Coastguard Worker TestStderrOutputGenerator(nullptr, nullptr, 0, "simple message",
274*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E nullptr : simple message\n");
275*8f0ba417SAndroid Build Coastguard Worker TestStderrOutputGenerator("tag", nullptr, 0, "simple message",
276*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : simple message\n");
277*8f0ba417SAndroid Build Coastguard Worker TestStderrOutputGenerator(
278*8f0ba417SAndroid Build Coastguard Worker "tag", "/path/to/some/file", 0, "simple message",
279*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : /path/to/some/file:0 simple message\n");
280*8f0ba417SAndroid Build Coastguard Worker }
281*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,StderrOutputGenerator_NewlineTagAndFile)282*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, StderrOutputGenerator_NewlineTagAndFile) {
283*8f0ba417SAndroid Build Coastguard Worker TestStderrOutputGenerator("tag\n\n", nullptr, 0, "simple message",
284*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag\n\n : simple message\n");
285*8f0ba417SAndroid Build Coastguard Worker TestStderrOutputGenerator(
286*8f0ba417SAndroid Build Coastguard Worker "tag", "/path/to/some/file\n\n", 0, "simple message",
287*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : /path/to/some/file\n\n:0 simple message\n");
288*8f0ba417SAndroid Build Coastguard Worker }
289*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,StderrOutputGenerator_TrailingNewLine)290*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, StderrOutputGenerator_TrailingNewLine) {
291*8f0ba417SAndroid Build Coastguard Worker TestStderrOutputGenerator("tag", nullptr, 0, "simple message\n",
292*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : simple message\n"
293*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : \n");
294*8f0ba417SAndroid Build Coastguard Worker }
295*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,StderrOutputGenerator_MultiLine)296*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, StderrOutputGenerator_MultiLine) {
297*8f0ba417SAndroid Build Coastguard Worker const char* expected_result =
298*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : simple message\n"
299*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : \n"
300*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : \n"
301*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : another message \n"
302*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : \n"
303*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : final message \n"
304*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : \n"
305*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : \n"
306*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : \n";
307*8f0ba417SAndroid Build Coastguard Worker
308*8f0ba417SAndroid Build Coastguard Worker TestStderrOutputGenerator("tag", nullptr, 0,
309*8f0ba417SAndroid Build Coastguard Worker "simple message\n\n\nanother message \n\n final message \n\n\n",
310*8f0ba417SAndroid Build Coastguard Worker expected_result);
311*8f0ba417SAndroid Build Coastguard Worker }
312*8f0ba417SAndroid Build Coastguard Worker
TEST(logging_splitters,StderrOutputGenerator_MultiLineLong)313*8f0ba417SAndroid Build Coastguard Worker TEST(logging_splitters, StderrOutputGenerator_MultiLineLong) {
314*8f0ba417SAndroid Build Coastguard Worker auto long_string_a = std::string(4000, 'a');
315*8f0ba417SAndroid Build Coastguard Worker auto long_string_b = std::string(4000, 'b');
316*8f0ba417SAndroid Build Coastguard Worker
317*8f0ba417SAndroid Build Coastguard Worker auto message = long_string_a + '\n' + long_string_b;
318*8f0ba417SAndroid Build Coastguard Worker auto expected_result = "01-01 00:00:00.000 1234 4321 E tag : " + long_string_a + '\n' +
319*8f0ba417SAndroid Build Coastguard Worker "01-01 00:00:00.000 1234 4321 E tag : " + long_string_b + '\n';
320*8f0ba417SAndroid Build Coastguard Worker TestStderrOutputGenerator("tag", nullptr, 0, message.c_str(), expected_result);
321*8f0ba417SAndroid Build Coastguard Worker }
322*8f0ba417SAndroid Build Coastguard Worker
323*8f0ba417SAndroid Build Coastguard Worker } // namespace base
324*8f0ba417SAndroid Build Coastguard Worker } // namespace android
325