1 /**
2 * Copyright (c) 2024 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 <gtest/gtest.h>
17
18 #include "libabckit/include/c/abckit.h"
19 #include "helpers/helpers.h"
20
21 namespace libabckit::test {
22
23 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
24 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
25 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
26 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
27
28 class LibAbcKitGraphStuff : public ::testing::Test {};
29
30 struct ClassData {
31 const char *className = nullptr;
32 std::vector<const char *> classMethods = {};
33 };
34
35 struct ModuleData {
36 const char *moduleName = nullptr;
37 std::vector<const char *> moduleMethods = {};
38 };
39
40 // Test: test-kind=api, api=ModifyApiImpl::functionSetGraph, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitGraphStuff,FunctionSetGraphStatic)41 TEST_F(LibAbcKitGraphStuff, FunctionSetGraphStatic)
42 {
43 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_static.abc";
44 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
45 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
46
47 std::vector<struct ClassData> userData = {{"ClassA", {"foo", "bar"}}, {"ClassB", {"baz", "func"}}};
48
49 g_implI->fileEnumerateModules(file, &userData, [](AbckitCoreModule *m, void *data) {
50 auto *userData = reinterpret_cast<std::vector<struct ClassData> *>(data);
51
52 for (const auto &classData : *userData) {
53 helpers::ClassByNameContext classCtxFinder = {nullptr, classData.className};
54 g_implI->moduleEnumerateClasses(m, &classCtxFinder, helpers::ClassByNameFinder);
55 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
56 EXPECT_NE(classCtxFinder.klass, nullptr);
57
58 for (auto *method : classData.classMethods) {
59 helpers::MethodByNameContext methodCtxFinder = {nullptr, method};
60 g_implI->classEnumerateMethods(classCtxFinder.klass, &methodCtxFinder, helpers::MethodByNameFinder);
61 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
62 EXPECT_NE(methodCtxFinder.method, nullptr);
63
64 auto *graph = g_implI->createGraphFromFunction(methodCtxFinder.method);
65 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
66
67 g_implM->functionSetGraph(methodCtxFinder.method, graph);
68 g_impl->destroyGraph(graph);
69 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
70 }
71 }
72
73 return true;
74 });
75 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
76
77 g_impl->closeFile(file);
78 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
79 }
80
81 // Test: test-kind=api, api=ModifyApiImpl::functionSetGraph, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitGraphStuff,CreateGraphFromFunctionStatic)82 TEST_F(LibAbcKitGraphStuff, CreateGraphFromFunctionStatic)
83 {
84 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_static.abc";
85 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
86 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
87
88 std::vector<struct ClassData> userData = {{"ClassA", {"foo", "bar"}}, {"ClassB", {"baz", "func"}}};
89
90 g_implI->fileEnumerateModules(file, &userData, [](AbckitCoreModule *m, void *data) {
91 auto *userData = reinterpret_cast<std::vector<struct ClassData> *>(data);
92
93 for (const auto &classData : *userData) {
94 helpers::ClassByNameContext classCtxFinder = {nullptr, classData.className};
95 g_implI->moduleEnumerateClasses(m, &classCtxFinder, helpers::ClassByNameFinder);
96 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
97 EXPECT_NE(classCtxFinder.klass, nullptr);
98
99 for (auto *method : classData.classMethods) {
100 helpers::MethodByNameContext methodCtxFinder = {nullptr, method};
101 g_implI->classEnumerateMethods(classCtxFinder.klass, &methodCtxFinder, helpers::MethodByNameFinder);
102 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
103 EXPECT_NE(methodCtxFinder.method, nullptr);
104
105 auto *graph = g_implI->createGraphFromFunction(methodCtxFinder.method);
106 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
107
108 g_implM->functionSetGraph(methodCtxFinder.method, graph);
109 g_impl->destroyGraph(graph);
110 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
111 }
112 }
113
114 return true;
115 });
116 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
117
118 g_impl->closeFile(file);
119 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
120 }
121
122 // Test: test-kind=api, api=ApiImpl::destroyGraph, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitGraphStuff,DestroyGraphStatic)123 TEST_F(LibAbcKitGraphStuff, DestroyGraphStatic)
124 {
125 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_static.abc";
126 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
127 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
128
129 std::vector<struct ClassData> userData = {{"ClassA", {"foo", "bar"}}, {"ClassB", {"baz", "func"}}};
130
131 g_implI->fileEnumerateModules(file, &userData, [](AbckitCoreModule *m, void *data) {
132 auto *userData = reinterpret_cast<std::vector<struct ClassData> *>(data);
133
134 for (const auto &classData : *userData) {
135 helpers::ClassByNameContext classCtxFinder = {nullptr, classData.className};
136 g_implI->moduleEnumerateClasses(m, &classCtxFinder, helpers::ClassByNameFinder);
137 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
138 EXPECT_NE(classCtxFinder.klass, nullptr);
139
140 for (auto *method : classData.classMethods) {
141 helpers::MethodByNameContext methodCtxFinder = {nullptr, method};
142 g_implI->classEnumerateMethods(classCtxFinder.klass, &methodCtxFinder, helpers::MethodByNameFinder);
143 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
144 EXPECT_NE(methodCtxFinder.method, nullptr);
145
146 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
147 auto *graph = g_implI->createGraphFromFunction(methodCtxFinder.method);
148 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
149 g_impl->destroyGraph(graph);
150 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
151 }
152 }
153
154 return true;
155 });
156 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
157
158 g_impl->closeFile(file);
159 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
160 }
161
162 // Test: test-kind=api, api=InspectApiImpl::createGraphFromFunction, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitGraphStuff,CreateGraphFromFunctionDynamic)163 TEST_F(LibAbcKitGraphStuff, CreateGraphFromFunctionDynamic)
164 {
165 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_dynamic.abc";
166 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
167 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
168
169 struct ModuleData userData = {"abc_dynamic", {"foo", "bar", "baz", "func"}};
170
171 helpers::ModuleByNameContext moduleCtxFinder = {nullptr, userData.moduleName};
172 g_implI->fileEnumerateModules(file, &moduleCtxFinder, helpers::ModuleByNameFinder);
173 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
174 ASSERT_NE(moduleCtxFinder.module, nullptr);
175
176 for (auto method : userData.moduleMethods) {
177 auto *found = helpers::FindMethodByName(file, method);
178 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
179 ASSERT_NE(found, nullptr);
180
181 auto *graph = g_implI->createGraphFromFunction(found);
182 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
183 g_implM->functionSetGraph(found, graph);
184 g_impl->destroyGraph(graph);
185 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
186 }
187
188 g_impl->closeFile(file);
189 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
190 }
191
192 // Test: test-kind=api, api=ModifyApiImpl::functionSetGraph, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitGraphStuff,FunctionSetGraphDynamic)193 TEST_F(LibAbcKitGraphStuff, FunctionSetGraphDynamic)
194 {
195 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_dynamic.abc";
196 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
197 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
198
199 struct ModuleData userData = {"abc_dynamic", {"foo", "bar", "baz", "func"}};
200
201 helpers::ModuleByNameContext moduleCtxFinder = {nullptr, userData.moduleName};
202 g_implI->fileEnumerateModules(file, &moduleCtxFinder, helpers::ModuleByNameFinder);
203 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
204 ASSERT_NE(moduleCtxFinder.module, nullptr);
205
206 for (auto method : userData.moduleMethods) {
207 auto *found = helpers::FindMethodByName(file, method);
208 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
209 ASSERT_NE(found, nullptr);
210
211 auto *graph = g_implI->createGraphFromFunction(found);
212 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
213 g_implM->functionSetGraph(found, graph);
214 g_impl->destroyGraph(graph);
215 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
216 }
217
218 g_impl->closeFile(file);
219 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
220 }
221
222 // Test: test-kind=api, api=ApiImpl::destroyGraph, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitGraphStuff,DestroyGraphDynamic)223 TEST_F(LibAbcKitGraphStuff, DestroyGraphDynamic)
224 {
225 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_dynamic.abc";
226 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
227 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
228
229 struct ModuleData userData = {"abc_dynamic", {"foo", "bar", "baz", "func"}};
230
231 helpers::ModuleByNameContext moduleCtxFinder = {nullptr, userData.moduleName};
232 g_implI->fileEnumerateModules(file, &moduleCtxFinder, helpers::ModuleByNameFinder);
233 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
234 ASSERT_NE(moduleCtxFinder.module, nullptr);
235
236 for (auto method : userData.moduleMethods) {
237 auto *found = helpers::FindMethodByName(file, method);
238 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
239 ASSERT_NE(found, nullptr);
240
241 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
242 auto *graph = g_implI->createGraphFromFunction(found);
243 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
244 g_impl->destroyGraph(graph);
245 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
246 }
247
248 g_impl->closeFile(file);
249 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
250 }
251
252 } // namespace libabckit::test
253