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 
16 #include <cstdlib>
17 #include <ctime>
18 #include <gtest/gtest.h>
19 
20 #include "caution.h"
21 #include "hichecker.h"
22 
23 using namespace testing::ext;
24 using namespace OHOS::HiviewDFX;
25 
26 namespace {
27     const int64_t SEC_TO_NS = 1000000000;
28     const int64_t MAX_CALL_DURATION_US = 1000; // 1ms
29     const int LOOP_COUNT = 1000;
30     const uint64_t RULE_ERROR0 = 0;
31     const uint64_t RULE_ERROR1 = -1;
32     const uint64_t RULE_ERROR2 = 999999999;
33     const uint64_t BASELINE_SIZE = 65 * 1024;
34 
35     vector<string> OUTPUT_PATH = {
36         "/system/etc/param/hichecker.para",
37         "/system/etc/param/hichecker.para.dac",
38         "/system/lib/module/hiviewdfx/libjsleakwatcher.z.so",
39         "/system/lib/module/libhichecker.z.so",
40         "/system/lib/platformsdk/libhichecker.so",
41         "/system/lib64/module/hiviewdfx/libjsleakwatcher.z.so",
42         "/system/lib64/module/libhichecker.z.so",
43         "/system/lib64/platformsdk/libhichecker.so"
44     };
45 }
46 
47 namespace OHOS {
48 namespace HiviewDFX {
49 class HiCheckerNativeTest : public testing::Test {
50 public:
SerUpTestCase()51     static void SerUpTestCase() {};
TearDownTestCase()52     static void TearDownTestCase() {};
53     void SetUp();
54     void TearDown();
55 };
56 
SetUp(void)57 void HiCheckerNativeTest::SetUp(void)
58 {
59     HiChecker::RemoveRule(Rule::ALL_RULES);
60 }
61 
TearDown(void)62 void HiCheckerNativeTest::TearDown(void)
63 {
64     HiChecker::RemoveRule(Rule::ALL_RULES);
65 }
66 
GetTimeNs()67 static int64_t GetTimeNs()
68 {
69     struct timespec ts;
70     clock_gettime(CLOCK_REALTIME, &ts);
71     return ts.tv_sec * SEC_TO_NS + ts.tv_nsec;
72 }
73 
74 /**
75   * @tc.name: AddRule001
76   * @tc.desc: add only one rule
77   * @tc.type: FUNC
78 */
HWTEST_F(HiCheckerNativeTest, AddRuleTest001, TestSize.Level1)79 HWTEST_F(HiCheckerNativeTest, AddRuleTest001, TestSize.Level1)
80 {
81     uint64_t rule = Rule::RULE_THREAD_CHECK_SLOW_PROCESS;
82     HiChecker::AddRule(Rule::RULE_THREAD_CHECK_SLOW_PROCESS);
83     ASSERT_EQ(HiChecker::GetRule(), rule);
84     rule |= Rule::RULE_CAUTION_PRINT_LOG;
85     HiChecker::AddRule(Rule::RULE_CAUTION_PRINT_LOG);
86     ASSERT_EQ(HiChecker::GetRule(), rule);
87 }
88 
89 /**
90   * @tc.name: AddRule002
91   * @tc.desc: add two or more rules
92   * @tc.type: FUNC
93 */
HWTEST_F(HiCheckerNativeTest, AddRuleTest002, TestSize.Level1)94 HWTEST_F(HiCheckerNativeTest, AddRuleTest002, TestSize.Level1)
95 {
96     uint64_t rule = Rule::RULE_THREAD_CHECK_SLOW_PROCESS |
97         Rule::RULE_CHECK_SLOW_EVENT | Rule::RULE_CHECK_ABILITY_CONNECTION_LEAK;
98     HiChecker::AddRule(Rule::RULE_THREAD_CHECK_SLOW_PROCESS |
99         Rule::RULE_CHECK_SLOW_EVENT | Rule::RULE_CHECK_ABILITY_CONNECTION_LEAK);
100     ASSERT_EQ(HiChecker::GetRule(), rule);
101     rule |= (Rule::RULE_CAUTION_PRINT_LOG | Rule::RULE_CAUTION_TRIGGER_CRASH);
102     HiChecker::AddRule(Rule::RULE_CAUTION_PRINT_LOG | Rule::RULE_CAUTION_TRIGGER_CRASH);
103     ASSERT_EQ(HiChecker::GetRule(), rule);
104 }
105 
106 /**
107   * @tc.name: AddRule003
108   * @tc.desc: add invaild rule
109   * @tc.type: FUNC
110 */
HWTEST_F(HiCheckerNativeTest, AddRuleTest003, TestSize.Level1)111 HWTEST_F(HiCheckerNativeTest, AddRuleTest003, TestSize.Level1)
112 {
113     HiChecker::AddRule(RULE_ERROR0);
114     ASSERT_EQ(HiChecker::GetRule(), 0);
115     HiChecker::AddRule(RULE_ERROR1);
116     ASSERT_EQ(HiChecker::GetRule(), 0);
117     HiChecker::AddRule(RULE_ERROR2);
118     ASSERT_EQ(HiChecker::GetRule(), 0);
119 }
120 
121 /**
122   * @tc.name: AddRulePerf
123   * @tc.desc: test performance for AddRule
124   * @tc.type: PERF
125 */
HWTEST_F(HiCheckerNativeTest, AddRulePerfTest001, TestSize.Level2)126 HWTEST_F(HiCheckerNativeTest, AddRulePerfTest001, TestSize.Level2)
127 {
128     int64_t total = 0;
129     for (int i = 0; i < LOOP_COUNT; i++) {
130         int64_t start = GetTimeNs();
131         HiChecker::AddRule(Rule::RULE_CHECK_SLOW_EVENT);
132         int64_t duration = GetTimeNs() - start;
133         total += duration;
134     }
135     int64_t duration = (total / LOOP_COUNT);
136     duration = duration / 1000;
137     ASSERT_TRUE(duration < MAX_CALL_DURATION_US);
138 }
139 
140 /**
141   * @tc.name: RemoveRule001
142   * @tc.desc: remove only one rule
143   * @tc.type: FUNC
144 */
145 HWTEST_F(HiCheckerNativeTest, RemoveRuleTest001, TestSize.Level1)
146 {
147     HiChecker::AddRule(Rule::ALL_RULES);
148     HiChecker::RemoveRule(Rule::RULE_CAUTION_TRIGGER_CRASH);
149     ASSERT_FALSE(HiChecker::Contains(Rule::RULE_CAUTION_TRIGGER_CRASH));
150     HiChecker::RemoveRule(Rule::RULE_CAUTION_PRINT_LOG);
151     ASSERT_FALSE(HiChecker::Contains(Rule::RULE_CAUTION_PRINT_LOG));
152     uint64_t rule = Rule::ALL_RULES ^ (Rule::RULE_CAUTION_PRINT_LOG | Rule::RULE_CAUTION_TRIGGER_CRASH);
153     ASSERT_EQ(HiChecker::GetRule(), rule);
154 }
155 
156 /**
157   * @tc.name: RemoveRule002
158   * @tc.desc: remove two or more rules
159   * @tc.type: FUNC
160 */
161 HWTEST_F(HiCheckerNativeTest, RemoveRuleTest002, TestSize.Level1)
162 {
163     HiChecker::AddRule(Rule::ALL_RULES);
164     HiChecker::RemoveRule(Rule::RULE_CAUTION_TRIGGER_CRASH | Rule::RULE_CAUTION_PRINT_LOG);
165     ASSERT_FALSE(HiChecker::Contains(Rule::RULE_CAUTION_TRIGGER_CRASH));
166     ASSERT_FALSE(HiChecker::Contains(Rule::RULE_CAUTION_PRINT_LOG));
167     uint64_t rule = Rule::ALL_RULES ^ (Rule::RULE_CAUTION_PRINT_LOG | Rule::RULE_CAUTION_TRIGGER_CRASH);
168     ASSERT_EQ(HiChecker::GetRule(), rule);
169 }
170 
171 /**
172   * @tc.name: RemoveRule003
173   * @tc.desc: remove invaild rule
174   * @tc.type: FUNC
175 */
176 HWTEST_F(HiCheckerNativeTest, RemoveRuleTest003, TestSize.Level1)
177 {
178     HiChecker::AddRule(Rule::ALL_RULES);
179     HiChecker::RemoveRule(RULE_ERROR0);
180     ASSERT_EQ(HiChecker::GetRule(), Rule::ALL_RULES);
181     HiChecker::RemoveRule(RULE_ERROR1);
182     ASSERT_EQ(HiChecker::GetRule(), Rule::ALL_RULES);
183     HiChecker::RemoveRule(RULE_ERROR2);
184     ASSERT_EQ(HiChecker::GetRule(), Rule::ALL_RULES);
185 }
186 
187 /**
188   * @tc.name: RemoveRulePerf
189   * @tc.desc: test performance for RemoveRule
190   * @tc.type: PERF
191 */
192 HWTEST_F(HiCheckerNativeTest, RemoveRulePerfTest001, TestSize.Level2)
193 {
194     int64_t total = 0;
195     for (int i = 0; i < LOOP_COUNT; i++) {
196         int64_t start = GetTimeNs();
197         HiChecker::RemoveRule(Rule::RULE_CHECK_SLOW_EVENT);
198         int64_t duration = GetTimeNs() - start;
199         total += duration;
200     }
201     int64_t duration = (total / LOOP_COUNT);
202     duration = duration / 1000;
203     ASSERT_TRUE(duration < MAX_CALL_DURATION_US);
204 }
205 
206 /**
207   * @tc.name: Contains001
208   * @tc.desc: test Contains
209   * @tc.type: FUNC
210 */
211 HWTEST_F(HiCheckerNativeTest, ContainsTest001, TestSize.Level1)
212 {
213     HiChecker::AddRule(Rule::RULE_CAUTION_PRINT_LOG);
214     ASSERT_TRUE(HiChecker::Contains(Rule::RULE_CAUTION_PRINT_LOG));
215     ASSERT_FALSE(HiChecker::Contains(Rule::RULE_CAUTION_TRIGGER_CRASH));
216     ASSERT_FALSE(HiChecker::Contains(Rule::RULE_CAUTION_PRINT_LOG | Rule::RULE_CAUTION_TRIGGER_CRASH));
217 }
218 
219 /**
220   * @tc.name: Contains002
221   * @tc.desc: test Contains with invaild rule
222   * @tc.type: FUNC
223 */
224 HWTEST_F(HiCheckerNativeTest, ContainsTest002, TestSize.Level1)
225 {
226     HiChecker::AddRule(Rule::ALL_RULES);
227     ASSERT_FALSE(HiChecker::Contains(RULE_ERROR0));
228     ASSERT_FALSE(HiChecker::Contains(RULE_ERROR1));
229     ASSERT_FALSE(HiChecker::Contains(RULE_ERROR2));
230 }
231 
232 /**
233   * @tc.name: CautionTest001
234   * @tc.desc: test Caution
235   * @tc.type: FUNC
236 */
237 HWTEST_F(HiCheckerNativeTest, CautionTest001, TestSize.Level1)
238 {
239     Caution caution;
240     caution.SetTriggerRule(Rule::RULE_CAUTION_PRINT_LOG);
241     EXPECT_EQ(caution.GetTriggerRule(), Rule::RULE_CAUTION_PRINT_LOG);
242 
243     caution.SetStackTrace("stack_trace");
244     EXPECT_EQ(caution.GetStackTrace(), "stack_trace");
245 
246     caution.SetCautionMsg("caution_msg");
247     EXPECT_EQ(caution.GetCautionMsg(), "caution_msg");
248 }
249 
250 /**
251   * @tc.name: NotifySlowProcessTest001
252   * @tc.desc: test NotifySlowProcess
253   * @tc.type: FUNC
254 */
255 HWTEST_F(HiCheckerNativeTest, NotifySlowProcessTest001, TestSize.Level1)
256 {
257     HiChecker::AddRule(RULE_ERROR0);
258     std::string eventTag = "NotifySlowProcessTest001";
259     HiChecker::NotifySlowProcess(eventTag);
260     HiChecker::AddRule(Rule::RULE_THREAD_CHECK_SLOW_PROCESS);
261     ASSERT_EQ(HiChecker::GetRule(), Rule::RULE_THREAD_CHECK_SLOW_PROCESS);
262     HiChecker::NotifySlowProcess(eventTag);
263     HiChecker::RemoveRule(Rule::RULE_CHECK_SLOW_EVENT);
264 }
265 
266 /**
267   * @tc.name: NotifyAbilityConnectionLeakTest001
268   * @tc.desc: test NotifyAbilityConnectionLeak
269   * @tc.type: FUNC
270 */
271 HWTEST_F(HiCheckerNativeTest, NotifyAbilityConnectionLeakTest001, TestSize.Level1)
272 {
273     std::string cautionMsg = "NotifyAbilityConnectionLeakTest001";
274     std::string stackTrace = "stackTrace";
275     Caution cautionError(RULE_ERROR0, cautionMsg, "stackTrace");
276     HiChecker::NotifyAbilityConnectionLeak(cautionError);
277     Caution caution(Rule::RULE_CHECK_ABILITY_CONNECTION_LEAK, cautionMsg, stackTrace);
278     HiChecker::NotifyAbilityConnectionLeak(caution);
279     EXPECT_EQ(caution.GetStackTrace(), stackTrace);
280     EXPECT_EQ(caution.GetCautionMsg(), cautionMsg);
281 }
282 
283 /**
284   * @tc.name: NotifySlowEventTest001
285   * @tc.desc: test PrintLog
286   * @tc.type: FUNC
287 */
288 HWTEST_F(HiCheckerNativeTest, NotifySlowEventTest001, TestSize.Level1)
289 {
290     HiChecker::AddRule(RULE_ERROR0);
291     std::string eventTag = "NotifySlowEventTest001 time out";
292     HiChecker::NotifySlowEvent(eventTag);
293     HiChecker::AddRule(Rule::RULE_CHECK_SLOW_EVENT);
294     ASSERT_TRUE(HiChecker::NeedCheckSlowEvent());
295     HiChecker::NotifySlowEvent(eventTag);
296     HiChecker::RemoveRule(Rule::RULE_CHECK_SLOW_EVENT);
297 }
298 
299 /**
300   * @tc.name: NotifyCautionTest001
301   * @tc.desc: test NotifyCaution
302   * @tc.type: FUNC
303 */
304 HWTEST_F(HiCheckerNativeTest, NotifyCautionTest001, TestSize.Level1)
305 {
306     HiChecker::AddRule(RULE_ERROR0);
307     Caution caution;
308     std::string tag = "error_tag";
309     HiChecker::NotifyCaution(RULE_ERROR0, tag, caution);
310     ASSERT_EQ(HiChecker::GetRule(), 0);
311 }
312 
313 /**
314   * @tc.name: NotifyCautionTest002
315   * @tc.desc: test NotifyCaution
316   * @tc.type: FUNC
317 */
318 HWTEST_F(HiCheckerNativeTest, NotifyCautionTest002, TestSize.Level1)
319 {
320     HiChecker::AddRule(Rule::RULE_CHECK_ARKUI_PERFORMANCE);
321     std::string tag = "arkui_tag";
322     Caution caution;
323     caution.SetTriggerRule(Rule::RULE_CHECK_ARKUI_PERFORMANCE);
324     HiChecker::NotifyCaution(Rule::RULE_CHECK_ARKUI_PERFORMANCE, tag, caution);
325     HiChecker::RemoveRule(Rule::RULE_CHECK_ARKUI_PERFORMANCE);
326     EXPECT_EQ(caution.GetCautionMsg(), "trigger:RULE_CHECK_ARKUI_PERFORMANCE,arkui_tag");
327 }
328 
329 /**
330   * @tc.name: NotifyCautionTest003
331   * @tc.desc: test NotifyCaution
332   * @tc.type: FUNC
333 */
334 HWTEST_F(HiCheckerNativeTest, NotifyCautionTest003, TestSize.Level1)
335 {
336     HiChecker::AddRule(Rule::RULE_THREAD_CHECK_SLOW_PROCESS);
337     std::string tag = "slow_process_tag";
338     Caution caution;
339     caution.SetTriggerRule(Rule::RULE_THREAD_CHECK_SLOW_PROCESS);
340     HiChecker::NotifyCaution(Rule::RULE_THREAD_CHECK_SLOW_PROCESS, tag, caution);
341     HiChecker::RemoveRule(Rule::RULE_THREAD_CHECK_SLOW_PROCESS);
342     EXPECT_EQ(caution.GetCautionMsg(), "trigger:RULE_THREAD_CHECK_SLOW_PROCESS,slow_process_tag");
343 }
344 
345 /**
346   * @tc.name: NotifyCautionTest004
347   * @tc.desc: test NotifyCaution
348   * @tc.type: FUNC
349 */
350 HWTEST_F(HiCheckerNativeTest, NotifyCautionTest004, TestSize.Level1)
351 {
352     HiChecker::AddRule(Rule::RULE_CHECK_SLOW_EVENT);
353     std::string tag = "slow_event_tag";
354     Caution caution;
355     caution.SetTriggerRule(Rule::RULE_CHECK_SLOW_EVENT);
356     HiChecker::NotifyCaution(Rule::RULE_CHECK_SLOW_EVENT, tag, caution);
357     HiChecker::RemoveRule(Rule::RULE_CHECK_SLOW_EVENT);
358     EXPECT_EQ(caution.GetCautionMsg(), "trigger:RULE_CHECK_SLOW_EVENT,slow_event_tag");
359 }
360 
361 /**
362   * @tc.name: InitHicheckerParamTest001
363   * @tc.desc: test InitHicheckerParam
364   * @tc.type: FUNC
365 */
366 HWTEST_F(HiCheckerNativeTest, InitHicheckerParamTest001, TestSize.Level1)
367 {
368     system("param set hiviewdfx.hichecker.checker_test 17179869184");
369     const char *processName = "checker_test111";
370     HiChecker::InitHicheckerParam(processName);
371     ASSERT_FALSE(HiChecker::Contains(Rule::RULE_CHECK_ARKUI_PERFORMANCE));
372 }
373 
374 /**
375   * @tc.name: InitHicheckerParamTest002
376   * @tc.desc: test InitHicheckerParam
377   * @tc.type: FUNC
378 */
379 HWTEST_F(HiCheckerNativeTest, InitHicheckerParamTest002, TestSize.Level1)
380 {
381     system("param set hiviewdfx.hichecker.checker_test 17179869184");
382     const char *processName = "checker_test";
383     HiChecker::InitHicheckerParam(processName);
384     ASSERT_TRUE(HiChecker::Contains(Rule::RULE_CHECK_ARKUI_PERFORMANCE));
385 }
386 
387 /**
388   * @tc.name: InitHicheckerParamTest003
389   * @tc.desc: test InitHicheckerParam
390   * @tc.type: FUNC
391 */
392 HWTEST_F(HiCheckerNativeTest, InitHicheckerParamTest003, TestSize.Level1)
393 {
394     const char *processName = "test.process.name.maxlength.greatthan.eighteen.aaaaaaaaaaaaaaaaaaaaaaaaaaa";
395     HiChecker::InitHicheckerParam(processName);
396     ASSERT_FALSE(HiChecker::Contains(Rule::RULE_CHECK_ARKUI_PERFORMANCE));
397 }
398 
399 /**
400   * @tc.name: InitHicheckerParamTest004
401   * @tc.desc: test InitHicheckerParam
402   * @tc.type: FUNC
403 */
404 HWTEST_F(HiCheckerNativeTest, InitHicheckerParamTest004, TestSize.Level1)
405 {
406     system("param set hiviewdfx.hichecker.checker_test 1024");
407     const char *processName = "checker_test";
408     HiChecker::InitHicheckerParam(processName);
409     ASSERT_FALSE(HiChecker::Contains(Rule::RULE_CHECK_ARKUI_PERFORMANCE));
410 }
411 
412 /**
413   * @tc.name: HicheckerRomTest001
414   * @tc.desc: test hichecker rom
415   * @tc.type: FUNC
416 */
417 HWTEST_F(HiCheckerNativeTest, HicheckerRomTest001, TestSize.Level1)
418 {
419     uint64_t realSize = 0;
420     for (int i = 0; i < OUTPUT_PATH.size(); i++) {
421         struct stat info = {0};
422         stat(OUTPUT_PATH[i].c_str(), &info);
423         realSize += static_cast<uint64_t>(info.st_size);
424     }
425     std::cout << "realSize = " << realSize << std::endl;
426     EXPECT_LT(realSize, BASELINE_SIZE);
427 }
428 } // namespace HiviewDFX
429 } // namespace OHOS
430