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 = {
__anonae3c608c0102() 61 [] (const std::string &msg) {
62 HILOG_BASE_DEBUG(LOG_CORE, "%{public}s", msg.c_str());
63 },
__anonae3c608c0202() 64 [] (const std::string &msg) {
65 HILOG_BASE_INFO(LOG_CORE, "%{public}s", msg.c_str());
66 },
__anonae3c608c0302() 67 [] (const std::string &msg) {
68 HILOG_BASE_WARN(LOG_CORE, "%{public}s", msg.c_str());
69 },
__anonae3c608c0402() 70 [] (const std::string &msg) {
71 HILOG_BASE_ERROR(LOG_CORE, "%{public}s", msg.c_str());
72 },
__anonae3c608c0502() 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:
SetUpTestCase()97 static void SetUpTestCase() {};
TearDownTestCase()98 static void TearDownTestCase() {};
99 void SetUp();
TearDown()100 void TearDown() {};
101 };
102
SetUp()103 void HiLogBaseNDKTest::SetUp()
104 {
105 PopenToString("hilog -r");
106 }
107
RandomStringGenerator(uint32_t logLen=16)108 static std::string RandomStringGenerator(uint32_t logLen = 16)
109 {
110 std::string str;
111 for (uint32_t i = 0; i < logLen; ++i) {
112 char newChar = rand() % ('z' - 'a') + 'a';
113 str.append(1, newChar);
114 }
115 return str;
116 }
117
HiLogWriteTest(LogMethodFunc loggingMethod,uint32_t logCount,uint32_t logLen,bool isDebug)118 static void HiLogWriteTest(LogMethodFunc loggingMethod, uint32_t logCount, uint32_t logLen, bool isDebug)
119 {
120 std::string logMsg(RandomStringGenerator(logLen));
121 for (uint32_t i = 0; i < logCount; ++i) {
122 loggingMethod(logMsg + std::to_string(i));
123 }
124 if (logMsg.length() > MAX_LOG_LEN-1) {
125 logMsg = logMsg.substr(0, MAX_LOG_LEN-1);
126 }
127 usleep(1000); /* 1000: sleep 1 ms */
128 std::string logMsgs = PopenToString("/system/bin/hilog -x");
129 uint32_t realCount = 0;
130 std::stringstream ss(logMsgs);
131 std::string str;
132 while (!ss.eof()) {
133 getline(ss, str);
134 if (str.find(logMsg) != std::string::npos) {
135 ++realCount;
136 }
137 }
138 uint32_t allowedLeastLogCount = logCount - logCount * 1 / 10; /* 1 / 10: loss rate less than 10% */
139 if (isDebug) {
140 allowedLeastLogCount = 0; /* 0: debug log is allowed to be closed */
141 }
142 EXPECT_GE(realCount, allowedLeastLogCount);
143 }
144
145 HWTEST_F(HiLogBaseNDKTest, SomeLogs, TestSize.Level1)
146 {
147 for(uint32_t i = 0; i < METHODS_NUMBER; ++i) {
148 std::cout << "Starting " << METHOD_NAMES[i] << " test\n";
149 HiLogWriteTest(LOG_C_METHODS[i], SOME_LOGS, SHORT_LOG, i == DEBUG_METHOD);
150 }
151 }
152
153 HWTEST_F(HiLogBaseNDKTest, MoreLogs, TestSize.Level1)
154 {
155 for(uint32_t i = 0; i < METHODS_NUMBER; ++i) {
156 std::cout << "Starting " << METHOD_NAMES[i] << " test\n";
157 HiLogWriteTest(LOG_C_METHODS[i], MORE_LOGS, SHORT_LOG, i == DEBUG_METHOD);
158 }
159 }
160
161 HWTEST_F(HiLogBaseNDKTest, LongLogs, TestSize.Level1)
162 {
163 for(uint32_t i = 0; i < METHODS_NUMBER; ++i) {
164 std::cout << "Starting " << METHOD_NAMES[i] << " test\n";
165 HiLogWriteTest(LOG_C_METHODS[i], 5, LONG_LOG, i == DEBUG_METHOD);
166 }
167 }
168
169 HWTEST_F(HiLogBaseNDKTest, VeryLongLogs, TestSize.Level1)
170 {
171 for(uint32_t i = 0; i < METHODS_NUMBER; ++i) {
172 std::cout << "Starting " << METHOD_NAMES[i] << " test\n";
173 HiLogWriteTest(LOG_C_METHODS[i], 5, VERY_LONG_LOG, i == DEBUG_METHOD);
174 }
175 }
176
177 HWTEST_F(HiLogBaseNDKTest, MemAllocTouch1, TestSize.Level1)
178 {
179 #undef TEXT_TO_CHECK
180 #define TEXT_TO_CHECK "Float potential mem alloc"
181 HILOG_BASE_ERROR(LOG_CORE, TEXT_TO_CHECK " %{public}515.2f", 123.3);
182 usleep(1000); /* 1000: sleep 1 ms */
183 std::string logMsgs = PopenToString("/system/bin/hilog -x");
184 uint32_t realCount = 0;
185 std::stringstream ss(logMsgs);
186 std::string str;
187 while (!ss.eof()) {
188 getline(ss, str);
189 if (str.find(TEXT_TO_CHECK) != std::string::npos) {
190 ++realCount;
191 }
192 }
193
194 EXPECT_EQ(realCount, 1);
195 }
196
197 HWTEST_F(HiLogBaseNDKTest, MemAllocTouch2, TestSize.Level1)
198 {
199 #undef TEXT_TO_CHECK
200 #define TEXT_TO_CHECK "Float potential mem alloc"
201 HILOG_BASE_ERROR(LOG_CORE, TEXT_TO_CHECK " %{public}000000005.00000002f", 123.3);
202 usleep(1000); /* 1000: sleep 1 ms */
203 std::string logMsgs = PopenToString("/system/bin/hilog -x");
204 uint32_t realCount = 0;
205 std::stringstream ss(logMsgs);
206 std::string str;
207 while (!ss.eof()) {
208 getline(ss, str);
209 if (str.find(TEXT_TO_CHECK) != std::string::npos) {
210 ++realCount;
211 }
212 }
213
214 EXPECT_EQ(realCount, 1);
215 }
216
217 HWTEST_F(HiLogBaseNDKTest, IsLoggable, TestSize.Level1)
218 {
219 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, LOG_TAG, LOG_DEBUG));
220 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, LOG_TAG, LOG_INFO));
221 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, LOG_TAG, LOG_WARN));
222 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, LOG_TAG, LOG_ERROR));
223 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, LOG_TAG, LOG_FATAL));
224 EXPECT_TRUE(HiLogBaseIsLoggable(0xD002D00, "abc", LOG_WARN));
225 }
226
227 } // namespace HiLogTest
228 } // namespace HiviewDFX
229 } // namespace OHOS
230