1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <array>
17 #include <cstdlib>
18 #include <ctime>
19 #include <iostream>
20 #include <sstream>
21 #include <string>
22
23 #include <gtest/gtest.h>
24 #include <hilog_common.h>
25
26 #include "hilog_base/log_base.h"
27
28 #undef LOG_DOMAIN
29 #define LOG_DOMAIN 0xD002D00
30
31 #undef LOG_TAG
32 #define LOG_TAG "HILOGBASETEST"
33
34 using namespace testing::ext;
35
36 namespace OHOS {
37 namespace HiviewDFX {
38 namespace HiLogBaseTest {
39 static constexpr unsigned int SOME_LOGS = 10;
40 static constexpr unsigned int MORE_LOGS = 100;
41 static constexpr unsigned int SHORT_LOG = 16;
42 static constexpr unsigned int LONG_LOG = 1000;
43 static constexpr unsigned int VERY_LONG_LOG = 2048;
44
45 enum LogInterfaceType {
46 DEBUG_METHOD = 0,
47 INFO_METHOD = 1,
48 WARN_METHOD = 2,
49 ERROR_METHOD = 3,
50 FATAL_METHOD = 4,
51 METHODS_NUMBER = 5,
52 };
53
54 using LogMethodFunc = std::function<void(const std::string &msg)>;
55
56 static const std::array<std::string, METHODS_NUMBER> METHOD_NAMES = {
57 "Debug", "Info", "Warn", "Error", "Fatal"
58 };
59
60 static const std::array<LogMethodFunc, METHODS_NUMBER> LOG_C_METHODS = {
__anon83c8caff0102() 61 [] (const std::string &msg) {
62 HILOG_BASE_DEBUG(LOG_CORE, "%{public}s", msg.c_str());
63 },
__anon83c8caff0202() 64 [] (const std::string &msg) {
65 HILOG_BASE_INFO(LOG_CORE, "%{public}s", msg.c_str());
66 },
__anon83c8caff0302() 67 [] (const std::string &msg) {
68 HILOG_BASE_WARN(LOG_CORE, "%{public}s", msg.c_str());
69 },
__anon83c8caff0402() 70 [] (const std::string &msg) {
71 HILOG_BASE_ERROR(LOG_CORE, "%{public}s", msg.c_str());
72 },
__anon83c8caff0502() 73 [] (const std::string &msg) {
74 HILOG_BASE_FATAL(LOG_CORE, "%{public}s", msg.c_str());
75 },
76 };
77
PopenToString(const std::string & command)78 static std::string PopenToString(const std::string &command)
79 {
80 std::string str;
81 constexpr int bufferSize = 1024;
82 FILE *fp = popen(command.c_str(), "re");
83 if (fp != nullptr) {
84 char buf[bufferSize] = {0};
85 size_t n = fread(buf, 1, sizeof(buf), fp);
86 while (n > 0) {
87 str.append(buf, n);
88 n = fread(buf, 1, sizeof(buf), fp);
89 }
90 pclose(fp);
91 }
92 return str;
93 }
94
95 class HiLogBaseNDKTest : public testing::Test {
96 public:
97 static void SetUpTestCase();
TearDownTestCase()98 static void TearDownTestCase() {}
99 void SetUp();
TearDown()100 void TearDown() {}
101 };
102
SetUpTestCase()103 void HiLogBaseNDKTest::SetUpTestCase()
104 {
105 (void)PopenToString("hilog -Q pidoff");
106 (void)PopenToString("hilog -Q domainoff");
107 }
108
SetUp()109 void HiLogBaseNDKTest::SetUp()
110 {
111 (void)PopenToString("hilog -r");
112 }
113
RandomStringGenerator(uint32_t logLen=16)114 static std::string RandomStringGenerator(uint32_t logLen = 16)
115 {
116 std::string str;
117 for (uint32_t i = 0; i < logLen; ++i) {
118 char newChar = rand() % ('z' - 'a') + 'a';
119 str.append(1, newChar);
120 }
121 return str;
122 }
123
HiLogWriteTest(LogMethodFunc loggingMethod,uint32_t logCount,uint32_t logLen,bool isDebug)124 static void HiLogWriteTest(LogMethodFunc loggingMethod, uint32_t logCount, uint32_t logLen, bool isDebug)
125 {
126 std::string logMsg(RandomStringGenerator(logLen));
127 for (uint32_t i = 0; i < logCount; ++i) {
128 loggingMethod(logMsg + std::to_string(i));
129 }
130 if (logMsg.length() > MAX_LOG_LEN-1) {
131 logMsg = logMsg.substr(0, MAX_LOG_LEN-1);
132 }
133 usleep(1000); /* 1000: sleep 1 ms */
134 std::string logMsgs = PopenToString("/system/bin/hilog -x");
135 uint32_t realCount = 0;
136 std::stringstream ss(logMsgs);
137 std::string str;
138 while (!ss.eof()) {
139 getline(ss, str);
140 if (str.find(logMsg) != std::string::npos) {
141 ++realCount;
142 }
143 }
144 uint32_t allowedLeastLogCount = logCount - logCount * 1 / 10; /* 1 / 10: loss rate less than 10% */
145 if (isDebug) {
146 allowedLeastLogCount = 0; /* 0: debug log is allowed to be closed */
147 }
148 EXPECT_GE(realCount, allowedLeastLogCount);
149 }
150
151 HWTEST_F(HiLogBaseNDKTest, SomeLogs, TestSize.Level1)
152 {
153 for(uint32_t i = 0; i < METHODS_NUMBER; ++i) {
154 std::cout << "Starting " << METHOD_NAMES[i] << " test\n";
155 HiLogWriteTest(LOG_C_METHODS[i], SOME_LOGS, SHORT_LOG, i == DEBUG_METHOD);
156 }
157 }
158
159 HWTEST_F(HiLogBaseNDKTest, MoreLogs, TestSize.Level1)
160 {
161 for(uint32_t i = 0; i < METHODS_NUMBER; ++i) {
162 std::cout << "Starting " << METHOD_NAMES[i] << " test\n";
163 HiLogWriteTest(LOG_C_METHODS[i], MORE_LOGS, SHORT_LOG, i == DEBUG_METHOD);
164 }
165 }
166
167 HWTEST_F(HiLogBaseNDKTest, LongLogs, TestSize.Level1)
168 {
169 for(uint32_t i = 0; i < METHODS_NUMBER; ++i) {
170 std::cout << "Starting " << METHOD_NAMES[i] << " test\n";
171 HiLogWriteTest(LOG_C_METHODS[i], 5, LONG_LOG, i == DEBUG_METHOD);
172 }
173 }
174
175 HWTEST_F(HiLogBaseNDKTest, VeryLongLogs, TestSize.Level1)
176 {
177 for(uint32_t i = 0; i < METHODS_NUMBER; ++i) {
178 std::cout << "Starting " << METHOD_NAMES[i] << " test\n";
179 HiLogWriteTest(LOG_C_METHODS[i], 5, VERY_LONG_LOG, i == DEBUG_METHOD);
180 }
181 }
182
183 HWTEST_F(HiLogBaseNDKTest, MemAllocTouch1, TestSize.Level1)
184 {
185 #undef TEXT_TO_CHECK
186 #define TEXT_TO_CHECK "Float potential mem alloc"
187 HILOG_BASE_ERROR(LOG_CORE, TEXT_TO_CHECK " %{public}515.2f", 123.3);
188 usleep(1000); /* 1000: sleep 1 ms */
189 std::string logMsgs = PopenToString("/system/bin/hilog -x");
190 uint32_t realCount = 0;
191 std::stringstream ss(logMsgs);
192 std::string str;
193 while (!ss.eof()) {
194 getline(ss, str);
195 if (str.find(TEXT_TO_CHECK) != std::string::npos) {
196 ++realCount;
197 }
198 }
199
200 EXPECT_EQ(realCount, 1);
201 }
202
203 HWTEST_F(HiLogBaseNDKTest, MemAllocTouch2, TestSize.Level1)
204 {
205 #undef TEXT_TO_CHECK
206 #define TEXT_TO_CHECK "Float potential mem alloc"
207 HILOG_BASE_ERROR(LOG_CORE, TEXT_TO_CHECK " %{public}000000005.00000002f", 123.3);
208 usleep(1000); /* 1000: sleep 1 ms */
209 std::string logMsgs = PopenToString("/system/bin/hilog -x");
210 uint32_t realCount = 0;
211 std::stringstream ss(logMsgs);
212 std::string str;
213 while (!ss.eof()) {
214 getline(ss, str);
215 if (str.find(TEXT_TO_CHECK) != std::string::npos) {
216 ++realCount;
217 }
218 }
219
220 EXPECT_EQ(realCount, 1);
221 }
222
223 HWTEST_F(HiLogBaseNDKTest, IsLoggable, TestSize.Level1)
224 {
225 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, LOG_TAG, LOG_DEBUG));
226 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, LOG_TAG, LOG_INFO));
227 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, LOG_TAG, LOG_WARN));
228 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, LOG_TAG, LOG_ERROR));
229 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, LOG_TAG, LOG_FATAL));
230 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, "abc", LOG_WARN));
231 EXPECT_FALSE(HiLogBaseIsLoggable(0xD002D00, "abc", LOG_LEVEL_MIN));
232 }
233
234 } // namespace HiLogTest
235 } // namespace HiviewDFX
236 } // namespace OHOS
237