1d9f0492fSopenharmony_ci/*
2d9f0492fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License.
5d9f0492fSopenharmony_ci * You may obtain a copy of the License at
6d9f0492fSopenharmony_ci *
7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8d9f0492fSopenharmony_ci *
9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and
13d9f0492fSopenharmony_ci * limitations under the License.
14d9f0492fSopenharmony_ci */
15d9f0492fSopenharmony_ci
16d9f0492fSopenharmony_ci#include <cinttypes>
17d9f0492fSopenharmony_ci#include <thread>
18d9f0492fSopenharmony_ci#include <mutex>
19d9f0492fSopenharmony_ci#include <vector>
20d9f0492fSopenharmony_ci#include <gtest/gtest.h>
21d9f0492fSopenharmony_ci#include "hookmgr.h"
22d9f0492fSopenharmony_ciusing namespace testing::ext;
23d9f0492fSopenharmony_ciusing namespace std;
24d9f0492fSopenharmony_ci
25d9f0492fSopenharmony_cinamespace initModuleTest {
26d9f0492fSopenharmony_ci#define STAGE_TEST_ONE 0
27d9f0492fSopenharmony_ciint g_publicData = 0;
28d9f0492fSopenharmony_cimutex g_mutex;
29d9f0492fSopenharmony_ciHOOK_MGR *g_hookMgr = nullptr;
30d9f0492fSopenharmony_ciclass HookMgrModuleTest : public testing::Test {
31d9f0492fSopenharmony_cipublic:
32d9f0492fSopenharmony_ci    static void SetUpTestCase(void) {};
33d9f0492fSopenharmony_ci    static void TearDownTestCase(void) {};
34d9f0492fSopenharmony_ci    void SetUp() {};
35d9f0492fSopenharmony_ci    void TearDown() {};
36d9f0492fSopenharmony_ci};
37d9f0492fSopenharmony_ci
38d9f0492fSopenharmony_cistruct HookExecCtx {
39d9f0492fSopenharmony_ci    int result;
40d9f0492fSopenharmony_ci    int retErr;
41d9f0492fSopenharmony_ci};
42d9f0492fSopenharmony_ci
43d9f0492fSopenharmony_civoid HookExecFunc(int n)
44d9f0492fSopenharmony_ci{
45d9f0492fSopenharmony_ci    for (int i = 0; i < n; ++i) {
46d9f0492fSopenharmony_ci        HookMgrExecute(g_hookMgr, STAGE_TEST_ONE, nullptr, nullptr);
47d9f0492fSopenharmony_ci    }
48d9f0492fSopenharmony_ci}
49d9f0492fSopenharmony_ci
50d9f0492fSopenharmony_cistatic int OhosTestHookMultiThread(const HOOK_INFO *hookInfo, void *executionContext)
51d9f0492fSopenharmony_ci{
52d9f0492fSopenharmony_ci    lock_guard<std::mutex> lg(g_mutex);
53d9f0492fSopenharmony_ci    g_publicData++;
54d9f0492fSopenharmony_ci    return 0;
55d9f0492fSopenharmony_ci}
56d9f0492fSopenharmony_ci
57d9f0492fSopenharmony_cistatic int OhosTestHookMultiThreadAnother(const HOOK_INFO *hookInfo, void *executionContext)
58d9f0492fSopenharmony_ci{
59d9f0492fSopenharmony_ci    lock_guard<std::mutex> lg(g_mutex);
60d9f0492fSopenharmony_ci    g_publicData++;
61d9f0492fSopenharmony_ci    return -1;
62d9f0492fSopenharmony_ci}
63d9f0492fSopenharmony_ci
64d9f0492fSopenharmony_cistatic void OhosHookPrint(const HOOK_INFO *hookInfo, void *traversalCookie)
65d9f0492fSopenharmony_ci{
66d9f0492fSopenharmony_ci    printf("\tstage[%02d] prio[%02d].\n", hookInfo->stage, hookInfo->prio);
67d9f0492fSopenharmony_ci}
68d9f0492fSopenharmony_ci
69d9f0492fSopenharmony_cistatic void DumpAllHooks(HOOK_MGR *hookMgr)
70d9f0492fSopenharmony_ci{
71d9f0492fSopenharmony_ci    printf("----------All Hooks---------------\n");
72d9f0492fSopenharmony_ci    HookMgrTraversal(hookMgr, NULL, OhosHookPrint);
73d9f0492fSopenharmony_ci    printf("----------------------------------\n\n");
74d9f0492fSopenharmony_ci}
75d9f0492fSopenharmony_ci
76d9f0492fSopenharmony_ciHWTEST_F(HookMgrModuleTest, HookMgrModuleTest, TestSize.Level1)
77d9f0492fSopenharmony_ci{
78d9f0492fSopenharmony_ci    int ret;
79d9f0492fSopenharmony_ci    int cnt;
80d9f0492fSopenharmony_ci    g_hookMgr = HookMgrCreate("moduleTestHook");
81d9f0492fSopenharmony_ci    ASSERT_NE(g_hookMgr, nullptr);
82d9f0492fSopenharmony_ci
83d9f0492fSopenharmony_ci    ret = HookMgrAdd(g_hookMgr, STAGE_TEST_ONE, 0, OhosTestHookMultiThread);
84d9f0492fSopenharmony_ci    EXPECT_EQ(ret, 0);
85d9f0492fSopenharmony_ci    cnt = HookMgrGetHooksCnt(g_hookMgr, STAGE_TEST_ONE);
86d9f0492fSopenharmony_ci    EXPECT_EQ(cnt, 1);
87d9f0492fSopenharmony_ci
88d9f0492fSopenharmony_ci    HOOK_INFO info;
89d9f0492fSopenharmony_ci    info.stage = STAGE_TEST_ONE;
90d9f0492fSopenharmony_ci    info.prio = 1;
91d9f0492fSopenharmony_ci    info.hook = OhosTestHookMultiThreadAnother;
92d9f0492fSopenharmony_ci    info.hookCookie = nullptr;
93d9f0492fSopenharmony_ci    HookMgrAddEx(g_hookMgr, &info);
94d9f0492fSopenharmony_ci    cnt = HookMgrGetHooksCnt(g_hookMgr, STAGE_TEST_ONE);
95d9f0492fSopenharmony_ci    EXPECT_EQ(cnt, 2);
96d9f0492fSopenharmony_ci    cnt = HookMgrGetStagesCnt(g_hookMgr);
97d9f0492fSopenharmony_ci    EXPECT_EQ(cnt, 1);
98d9f0492fSopenharmony_ci    DumpAllHooks(g_hookMgr);
99d9f0492fSopenharmony_ci
100d9f0492fSopenharmony_ci    // test multiThread HookMgrExecute
101d9f0492fSopenharmony_ci    std::vector<std::thread> threads;
102d9f0492fSopenharmony_ci    for (int i = 1; i <= 10; ++i) {
103d9f0492fSopenharmony_ci        threads.push_back(std::thread(HookExecFunc, 10));
104d9f0492fSopenharmony_ci    }
105d9f0492fSopenharmony_ci    for (auto & th : threads) {
106d9f0492fSopenharmony_ci        th.join();
107d9f0492fSopenharmony_ci    }
108d9f0492fSopenharmony_ci    EXPECT_EQ(g_publicData, 200);
109d9f0492fSopenharmony_ci
110d9f0492fSopenharmony_ci    HookMgrAdd(g_hookMgr, STAGE_TEST_ONE, 1, OhosTestHookMultiThreadAnother);
111d9f0492fSopenharmony_ci    cnt = HookMgrGetHooksCnt(g_hookMgr, STAGE_TEST_ONE);
112d9f0492fSopenharmony_ci    EXPECT_EQ(cnt, 2);
113d9f0492fSopenharmony_ci
114d9f0492fSopenharmony_ci    HookMgrDel(g_hookMgr, STAGE_TEST_ONE, OhosTestHookMultiThreadAnother);
115d9f0492fSopenharmony_ci    cnt = HookMgrGetHooksCnt(g_hookMgr, STAGE_TEST_ONE);
116d9f0492fSopenharmony_ci    EXPECT_EQ(cnt, 1);
117d9f0492fSopenharmony_ci    HookMgrDestroy(g_hookMgr);
118d9f0492fSopenharmony_ci}
119d9f0492fSopenharmony_ci
120d9f0492fSopenharmony_ci} // namespace init_ut
121