1*598139dcSAndroid Build Coastguard Worker /*
2*598139dcSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*598139dcSAndroid Build Coastguard Worker *
4*598139dcSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*598139dcSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*598139dcSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*598139dcSAndroid Build Coastguard Worker *
8*598139dcSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*598139dcSAndroid Build Coastguard Worker *
10*598139dcSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*598139dcSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*598139dcSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*598139dcSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*598139dcSAndroid Build Coastguard Worker * limitations under the License.
15*598139dcSAndroid Build Coastguard Worker */
16*598139dcSAndroid Build Coastguard Worker
17*598139dcSAndroid Build Coastguard Worker #include <log/logprint.h>
18*598139dcSAndroid Build Coastguard Worker
19*598139dcSAndroid Build Coastguard Worker #include <string>
20*598139dcSAndroid Build Coastguard Worker
21*598139dcSAndroid Build Coastguard Worker #include <gtest/gtest.h>
22*598139dcSAndroid Build Coastguard Worker
23*598139dcSAndroid Build Coastguard Worker #include <log/log_read.h>
24*598139dcSAndroid Build Coastguard Worker
25*598139dcSAndroid Build Coastguard Worker using namespace std::string_literals;
26*598139dcSAndroid Build Coastguard Worker
27*598139dcSAndroid Build Coastguard Worker size_t convertPrintable(char*, const char*, size_t);
28*598139dcSAndroid Build Coastguard Worker
TEST(liblog,convertPrintable_ascii)29*598139dcSAndroid Build Coastguard Worker TEST(liblog, convertPrintable_ascii) {
30*598139dcSAndroid Build Coastguard Worker auto input = "easy string, output same";
31*598139dcSAndroid Build Coastguard Worker auto output_size = convertPrintable(nullptr, input, strlen(input));
32*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(output_size, strlen(input));
33*598139dcSAndroid Build Coastguard Worker
34*598139dcSAndroid Build Coastguard Worker char output[output_size + 1];
35*598139dcSAndroid Build Coastguard Worker memset(output, 'x', sizeof(output));
36*598139dcSAndroid Build Coastguard Worker
37*598139dcSAndroid Build Coastguard Worker output_size = convertPrintable(output, input, strlen(input));
38*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(output_size, strlen(input));
39*598139dcSAndroid Build Coastguard Worker EXPECT_STREQ(input, output);
40*598139dcSAndroid Build Coastguard Worker }
41*598139dcSAndroid Build Coastguard Worker
TEST(liblog,convertPrintable_escapes)42*598139dcSAndroid Build Coastguard Worker TEST(liblog, convertPrintable_escapes) {
43*598139dcSAndroid Build Coastguard Worker std::string input = "escape\x00\x7f\a\b\t\n\v\f\r\\"s;
44*598139dcSAndroid Build Coastguard Worker // We want to test escaping of ASCII NUL at the end too.
45*598139dcSAndroid Build Coastguard Worker auto input_size = input.size() + 1;
46*598139dcSAndroid Build Coastguard Worker
47*598139dcSAndroid Build Coastguard Worker // Note that \t is not escaped.
48*598139dcSAndroid Build Coastguard Worker std::string expected_output = "escape\\x00\\x7F\\a\\b\t\\n\\v\\f\\r\\\\\\x00"s;
49*598139dcSAndroid Build Coastguard Worker auto expected_output_size = expected_output.size();
50*598139dcSAndroid Build Coastguard Worker
51*598139dcSAndroid Build Coastguard Worker auto output_size = convertPrintable(nullptr, input.c_str(), input_size);
52*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(output_size, expected_output_size) << input_size;
53*598139dcSAndroid Build Coastguard Worker
54*598139dcSAndroid Build Coastguard Worker char output[output_size + 1];
55*598139dcSAndroid Build Coastguard Worker memset(output, 'x', sizeof(output));
56*598139dcSAndroid Build Coastguard Worker
57*598139dcSAndroid Build Coastguard Worker output_size = convertPrintable(output, input.c_str(), input_size);
58*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(output_size, expected_output_size);
59*598139dcSAndroid Build Coastguard Worker EXPECT_STREQ(expected_output.c_str(), output);
60*598139dcSAndroid Build Coastguard Worker }
61*598139dcSAndroid Build Coastguard Worker
TEST(liblog,convertPrintable_validutf8)62*598139dcSAndroid Build Coastguard Worker TEST(liblog, convertPrintable_validutf8) {
63*598139dcSAndroid Build Coastguard Worker setlocale(LC_ALL, "C.UTF-8");
64*598139dcSAndroid Build Coastguard Worker
65*598139dcSAndroid Build Coastguard Worker const char* input = "¢ह€";
66*598139dcSAndroid Build Coastguard Worker size_t output_size = convertPrintable(nullptr, input, strlen(input));
67*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(output_size, strlen(input));
68*598139dcSAndroid Build Coastguard Worker
69*598139dcSAndroid Build Coastguard Worker char output[output_size + 1];
70*598139dcSAndroid Build Coastguard Worker memset(output, 'x', sizeof(output));
71*598139dcSAndroid Build Coastguard Worker
72*598139dcSAndroid Build Coastguard Worker output_size = convertPrintable(output, input, strlen(input));
73*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(output_size, strlen(input));
74*598139dcSAndroid Build Coastguard Worker EXPECT_STREQ(input, output);
75*598139dcSAndroid Build Coastguard Worker }
76*598139dcSAndroid Build Coastguard Worker
TEST(liblog,convertPrintable_invalidutf8)77*598139dcSAndroid Build Coastguard Worker TEST(liblog, convertPrintable_invalidutf8) {
78*598139dcSAndroid Build Coastguard Worker auto input = "\x80\xC2\x01\xE0\xA4\x06\xE0\x06\xF0\x90\x8D\x06\xF0\x90\x06\xF0\x0E";
79*598139dcSAndroid Build Coastguard Worker auto expected_output =
80*598139dcSAndroid Build Coastguard Worker "\\x80\\xC2\\x01\\xE0\\xA4\\x06\\xE0\\x06\\xF0\\x90\\x8D\\x06\\xF0\\x90\\x06\\xF0\\x0E";
81*598139dcSAndroid Build Coastguard Worker auto output_size = convertPrintable(nullptr, input, strlen(input));
82*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(output_size, strlen(expected_output));
83*598139dcSAndroid Build Coastguard Worker
84*598139dcSAndroid Build Coastguard Worker char output[output_size + 1];
85*598139dcSAndroid Build Coastguard Worker memset(output, 'x', sizeof(output));
86*598139dcSAndroid Build Coastguard Worker
87*598139dcSAndroid Build Coastguard Worker output_size = convertPrintable(output, input, strlen(input));
88*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(output_size, strlen(expected_output));
89*598139dcSAndroid Build Coastguard Worker EXPECT_STREQ(expected_output, output);
90*598139dcSAndroid Build Coastguard Worker }
91*598139dcSAndroid Build Coastguard Worker
TEST(liblog,convertPrintable_mixed)92*598139dcSAndroid Build Coastguard Worker TEST(liblog, convertPrintable_mixed) {
93*598139dcSAndroid Build Coastguard Worker setlocale(LC_ALL, "C.UTF-8");
94*598139dcSAndroid Build Coastguard Worker
95*598139dcSAndroid Build Coastguard Worker const char* input =
96*598139dcSAndroid Build Coastguard Worker "\x80\xC2¢ह€\x01\xE0\xA4\x06¢ह€\xE0\x06\a\b\xF0\x90¢ह€\x8D\x06\xF0\t\t\x90\x06\xF0\x0E";
97*598139dcSAndroid Build Coastguard Worker const char* expected_output =
98*598139dcSAndroid Build Coastguard Worker "\\x80\\xC2¢ह€\\x01\\xE0\\xA4\\x06¢ह€\\xE0\\x06\\a\\b\\xF0\\x90¢ह€\\x8D\\x06\\xF0\t\t"
99*598139dcSAndroid Build Coastguard Worker "\\x90\\x06\\xF0\\x0E";
100*598139dcSAndroid Build Coastguard Worker size_t output_size = convertPrintable(nullptr, input, strlen(input));
101*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(output_size, strlen(expected_output));
102*598139dcSAndroid Build Coastguard Worker
103*598139dcSAndroid Build Coastguard Worker char output[output_size + 1];
104*598139dcSAndroid Build Coastguard Worker memset(output, 'x', sizeof(output));
105*598139dcSAndroid Build Coastguard Worker
106*598139dcSAndroid Build Coastguard Worker output_size = convertPrintable(output, input, strlen(input));
107*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(output_size, strlen(expected_output));
108*598139dcSAndroid Build Coastguard Worker EXPECT_STREQ(expected_output, output);
109*598139dcSAndroid Build Coastguard Worker }
110*598139dcSAndroid Build Coastguard Worker
TEST(liblog,log_print_different_header_size)111*598139dcSAndroid Build Coastguard Worker TEST(liblog, log_print_different_header_size) {
112*598139dcSAndroid Build Coastguard Worker constexpr int32_t kPid = 123;
113*598139dcSAndroid Build Coastguard Worker constexpr uint32_t kTid = 456;
114*598139dcSAndroid Build Coastguard Worker constexpr uint32_t kSec = 1000;
115*598139dcSAndroid Build Coastguard Worker constexpr uint32_t kNsec = 999;
116*598139dcSAndroid Build Coastguard Worker constexpr uint32_t kLid = LOG_ID_MAIN;
117*598139dcSAndroid Build Coastguard Worker constexpr uint32_t kUid = 987;
118*598139dcSAndroid Build Coastguard Worker constexpr char kPriority = ANDROID_LOG_ERROR;
119*598139dcSAndroid Build Coastguard Worker
120*598139dcSAndroid Build Coastguard Worker auto create_buf = [](char* buf, size_t len, uint16_t hdr_size) {
121*598139dcSAndroid Build Coastguard Worker memset(buf, 0, len);
122*598139dcSAndroid Build Coastguard Worker logger_entry* header = reinterpret_cast<logger_entry*>(buf);
123*598139dcSAndroid Build Coastguard Worker header->hdr_size = hdr_size;
124*598139dcSAndroid Build Coastguard Worker header->pid = kPid;
125*598139dcSAndroid Build Coastguard Worker header->tid = kTid;
126*598139dcSAndroid Build Coastguard Worker header->sec = kSec;
127*598139dcSAndroid Build Coastguard Worker header->nsec = kNsec;
128*598139dcSAndroid Build Coastguard Worker header->lid = kLid;
129*598139dcSAndroid Build Coastguard Worker header->uid = kUid;
130*598139dcSAndroid Build Coastguard Worker char* message = buf + header->hdr_size;
131*598139dcSAndroid Build Coastguard Worker uint16_t message_len = 0;
132*598139dcSAndroid Build Coastguard Worker message[message_len++] = kPriority;
133*598139dcSAndroid Build Coastguard Worker message[message_len++] = 'T';
134*598139dcSAndroid Build Coastguard Worker message[message_len++] = 'a';
135*598139dcSAndroid Build Coastguard Worker message[message_len++] = 'g';
136*598139dcSAndroid Build Coastguard Worker message[message_len++] = '\0';
137*598139dcSAndroid Build Coastguard Worker message[message_len++] = 'm';
138*598139dcSAndroid Build Coastguard Worker message[message_len++] = 's';
139*598139dcSAndroid Build Coastguard Worker message[message_len++] = 'g';
140*598139dcSAndroid Build Coastguard Worker message[message_len++] = '!';
141*598139dcSAndroid Build Coastguard Worker message[message_len++] = '\0';
142*598139dcSAndroid Build Coastguard Worker header->len = message_len;
143*598139dcSAndroid Build Coastguard Worker };
144*598139dcSAndroid Build Coastguard Worker
145*598139dcSAndroid Build Coastguard Worker auto check_entry = [&](const AndroidLogEntry& entry) {
146*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(kSec, static_cast<uint32_t>(entry.tv_sec));
147*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(kNsec, static_cast<uint32_t>(entry.tv_nsec));
148*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(kPriority, entry.priority);
149*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(kUid, static_cast<uint32_t>(entry.uid));
150*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(kPid, entry.pid);
151*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(kTid, static_cast<uint32_t>(entry.tid));
152*598139dcSAndroid Build Coastguard Worker EXPECT_STREQ("Tag", entry.tag);
153*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(4U, entry.tagLen); // Apparently taglen includes the nullptr?
154*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(4U, entry.messageLen);
155*598139dcSAndroid Build Coastguard Worker EXPECT_STREQ("msg!", entry.message);
156*598139dcSAndroid Build Coastguard Worker };
157*598139dcSAndroid Build Coastguard Worker alignas(logger_entry) char buf[LOGGER_ENTRY_MAX_LEN];
158*598139dcSAndroid Build Coastguard Worker create_buf(buf, sizeof(buf), sizeof(logger_entry));
159*598139dcSAndroid Build Coastguard Worker
160*598139dcSAndroid Build Coastguard Worker AndroidLogEntry entry_normal_size;
161*598139dcSAndroid Build Coastguard Worker ASSERT_EQ(0,
162*598139dcSAndroid Build Coastguard Worker android_log_processLogBuffer(reinterpret_cast<logger_entry*>(buf), &entry_normal_size));
163*598139dcSAndroid Build Coastguard Worker check_entry(entry_normal_size);
164*598139dcSAndroid Build Coastguard Worker
165*598139dcSAndroid Build Coastguard Worker create_buf(buf, sizeof(buf), sizeof(logger_entry) + 3);
166*598139dcSAndroid Build Coastguard Worker AndroidLogEntry entry_odd_size;
167*598139dcSAndroid Build Coastguard Worker ASSERT_EQ(0, android_log_processLogBuffer(reinterpret_cast<logger_entry*>(buf), &entry_odd_size));
168*598139dcSAndroid Build Coastguard Worker check_entry(entry_odd_size);
169*598139dcSAndroid Build Coastguard Worker }
170