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
23using namespace testing::ext;
24using namespace OHOS::HiviewDFX;
25
26namespace {
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
47namespace OHOS {
48namespace HiviewDFX {
49class HiCheckerNativeTest : public testing::Test {
50public:
51    static void SerUpTestCase() {};
52    static void TearDownTestCase() {};
53    void SetUp();
54    void TearDown();
55};
56
57void HiCheckerNativeTest::SetUp(void)
58{
59    HiChecker::RemoveRule(Rule::ALL_RULES);
60}
61
62void HiCheckerNativeTest::TearDown(void)
63{
64    HiChecker::RemoveRule(Rule::ALL_RULES);
65}
66
67static 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*/
79HWTEST_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*/
94HWTEST_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*/
111HWTEST_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*/
126HWTEST_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*/
145HWTEST_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*/
161HWTEST_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*/
176HWTEST_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*/
192HWTEST_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*/
211HWTEST_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*/
224HWTEST_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*/
237HWTEST_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*/
255HWTEST_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*/
271HWTEST_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*/
288HWTEST_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*/
304HWTEST_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*/
318HWTEST_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*/
334HWTEST_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*/
350HWTEST_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*/
366HWTEST_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*/
379HWTEST_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*/
392HWTEST_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*/
404HWTEST_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*/
417HWTEST_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