1 /*
2  * Copyright (c) 2022 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 #include "hilogtool_test.h"
16 #include "hilog/log_c.h"
17 #include <dirent.h>
18 #include <log_utils.h>
19 #include <properties.h>
20 #include <hilog_common.h>
21 #include <list>
22 #include <regex>
23 
24 using namespace std;
25 using namespace testing::ext;
26 using namespace OHOS;
27 using namespace OHOS::HiviewDFX;
28 
GetCmdLinesFromPopen(const std::string & cmd)29 static int GetCmdLinesFromPopen(const std::string& cmd)
30 {
31     if (cmd.empty()) {
32         return 0;
33     }
34     FILE* fp = popen(cmd.c_str(), "r");
35     if (fp == nullptr) {
36         return 0;
37     }
38     int ret = 0;
39     char* buffer = nullptr;
40     size_t len = 0;
41     while (getline(&buffer, &len, fp) != -1) {
42         ret++;
43     }
44     if (buffer != nullptr) {
45         free(buffer);
46         buffer = nullptr;
47     }
48     pclose(fp);
49     return ret;
50 }
51 
GetCmdResultFromPopen(const std::string & cmd)52 static std::string GetCmdResultFromPopen(const std::string& cmd)
53 {
54     if (cmd.empty()) {
55         return "";
56     }
57     FILE* fp = popen(cmd.c_str(), "r");
58     if (fp == nullptr) {
59         return "";
60     }
61     std::string ret = "";
62     char* buffer = nullptr;
63     size_t len = 0;
64     while (getline(&buffer, &len, fp) != -1) {
65         std::string line = buffer;
66         ret += line;
67     }
68     if (buffer != nullptr) {
69         free(buffer);
70         buffer = nullptr;
71     }
72     pclose(fp);
73     return ret;
74 }
75 
IsExistInCmdResult(const std::string & cmd,const std::string & str)76 static bool IsExistInCmdResult(const std::string &cmd, const std::string &str)
77 {
78     if (cmd.empty()) {
79         return false;
80     }
81     FILE* fp = popen(cmd.c_str(), "r");
82     if (fp == nullptr) {
83         return false;
84     }
85     bool ret = false;
86     char* buffer = nullptr;
87     size_t len = 0;
88     while (getline(&buffer, &len, fp) != -1) {
89         std::string line = buffer;
90         if (line.find(str) != string::npos) {
91             ret = true;
92             break;
93         }
94     }
95     if (buffer != nullptr) {
96         free(buffer);
97         buffer = nullptr;
98     }
99     pclose(fp);
100     return ret;
101 }
102 
TearDownTestCase()103 void HilogToolTest::TearDownTestCase()
104 {
105     (void)GetCmdResultFromPopen("hilog -b I");
106     (void)GetCmdResultFromPopen("hilog -G 256K");
107     (void)GetCmdResultFromPopen("hilog -w stop");
108     (void)GetCmdResultFromPopen("hilog -w start");
109 }
110 
111 namespace {
112 const std::list<pair<string, string>> helperList = {
113     /* help cmd suffix, information key word */
114     {"", "Usage"},
115     {"query", "Query"},
116     {"clear", "Remove"},
117     {"buffer", "buffer"},
118     {"stats", "statistics"},
119     {"persist", "persistance"},
120     {"private", "privacy"},
121     {"kmsg", "kmsg"},
122     {"flowcontrol", "flow-control"},
123     {"baselevel", "baselevel"},
124     {"combo", "combination"},
125     {"domain", "domain"},
126 };
127 
128 /**
129  * @tc.name: Dfx_HilogToolTest_HelperTest_001
130  * @tc.desc: hilog help information.
131  * @tc.type: FUNC
132  */
133 HWTEST_F(HilogToolTest, HelperTest_001, TestSize.Level1)
134 {
135     /**
136      * @tc.steps: step1. show hilog help information.
137      * @tc.steps: step2. invalid cmd.
138      */
139     GTEST_LOG_(INFO) << "HelperTest_001: start.";
140     std::string prefix = "hilog -h ";
141     std::string cmd = "";
142     for (auto &it : helperList) {
143         cmd = prefix + it.first;
144         EXPECT_TRUE(IsExistInCmdResult(cmd, it.second));
145     }
146 
147     prefix = "hilog --help ";
148     for (auto &it : helperList) {
149         cmd = prefix + it.first;
150         EXPECT_TRUE(IsExistInCmdResult(cmd, it.second));
151     }
152 }
153 
154 /**
155  * @tc.name: Dfx_HilogToolTest_HandleTest_001
156  * @tc.desc: BaseLogLevelHandler.
157  * @tc.type: FUNC
158  */
159 HWTEST_F(HilogToolTest, HandleTest_001, TestSize.Level1)
160 {
161     /**
162      * @tc.steps: step1. set global log level to INFO.
163      * @tc.steps: step2. invalid log level.
164      */
165     GTEST_LOG_(INFO) << "HandleTest_001: start.";
166     std::string level = "I";
167     std::string cmd = "hilog -b " + level;
168     std::string str = "Set global log level to " + level + " successfully\n";
169     std::string query = "param get hilog.loggable.global";
170     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
171     EXPECT_EQ(GetCmdResultFromPopen(query), level + " \n");
172 
173     // stderr redirect to stdout
174     cmd = "hilog -b test_level 2>&1";
175     std::string errMsg = ErrorCode2Str(ERR_LOG_LEVEL_INVALID) + "\n";
176     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
177 }
178 
179 /**
180  * @tc.name: Dfx_HilogToolTest_HandleTest_002
181  * @tc.desc: DomainHandler.
182  * @tc.type: FUNC
183  */
184 HWTEST_F(HilogToolTest, HandleTest_002, TestSize.Level1)
185 {
186     /**
187      * @tc.steps: step1. set domain xxx log level to INFO.
188      * @tc.steps: step2. invaild domain.
189      */
190     GTEST_LOG_(INFO) << "HandleTest_002: start.";
191     uint32_t domain = 0xd002d00;
192     std::string level = "I";
193     std::string cmd = "hilog -b " + level + " -D " + Uint2HexStr(domain);
194     std::string str = "Set domain 0x" + Uint2HexStr(domain) + " log level to " + level + " successfully\n";
195     std::string query = "param get hilog.loggable.domain." + Uint2HexStr(domain);
196     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
197     EXPECT_EQ(GetCmdResultFromPopen(query), level + " \n");
198 
199     cmd = "hilog -D test_domain 2>&1";
200     std::string errMsg = ErrorCode2Str(ERR_INVALID_DOMAIN_STR) + "\n";
201     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
202 }
203 
204 /**
205  * @tc.name: Dfx_HilogToolTest_HandleTest_003
206  * @tc.desc: TagHandler.
207  * @tc.type: FUNC
208  */
209 HWTEST_F(HilogToolTest, HandleTest_003, TestSize.Level1)
210 {
211     /**
212      * @tc.steps: step1. set tag xxx log level to INFO.
213      * @tc.steps: step2. invalid tag.
214      */
215     GTEST_LOG_(INFO) << "HandleTest_003: start.";
216     std::string tag = "test";
217     std::string level = "I";
218     std::string cmd = "hilog -b " + level + " -T " + tag;
219     std::string str = "Set tag " +  tag + " log level to " + level + " successfully\n";
220     std::string query = "param get hilog.loggable.tag." + tag;
221     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
222     EXPECT_EQ(GetCmdResultFromPopen(query), level + " \n");
223 
224     cmd = "hilog -T abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 2>&1";
225     std::string errMsg = ErrorCode2Str(ERR_TAG_STR_TOO_LONG) + "\n";
226     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
227 }
228 
229 /**
230  * @tc.name: Dfx_HilogToolTest_HandleTest_004
231  * @tc.desc: BufferSizeSetHandler.
232  * @tc.type: FUNC
233  */
234 HWTEST_F(HilogToolTest, HandleTest_004, TestSize.Level1)
235 {
236     /**
237      * @tc.steps: step1. set app,init.core buffer size [valid].
238      * @tc.expected: step1. set app,init.core buffer size successfully.
239      * @tc.steps: step2. set app,init.core buffer size [invalid].
240      * @tc.expected: step2  set app,init.core buffer size failed.
241      * buffer size should be in range [64.0K, 512.0M].
242      * @tc.expected: step3  invalid buffer size str.
243      */
244     GTEST_LOG_(INFO) << "HandleTest_004: start.";
245     std::string cmd = "hilog -G 512K";
246     std::string str = "Set log type app buffer size to 512.0K successfully\n"
247         "Set log type init buffer size to 512.0K successfully\n"
248         "Set log type core buffer size to 512.0K successfully\n"
249         "Set log type only_prerelease buffer size to 512.0K successfully\n";
250     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
251 
252     cmd = "hilog -G 512G";
253     str = "failed";
254     EXPECT_TRUE(IsExistInCmdResult(cmd, str));
255 
256     std::string inValidStrCmd = "hilog -G test_buffersize 2>&1";
257     std::string errMsg = ErrorCode2Str(ERR_INVALID_SIZE_STR) + "\n";
258     EXPECT_EQ(GetCmdResultFromPopen(inValidStrCmd), errMsg);
259 }
260 
261 /**
262  * @tc.name: Dfx_HilogToolTest_HandleTest_005
263  * @tc.desc: BufferSizeGetHandler.
264  * @tc.type: FUNC
265  */
266 HWTEST_F(HilogToolTest, HandleTest_005, TestSize.Level1)
267 {
268     /**
269      * @tc.steps: step1. get app,init.core valid buffer size.
270      */
271     GTEST_LOG_(INFO) << "HandleTest_005: start.";
272     std::string cmd = "hilog -g";
273     std::string str = "Log type app buffer size is 512.0K\n"
274         "Log type init buffer size is 512.0K\n"
275         "Log type core buffer size is 512.0K\n"
276         "Log type only_prerelease buffer size is 512.0K\n";
277     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
278 }
279 
280 /**
281  * @tc.name: Dfx_HilogToolTest_HandleTest_006
282  * @tc.desc: KmsgFeatureSetHandler.
283  * @tc.type: FUNC
284  */
285 HWTEST_F(HilogToolTest, HandleTest_006, TestSize.Level1)
286 {
287     /**
288      * @tc.steps: step1. set hilogd storing kmsg log feature on.
289      * @tc.steps: step2. set hilogd storing kmsg log feature off.
290      * @tc.steps: step3. set hilogd storing kmsg log feature invalid.
291      */
292     GTEST_LOG_(INFO) << "HandleTest_006: start.";
293     std::string cmd = "hilog -k on";
294     std::string str = "Set hilogd storing kmsg log on successfully\n";
295     std::string query = "param get persist.sys.hilog.kmsg.on";
296     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
297     EXPECT_EQ(GetCmdResultFromPopen(query), "true \n");
298 
299     cmd = "hilog -k off";
300     str = "Set hilogd storing kmsg log off successfully\n";
301     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
302     EXPECT_EQ(GetCmdResultFromPopen(query), "false \n");
303 
304     cmd = "hilog -k test_feature 2>&1";
305     std::string errMsg = ErrorCode2Str(ERR_INVALID_ARGUMENT) + "\n";
306     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
307 }
308 
309 /**
310  * @tc.name: Dfx_HilogToolTest_HandleTest_007
311  * @tc.desc: PrivateFeatureSetHandler.
312  * @tc.type: FUNC
313  */
314 HWTEST_F(HilogToolTest, HandleTest_007, TestSize.Level1)
315 {
316     /**
317      * @tc.steps: step1. set hilog api privacy formatter feature on.
318      * @tc.steps: step2. set hilog api privacy formatter feature off.
319      * @tc.steps: step3. set hilog api privacy formatter feature invalid.
320      */
321     GTEST_LOG_(INFO) << "HandleTest_007: start.";
322     std::string cmd = "hilog -p on";
323     std::string str = "Set hilog privacy format on successfully\n";
324     std::string query = "param get hilog.private.on";
325     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
326     EXPECT_EQ(GetCmdResultFromPopen(query), "true \n");
327 
328     cmd = "hilog -p off";
329     str = "Set hilog privacy format off successfully\n";
330     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
331     EXPECT_EQ(GetCmdResultFromPopen(query), "false \n");
332 
333     cmd = "hilog -p test_feature 2>&1";
334     std::string errMsg = ErrorCode2Str(ERR_INVALID_ARGUMENT) + "\n";
335     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
336 }
337 
338 /**
339  * @tc.name: Dfx_HilogToolTest_HandleTest_008
340  * @tc.desc: FlowControlFeatureSetHandler.
341  * @tc.type: FUNC
342  */
343 HWTEST_F(HilogToolTest, HandleTest_008, TestSize.Level1)
344 {
345     /**
346      * @tc.steps: step1. set process flow control on.
347      * @tc.steps: step2. set process flow control off.
348      * @tc.steps: step3. set domain flow control on.
349      * @tc.steps: step4. set domain flow control off.
350      * @tc.steps: step5. invalid cmd.
351      */
352     GTEST_LOG_(INFO) << "HandleTest_008: start.";
353     std::string cmd = "hilog -Q pidon";
354     std::string str = "Set flow control by process to enabled, result: Success [CODE: 0]\n";
355     std::string query = "param get hilog.flowctrl.proc.on";
356     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
357     EXPECT_EQ(GetCmdResultFromPopen(query), "true \n");
358 
359     cmd = "hilog -Q pidoff";
360     str = "Set flow control by process to disabled, result: Success [CODE: 0]\n";
361     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
362     EXPECT_EQ(GetCmdResultFromPopen(query), "false \n");
363 
364     cmd = "hilog -Q domainon";
365     str = "Set flow control by domain to enabled, result: Success [CODE: 0]\n";
366     query = "param get hilog.flowctrl.domain.on";
367     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
368     EXPECT_EQ(GetCmdResultFromPopen(query), "true \n");
369 
370     cmd = "hilog -Q domainoff";
371     str = "Set flow control by domain to disabled, result: Success [CODE: 0]\n";
372     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
373     EXPECT_EQ(GetCmdResultFromPopen(query), "false \n");
374 
375     cmd = "hilog -Q test_cmd 2>&1";
376     std::string errMsg = ErrorCode2Str(ERR_INVALID_ARGUMENT) + "\n";
377     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
378 }
379 
380 /**
381  * @tc.name: Dfx_HilogToolTest_HandleTest_009
382  * @tc.desc: HeadHandler & TailHandler.
383  * @tc.type: FUNC
384  */
385 HWTEST_F(HilogToolTest, HandleTest_009, TestSize.Level1)
386 {
387     /**
388      * @tc.steps: step1. show n lines logs on head of buffer.
389      * @tc.steps: step2. show n lines logs on tail of buffer.
390      * @tc.steps: step3. invalid cmd.
391      */
392     GTEST_LOG_(INFO) << "HandleTest_009: start.";
393     int lines = 5;
394     std::string cmd = "hilog -a " + std::to_string(lines);
395     EXPECT_EQ(GetCmdLinesFromPopen(cmd), lines);
396 
397     cmd = "hilog -z " + std::to_string(lines);
398     EXPECT_EQ(GetCmdLinesFromPopen(cmd), lines);
399 
400     cmd = "hilog -a test 2>&1";
401     std::string errMsg = ErrorCode2Str(ERR_NOT_NUMBER_STR) + "\n";
402     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
403 
404     cmd = "hilog -z test 2>&1";
405     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
406 
407     cmd = "hilog -a 10 -z 10 2>&1";
408     errMsg = ErrorCode2Str(ERR_COMMAND_INVALID) + "\n";
409     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
410 }
411 
412 /**
413  * @tc.name: Dfx_HilogToolTest_HandleTest_010
414  * @tc.desc: RemoveHandler.
415  * @tc.type: FUNC
416  */
417 HWTEST_F(HilogToolTest, HandleTest_010, TestSize.Level1)
418 {
419     /**
420      * @tc.steps: step1. get the localtime.
421      * @tc.steps: step2. remove all logs in hilogd buffer.
422      * @tc.steps: step3. compare the logtime to localtime.
423      */
424     GTEST_LOG_(INFO) << "HandleTest_010: start.";
425     time_t tnow = time(nullptr);
426     struct tm *tmNow = localtime(&tnow);
427     char clearTime[32] = {0};
428     if (tmNow != nullptr) {
429         strftime(clearTime, sizeof(clearTime), "%m-%d %H:%M:%S.%s", tmNow);
430     }
431     std::string cmd = "hilog -r";
432     std::string str = "Log type core,app,only_prerelease buffer clear successfully\n";
433     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
434 
435     sleep(1);
436     std::string res = GetCmdResultFromPopen("hilog -a 5");
437     std::string initStr = "HiLog: ========Zeroth log of type: init";
438     vector<string> vec;
439     std::string logTime = "";
440     Split(res, vec, "\n");
441     for (auto& it : vec) {
442         if (it.find(initStr) == string::npos) {
443             logTime = it.substr(0, 18);
444             EXPECT_LT(clearTime, logTime);
445         }
446     }
447 }
448 
449 /**
450  * @tc.name: Dfx_HilogToolTest_HandleTest_011
451  * @tc.desc: TypeHandler.
452  * @tc.type: FUNC
453  */
454 HWTEST_F(HilogToolTest, HandleTest_011, TestSize.Level1)
455 {
456     /**
457      * @tc.steps: step1. remove app logs in hilogd buffer.
458      * @tc.steps: step2. remove core logs in hilogd buffer.
459      * @tc.steps: step3. invalid log type.
460      */
461     GTEST_LOG_(INFO) << "HandleTest_011: start.";
462     std::string cmd = "hilog -r -t app";
463     std::string str = "Log type app buffer clear successfully\n";
464     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
465 
466     cmd = "hilog -r -t core";
467     str = "Log type core buffer clear successfully\n";
468     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
469 
470     cmd = "hilog -r -t test_type 2>&1";
471     std::string errMsg = ErrorCode2Str(ERR_LOG_TYPE_INVALID) + "\n";
472     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
473 }
474 
475 /**
476  * @tc.name: Dfx_HilogToolTest_HandleTest_012
477  * @tc.desc: PersistTaskHandler FileNameHandler JobIdHandler FileLengthHandler FileNumberHandler.
478  * @tc.type: FUNC
479  */
480 HWTEST_F(HilogToolTest, HandleTest_012, TestSize.Level1)
481 {
482     /**
483      * @tc.steps: step1. start hilog persistance task control.
484      * @tc.steps: step2. stop hilog persistance task control.
485      * @tc.steps: step3. start hilog persistance task control with advanced options.
486      * @tc.steps: step4. query tasks informations.
487      * @tc.steps: step5. invalid persistance cmd.
488      * @tc.steps: step6. query invalid filename.
489      * @tc.steps: step7. query invalid jobid.
490      * @tc.steps: step8. query invalid filelength.
491      * @tc.steps: step9. query invalid filenumber.
492      */
493     GTEST_LOG_(INFO) << "HandleTest_012: start.";
494     (void)GetCmdResultFromPopen("hilog -w stop");
495     std::string cmd = "hilog -w start";
496     std::string str = "Persist task [jobid:1] start successfully\n";
497     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
498 
499     cmd = "hilog -w stop";
500     str = "Persist task [jobid:1] stop successfully\n";
501     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
502 
503     std::string filename = "test";
504     uint64_t length = 2 * 1024 * 1024;
505     std::string unit = "B";
506     std::string compress = "zlib";
507     int num = 25;
508     int jobid = 200;
509     cmd = "hilog -w start -f " + filename + " -l " + std::to_string(length) + unit
510         + " -n " + std::to_string(num) + " -m " + compress + " -j " + std::to_string(jobid);
511     str = "Persist task [jobid:" + std::to_string(jobid) + "] start successfully\n";
512     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
513 
514     cmd = "hilog -w query";
515     str = std::to_string(jobid) + " init,core,app,only_prerelease " + compress + " /data/log/hilog/" + filename
516         + " " + Size2Str(length) + " " + std::to_string(num) + "\n";
517     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
518 
519     cmd = "hilog -w test 2>&1";
520     std::string errMsg = ErrorCode2Str(ERR_INVALID_ARGUMENT) + "\n";
521     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
522 
523     filename = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
524                 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
525     cmd = "hilog -w query -f " + filename + " 2>&1";
526     errMsg = ErrorCode2Str(ERR_FILE_NAME_TOO_LONG) + "\n";
527     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
528 
529     cmd = "hilog -w query -j test 2>&1";
530     errMsg = ErrorCode2Str(ERR_NOT_NUMBER_STR) + "\n";
531     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
532 
533     cmd = "hilog -w query -l test 2>&1";
534     errMsg = ErrorCode2Str(ERR_INVALID_SIZE_STR) + "\n";
535     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
536 
537     cmd = "hilog -w query -n test 2>&1";
538     errMsg = ErrorCode2Str(ERR_NOT_NUMBER_STR) + "\n";
539     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
540 }
541 
542 /**
543  * @tc.name: Dfx_HilogToolTest_HandleTest_013
544  * @tc.desc: RegexHandler.
545  * @tc.type: FUNC
546  */
547 HWTEST_F(HilogToolTest, HandleTest_013, TestSize.Level1)
548 {
549     /**
550      * @tc.steps: step1. show the logs which match the regular expression.
551 	 * @tc.steps: step2. invaild regex.
552      */
553     GTEST_LOG_(INFO) << "HandleTest_013: start.";
554     std::string cmd = "hilog -x -e ";
555     std::string regex = "service";
556     std::string res = GetCmdResultFromPopen(cmd + regex);
557     if (res != "") {
558         vector<string> vec;
559         Split(res, vec, "\n");
560         for (auto& it : vec) {
561             EXPECT_TRUE(it.find(regex) != string::npos);
562         }
563     }
564 
565     cmd = "hilog -x -e abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
566             "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
567             "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 2>&1";
568     std::string errMsg = ErrorCode2Str(ERR_REGEX_STR_TOO_LONG) + "\n";
569     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
570 }
571 
572 /**
573  * @tc.name: Dfx_HilogToolTest_HandleTest_013
574  * @tc.desc: LevelHandler.
575  * @tc.type: FUNC
576  */
577 HWTEST_F(HilogToolTest, HandleTest_014, TestSize.Level1)
578 {
579     /**
580      * @tc.steps: step1. filter log level.
581      * @tc.steps: step2. invaild log level usage.
582      */
583     GTEST_LOG_(INFO) << "HandleTest_014: start.";
584     std::string cmd = "hilog -a 10 -L ";
585     std::string level = "I";
586     std::string res = GetCmdResultFromPopen(cmd + level);
587     vector<string> vec;
588     Split(res, vec, "\n");
589     for (auto& it : vec) {
590         std::string logLevel = it.substr(31, 1);
591         EXPECT_EQ(logLevel, level);
592     }
593 
594     cmd = "hilog -L test_level 2>&1";
595     std::string errMsg = ErrorCode2Str(ERR_LOG_LEVEL_INVALID) + "\n";
596     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
597 
598     cmd = "hilog -L E F 2>&1";
599     errMsg = ErrorCode2Str(ERR_TOO_MANY_ARGUMENTS) + "\n";
600     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
601 
602     cmd = "hilog -L E -L F 2>&1";
603     errMsg = ErrorCode2Str(ERR_DUPLICATE_OPTION) + "\n";
604     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
605 }
606 
607 /**
608  * @tc.name: Dfx_HilogToolTest_HandleTest_013
609  * @tc.desc: PidHandler.
610  * @tc.type: FUNC
611  */
612 HWTEST_F(HilogToolTest, HandleTest_015, TestSize.Level1)
613 {
614     /**
615      * @tc.steps: step1. filter PID.
616      */
617     GTEST_LOG_(INFO) << "HandleTest_015: start.";
618     std::string pid = GetCmdResultFromPopen("hilog -z 1").substr(19, 5);
619     std::string cmd = "hilog -a 10 -P ";
620     std::string res = GetCmdResultFromPopen(cmd + pid);
621     if (res != "") {
622         vector<string> vec;
623         Split(res, vec, "\n");
624         for (auto& it : vec) {
625             std::string logPid = it.substr(19, 5);
626             EXPECT_EQ(logPid, pid);
627         }
628     }
629 
630     cmd = "hilog -P test 2>&1";
631     std::string errMsg = ErrorCode2Str(ERR_NOT_NUMBER_STR) + "\n";
632     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
633 }
634 
635 /**
636  * @tc.name: Dfx_HilogToolTest_HandleTest_016
637  * @tc.desc: StatsInfoQueryHandler.
638  * @tc.type: FUNC
639  */
640 HWTEST_F(HilogToolTest, HandleTest_016, TestSize.Level1)
641 {
642     /**
643      * @tc.steps: step1. set stats property.
644      * @tc.steps: step2. restart hilog service.
645      * @tc.steps: step3. show log statistic report.
646      * @tc.steps: step4. clear hilogd statistic information.
647      */
648     GTEST_LOG_(INFO) << "HandleTest_016: start.";
649     (void)GetCmdResultFromPopen("param set persist.sys.hilog.stats false");
650     (void)GetCmdResultFromPopen("param set persist.sys.hilog.stats.tag false");
651     (void)GetCmdResultFromPopen("service_control stop hilogd");
652     (void)GetCmdResultFromPopen("service_control start hilogd");
653     sleep(3);
654     std::string cmd = "hilog -s";
655     std::string str = "Statistic info query failed";
656     EXPECT_TRUE(IsExistInCmdResult(cmd, str));
657 
658     (void)GetCmdResultFromPopen("param set persist.sys.hilog.stats true");
659     (void)GetCmdResultFromPopen("param set persist.sys.hilog.stats.tag true");
660     (void)GetCmdResultFromPopen("service_control stop hilogd");
661     (void)GetCmdResultFromPopen("service_control start hilogd");
662     sleep(10);
663     str = "report";
664     EXPECT_TRUE(IsExistInCmdResult(cmd, str));
665     EXPECT_TRUE(IsStatsEnable());
666     EXPECT_TRUE(IsTagStatsEnable());
667 
668     cmd = "hilog -S";
669     str = "Statistic info clear successfully\n";
670     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
671 }
672 
673 /**
674  * @tc.name: Dfx_HilogToolTest_HandleTest_017
675  * @tc.desc: FormatHandler.
676  * @tc.type: FUNC
677  */
678 HWTEST_F(HilogToolTest, HandleTest_017, TestSize.Level1)
679 {
680     /**
681      * @tc.steps: step1. log format time.
682      * @tc.steps: step2. log format epoch.
683      * @tc.steps: step3. log format monotonic.
684      * @tc.steps: step4. log format msec.
685      * @tc.steps: step5. log format usec.
686      * @tc.steps: step6. log format nsec.
687      * @tc.steps: step7. log format year.
688      * @tc.steps: step8. log format zone.
689      * @tc.steps: step9. invalid log format.
690      */
691     GTEST_LOG_(INFO) << "HandleTest_017: start.";
692     std::string cmd = "hilog -v time -z 5";
693     std::regex pattern("(0\\d{1}|1[0-2])-(0\\d{1}|[12]\\d{1}|3[01])\\s(0\\d{1}|1\\d{1}|2[0-3])"
694                         ":[0-5]\\d{1}:([0-5]\\d{1})(\\.(\\d){0,3})?$");
695     std::string res = GetCmdResultFromPopen(cmd);
696     vector<string> vec;
697     Split(res, vec, "\n");
698     for (auto& it : vec) {
699         EXPECT_TRUE(regex_match(it.substr(0, 18), pattern));
700     }
701 
702     cmd = "hilog -v epoch -z 5";
703     pattern = ("\\d{0,10}.\\d{3}$");
704     res = GetCmdResultFromPopen(cmd);
705     Split(res, vec, "\n");
706     for (auto& it : vec) {
707         EXPECT_TRUE(regex_match(it.substr(0, 14), pattern));
708     }
709 
710     cmd = "hilog -v monotonic -z 5";
711     pattern = ("\\d{0,8}.\\d{3}$");
712     res = GetCmdResultFromPopen(cmd);
713     std::string initStr = "HiLog: ========Zeroth log of type";
714     Split(res, vec, "\n");
715     for (auto& it : vec) {
716         if (it.find(initStr) == string::npos) {
717             std::string str = it.substr(0, 12);
718             // remove the head blank space
719             str.erase(0, str.find_first_not_of(" "));
720             EXPECT_TRUE(regex_match(str, pattern));
721         }
722     }
723 
724     cmd = "hilog -v msec -z 5";
725     pattern = ("(0\\d{1}|1[0-2])-(0\\d{1}|[12]\\d{1}|3[01])\\s(0\\d{1}|1\\d{1}|2[0-3])"
726                         ":[0-5]\\d{1}:([0-5]\\d{1})(\\.(\\d){0,3})?$");
727     res = GetCmdResultFromPopen(cmd);
728     Split(res, vec, "\n");
729     for (auto& it : vec) {
730         EXPECT_TRUE(regex_match(it.substr(0, 18), pattern));
731     }
732 
733     cmd = "hilog -v usec -z 5";
734     pattern = "(0\\d{1}|1[0-2])-(0\\d{1}|[12]\\d{1}|3[01])\\s(0\\d{1}|1\\d{1}|2[0-3])"
735                 ":[0-5]\\d{1}:([0-5]\\d{1})(\\.(\\d){0,6})?$";
736     res = GetCmdResultFromPopen(cmd);
737     Split(res, vec, "\n");
738     for (auto& it : vec) {
739         EXPECT_TRUE(regex_match(it.substr(0, 21), pattern));
740     }
741 
742     cmd = "hilog -v nsec -z 5";
743     pattern = "(0\\d{1}|1[0-2])-(0\\d{1}|[12]\\d{1}|3[01])\\s(0\\d{1}|1\\d{1}|2[0-3])"
744                 ":[0-5]\\d{1}:([0-5]\\d{1})(\\.(\\d){0,9})?$";
745     res = GetCmdResultFromPopen(cmd);
746     Split(res, vec, "\n");
747     for (auto& it : vec) {
748         EXPECT_TRUE(regex_match(it.substr(0, 24), pattern));
749     }
750 
751     cmd = "hilog -v year -z 5";
752     pattern = "(\\d{4})-(0\\d{1}|1[0-2])-(0\\d{1}|[12]\\d{1}|3[01])\\s(0\\d{1}|1\\d{1}|2[0-3])"
753             ":[0-5]\\d{1}:([0-5]\\d{1})(\\.(\\d){0,3})?$";
754     res = GetCmdResultFromPopen(cmd);
755     Split(res, vec, "\n");
756     for (auto& it : vec) {
757         EXPECT_TRUE(regex_match(it.substr(0, 23), pattern));
758     }
759 
760     cmd = "hilog -v zone -z 5";
761     std::regex gmtPattern("GMT (0\\d{1}|1[0-2])-(0\\d{1}|[12]\\d{1}|3[01])\\s(0\\d{1}|1\\d{1}|2[0-3])"
762             ":[0-5]\\d{1}:([0-5]\\d{1})(\\.(\\d){0,3})?$");
763     std::regex cstPattern("CST (0\\d{1}|1[0-2])-(0\\d{1}|[12]\\d{1}|3[01])\\s(0\\d{1}|1\\d{1}|2[0-3])"
764             ":[0-5]\\d{1}:([0-5]\\d{1})(\\.(\\d){0,3})?$");
765     res = GetCmdResultFromPopen(cmd);
766     Split(res, vec, "\n");
767     for (auto& it : vec) {
768         EXPECT_TRUE(regex_match(it.substr(0, 22), gmtPattern) || regex_match(it.substr(0, 22), cstPattern));
769     }
770 
771     cmd = "hilog -v test 2>&1";
772     std::string errMsg = ErrorCode2Str(ERR_INVALID_ARGUMENT) + "\n";
773     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
774 
775     cmd = "hilog -v time -v epoch 2>&1";
776     errMsg = ErrorCode2Str(ERR_DUPLICATE_OPTION) + "\n";
777     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
778 
779     cmd = "hilog -v msec -v usec 2>&1";
780     errMsg = ErrorCode2Str(ERR_DUPLICATE_OPTION) + "\n";
781     EXPECT_EQ(GetCmdResultFromPopen(cmd), errMsg);
782 
783     cmd = "hilog -x -v color";
784     EXPECT_GT(GetCmdLinesFromPopen(cmd), 0);
785 }
786 
787 /**
788  * @tc.name: Dfx_HilogToolTest_HandleTest_018
789  * @tc.desc: QueryLogHandler.
790  * @tc.type: FUNC
791  */
792 HWTEST_F(HilogToolTest, HandleTest_018, TestSize.Level1)
793 {
794     /**
795      * @tc.steps: step1. query log of specific pid.
796      * @tc.steps: step2. query log of specific domain.
797      * @tc.steps: step3. query log of specific tag.
798      */
799     GTEST_LOG_(INFO) << "HandleTest_018: start.";
800     std::string res = GetCmdResultFromPopen("hilog -z 1");
801     std::string pid = res.substr(19, 5);
802     std::string domain = res.substr(34, 5);
803     int tagLen = res.substr(40).find(":") + 1;
804     std::string tag = res.substr(40, tagLen);
805     std::string queryDomainCmd = "hilog -x -D d0" + domain;
806     std::string queryPidCmd = "hilog -x -P " + pid;
807     std::string queryTagCmd = "hilog -x -T " + tag;
808     vector<string> vec;
809 
810     res = GetCmdResultFromPopen(queryPidCmd);
811     if (res != "") {
812         Split(res, vec, "\n");
813         for (auto& it : vec) {
814             std::string logPid = it.substr(19, 5);
815             EXPECT_EQ(logPid, pid);
816         }
817     }
818 
819     res = GetCmdResultFromPopen(queryDomainCmd);
820     if (res != "") {
821         Split(res, vec, "\n");
822         for (auto& it : vec) {
823             std::string logDomain = it.substr(34, 5);
824             EXPECT_EQ(logDomain, domain);
825         }
826     }
827 
828     res = GetCmdResultFromPopen(queryTagCmd);
829     if (res != "") {
830         Split(res, vec, "\n");
831         for (auto& it : vec) {
832             std::string logTag = it.substr(40, tagLen);
833             EXPECT_EQ(logTag, tag);
834         }
835     }
836 }
837 
838 /**
839  * @tc.name: Dfx_HilogToolTest_HandleTest_019
840  * @tc.desc: tag & domain level ctl.
841  * @tc.type: FUNC
842  */
843 HWTEST_F(HilogToolTest, HandleTest_019, TestSize.Level1)
844 {
845     /**
846      * @tc.steps: step1. tag level ctl.
847      * @tc.steps: step2. domain level ctl.
848      */
849     GTEST_LOG_(INFO) << "HandleTest_019: start.";
850     std::string res = GetCmdResultFromPopen("hilog -z 1");
851     uint32_t domain = std::stoi(res.substr(34, 5));
852     int tagLen = res.substr(40).find(":") + 1;
853     std::string tag = res.substr(40, tagLen);
854 
855     // Priority: TagLevel > DomainLevel > GlobalLevel
856     SetTagLevel(tag, LOG_ERROR);
857     SetDomainLevel(domain, LOG_INFO);
858     EXPECT_FALSE(HiLogIsLoggable(domain, tag.c_str(), LOG_INFO));
859     EXPECT_TRUE(HiLogIsLoggable(domain, tag.c_str(), LOG_ERROR));
860 
861     SetTagLevel(tag, LOG_INFO);
862     SetDomainLevel(domain, LOG_ERROR);
863     EXPECT_TRUE(HiLogIsLoggable(domain, tag.c_str(), LOG_INFO));
864     EXPECT_TRUE(HiLogIsLoggable(domain, tag.c_str(), LOG_ERROR));
865 
866     // restore log level
867     SetDomainLevel(domain, LOG_INFO);
868 }
869 
870 /**
871  * @tc.name: Dfx_HilogToolTest_ClearTest_020
872  * @tc.desc: hilog -w clear can delete /data/log/hilog/hilog*.gz.
873  * @tc.type: FUNC
874  */
875 HWTEST_F(HilogToolTest, HandleTest_020, TestSize.Level1)
876 {
877     GTEST_LOG_(INFO) << "HandleTest_020: start.";
878     (void)GetCmdResultFromPopen("hilog -w stop");
879     std::string cmd = "hilog -w clear";
880     std::string str = "Persist log /data/log/hilog clear successfully\n";
881     EXPECT_EQ(GetCmdResultFromPopen(cmd), str);
882 
883     std::regex hilogFilePattern("^hilog.*gz$");
884     DIR *dir = nullptr;
885     struct dirent *ent = nullptr;
886     if ((dir = opendir("/data/log/hilog")) != nullptr) {
887         while ((ent = readdir(dir)) != nullptr) {
888             EXPECT_FALSE(std::regex_match(ent->d_name, hilogFilePattern));
889         }
890     }
891     if (dir != nullptr) {
892         closedir(dir);
893     }
894     (void)GetCmdResultFromPopen("hilog -w start");
895 }
896 } // namespace
897