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 <cinttypes>
17 #include <thread>
18 #include <mutex>
19 #include <vector>
20 #include <gtest/gtest.h>
21 #include "hookmgr.h"
22 using namespace testing::ext;
23 using namespace std;
24
25 namespace initModuleTest {
26 #define STAGE_TEST_ONE 0
27 int g_publicData = 0;
28 mutex g_mutex;
29 HOOK_MGR *g_hookMgr = nullptr;
30 class HookMgrModuleTest : public testing::Test {
31 public:
SetUpTestCase(void)32 static void SetUpTestCase(void) {};
TearDownTestCase(void)33 static void TearDownTestCase(void) {};
SetUp()34 void SetUp() {};
TearDown()35 void TearDown() {};
36 };
37
38 struct HookExecCtx {
39 int result;
40 int retErr;
41 };
42
HookExecFunc(int n)43 void HookExecFunc(int n)
44 {
45 for (int i = 0; i < n; ++i) {
46 HookMgrExecute(g_hookMgr, STAGE_TEST_ONE, nullptr, nullptr);
47 }
48 }
49
OhosTestHookMultiThread(const HOOK_INFO * hookInfo,void * executionContext)50 static int OhosTestHookMultiThread(const HOOK_INFO *hookInfo, void *executionContext)
51 {
52 lock_guard<std::mutex> lg(g_mutex);
53 g_publicData++;
54 return 0;
55 }
56
OhosTestHookMultiThreadAnother(const HOOK_INFO * hookInfo,void * executionContext)57 static int OhosTestHookMultiThreadAnother(const HOOK_INFO *hookInfo, void *executionContext)
58 {
59 lock_guard<std::mutex> lg(g_mutex);
60 g_publicData++;
61 return -1;
62 }
63
OhosHookPrint(const HOOK_INFO * hookInfo,void * traversalCookie)64 static void OhosHookPrint(const HOOK_INFO *hookInfo, void *traversalCookie)
65 {
66 printf("\tstage[%02d] prio[%02d].\n", hookInfo->stage, hookInfo->prio);
67 }
68
DumpAllHooks(HOOK_MGR * hookMgr)69 static void DumpAllHooks(HOOK_MGR *hookMgr)
70 {
71 printf("----------All Hooks---------------\n");
72 HookMgrTraversal(hookMgr, NULL, OhosHookPrint);
73 printf("----------------------------------\n\n");
74 }
75
76 HWTEST_F(HookMgrModuleTest, HookMgrModuleTest, TestSize.Level1)
77 {
78 int ret;
79 int cnt;
80 g_hookMgr = HookMgrCreate("moduleTestHook");
81 ASSERT_NE(g_hookMgr, nullptr);
82
83 ret = HookMgrAdd(g_hookMgr, STAGE_TEST_ONE, 0, OhosTestHookMultiThread);
84 EXPECT_EQ(ret, 0);
85 cnt = HookMgrGetHooksCnt(g_hookMgr, STAGE_TEST_ONE);
86 EXPECT_EQ(cnt, 1);
87
88 HOOK_INFO info;
89 info.stage = STAGE_TEST_ONE;
90 info.prio = 1;
91 info.hook = OhosTestHookMultiThreadAnother;
92 info.hookCookie = nullptr;
93 HookMgrAddEx(g_hookMgr, &info);
94 cnt = HookMgrGetHooksCnt(g_hookMgr, STAGE_TEST_ONE);
95 EXPECT_EQ(cnt, 2);
96 cnt = HookMgrGetStagesCnt(g_hookMgr);
97 EXPECT_EQ(cnt, 1);
98 DumpAllHooks(g_hookMgr);
99
100 // test multiThread HookMgrExecute
101 std::vector<std::thread> threads;
102 for (int i = 1; i <= 10; ++i) {
103 threads.push_back(std::thread(HookExecFunc, 10));
104 }
105 for (auto & th : threads) {
106 th.join();
107 }
108 EXPECT_EQ(g_publicData, 200);
109
110 HookMgrAdd(g_hookMgr, STAGE_TEST_ONE, 1, OhosTestHookMultiThreadAnother);
111 cnt = HookMgrGetHooksCnt(g_hookMgr, STAGE_TEST_ONE);
112 EXPECT_EQ(cnt, 2);
113
114 HookMgrDel(g_hookMgr, STAGE_TEST_ONE, OhosTestHookMultiThreadAnother);
115 cnt = HookMgrGetHooksCnt(g_hookMgr, STAGE_TEST_ONE);
116 EXPECT_EQ(cnt, 1);
117 HookMgrDestroy(g_hookMgr);
118 }
119
120 } // namespace init_ut
121