• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cassert>
17 #include <cstring>
18 #include <gtest/gtest.h>
19 
20 #include "libabckit/include/c/abckit.h"
21 #include "helpers/helpers.h"
22 #include "helpers/helpers_runtime.h"
23 #include "libabckit/include/c/metadata_core.h"
24 #include "metadata_inspect_impl.h"
25 #include "libabckit/include/c/isa/isa_dynamic.h"
26 #include "ir_impl.h"
27 #include "logger.h"
28 
29 namespace libabckit::test {
30 
31 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 static auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35 
36 static constexpr auto MODIFIED = ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic_modified.abc";
37 
38 class LibAbcKitInspectApiModulesTest : public ::testing::Test {};
39 
40 // ========================================
41 // Helpers
42 // ========================================
43 
ModuleNamesCollector(AbckitCoreModule * module,void * data)44 static bool ModuleNamesCollector(AbckitCoreModule *module, void *data)
45 {
46     helpers::AssertModuleVisitor(module, data);
47 
48     AbckitFile *file = g_implI->moduleGetFile(module);
49     EXPECT_TRUE(g_impl->getLastError() == ABCKIT_STATUS_NO_ERROR);
50     EXPECT_TRUE(file != nullptr);
51     auto names = reinterpret_cast<std::set<std::string> *>(data);
52     auto moduleName = g_implI->moduleGetName(module);
53     EXPECT_TRUE(g_impl->getLastError() == ABCKIT_STATUS_NO_ERROR);
54 
55     auto name = helpers::AbckitStringToString(moduleName);
56     LIBABCKIT_LOG(DEBUG) << "module name: " << name << std::endl;
57     EXPECT_TRUE(names->find(name.data()) == names->end());
58     names->insert(name.data());
59 
60     return true;
61 }
62 
ModuleCollector(AbckitCoreModule * module,void * data)63 static bool ModuleCollector(AbckitCoreModule *module, void *data)
64 {
65     helpers::AssertModuleVisitor(module, data);
66 
67     auto modules = reinterpret_cast<std::set<AbckitCoreModule *> *>(data);
68     EXPECT_TRUE(modules->find(module) == modules->end());
69     modules->insert(module);
70 
71     return true;
72 }
73 
ModuleImportNamesCollector(AbckitCoreImportDescriptor * id,void * data)74 static bool ModuleImportNamesCollector(AbckitCoreImportDescriptor *id, void *data)
75 {
76     helpers::AssertImportVisitor(id, data);
77 
78     AbckitFile *file = g_implI->importDescriptorGetFile(id);
79     EXPECT_TRUE(g_impl->getLastError() == ABCKIT_STATUS_NO_ERROR);
80     EXPECT_TRUE(file != nullptr);
81     auto names = reinterpret_cast<std::unordered_map<std::string, size_t> *>(data);
82     auto importName = g_implI->importDescriptorGetName(id);
83     EXPECT_TRUE(g_impl->getLastError() == ABCKIT_STATUS_NO_ERROR);
84 
85     auto name = helpers::AbckitStringToString(importName);
86     LIBABCKIT_LOG(DEBUG) << "import name: " << name << std::endl;
87     auto found = names->find(name.data());
88     if (found != names->end()) {
89         found->second += 1;
90     } else {
91         names->emplace(name, 1);
92     }
93 
94     return true;
95 }
96 
ModuleImportAliasCollector(AbckitCoreImportDescriptor * id,void * data)97 static bool ModuleImportAliasCollector(AbckitCoreImportDescriptor *id, void *data)
98 {
99     helpers::AssertImportVisitor(id, data);
100 
101     AbckitFile *file = g_implI->importDescriptorGetFile(id);
102     EXPECT_TRUE(g_impl->getLastError() == ABCKIT_STATUS_NO_ERROR);
103     EXPECT_TRUE(file != nullptr);
104     auto names = reinterpret_cast<std::set<std::string> *>(data);
105     auto importName = g_implI->importDescriptorGetAlias(id);
106     EXPECT_TRUE(g_impl->getLastError() == ABCKIT_STATUS_NO_ERROR);
107 
108     auto name = helpers::AbckitStringToString(importName);
109     LIBABCKIT_LOG(DEBUG) << "import alias: " << name << std::endl;
110     EXPECT_TRUE(names->find(name.data()) == names->end());
111     names->insert(name.data());
112 
113     return true;
114 }
115 
ModuleExportNamesCollector(AbckitCoreExportDescriptor * ed,void * data)116 static bool ModuleExportNamesCollector(AbckitCoreExportDescriptor *ed, void *data)
117 {
118     helpers::AssertExportVisitor(ed, data);
119 
120     AbckitFile *file = g_implI->exportDescriptorGetFile(ed);
121     EXPECT_TRUE(g_impl->getLastError() == ABCKIT_STATUS_NO_ERROR);
122     EXPECT_TRUE(file != nullptr);
123     auto names = reinterpret_cast<std::unordered_map<std::string, size_t> *>(data);
124     auto exportName = g_implI->exportDescriptorGetName(ed);
125     EXPECT_TRUE(g_impl->getLastError() == ABCKIT_STATUS_NO_ERROR);
126 
127     auto name = helpers::AbckitStringToString(exportName);
128     LIBABCKIT_LOG(DEBUG) << "export name: " << name << std::endl;
129     auto found = names->find(name.data());
130     if (found != names->end()) {
131         found->second += 1;
132     } else {
133         names->emplace(name, 1);
134     }
135 
136     return true;
137 }
138 
ModuleExportAliasCollector(AbckitCoreExportDescriptor * ed,void * data)139 static bool ModuleExportAliasCollector(AbckitCoreExportDescriptor *ed, void *data)
140 {
141     helpers::AssertExportVisitor(ed, data);
142 
143     AbckitFile *file = g_implI->exportDescriptorGetFile(ed);
144     EXPECT_TRUE(g_impl->getLastError() == ABCKIT_STATUS_NO_ERROR);
145     EXPECT_TRUE(file != nullptr);
146     auto names = reinterpret_cast<std::set<std::string> *>(data);
147     auto exportName = g_implI->exportDescriptorGetAlias(ed);
148     EXPECT_TRUE(g_impl->getLastError() == ABCKIT_STATUS_NO_ERROR);
149 
150     auto name = helpers::AbckitStringToString(exportName);
151     LIBABCKIT_LOG(DEBUG) << "export alias: " << name << std::endl;
152     EXPECT_TRUE(names->find(name.data()) == names->end());
153     names->insert(name.data());
154 
155     return true;
156 }
157 
GetFileTarget(AbckitFile * file,const char * moduleName)158 static AbckitTarget GetFileTarget(AbckitFile *file, const char *moduleName)
159 {
160     helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName};
161     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
162     EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
163     EXPECT_NE(ctxFinder.module, nullptr);
164     auto *m = ctxFinder.module;
165 
166     return g_implI->moduleGetTarget(m);
167 }
168 
169 // ========================================
170 // Modules Tests
171 // ========================================
172 
173 // Test: test-kind=api, api=InspectApiImpl::moduleGetName, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicModuleGetName)174 TEST_F(LibAbcKitInspectApiModulesTest, DynamicModuleGetName)
175 {
176     AbckitFile *file = nullptr;
177     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
178 
179     std::set<std::string> gotNames;
180 
181     g_implI->fileEnumerateModules(file, &gotNames, ModuleNamesCollector);
182     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
183 
184     std::set<std::string> expectedNames = {"modules_dynamic", "modules/module1", "modules/module2", "modules/module3"};
185     ASSERT_EQ(expectedNames.size(), gotNames.size());
186     for (auto &expectedName : expectedNames) {
187         ASSERT_NE(gotNames.find(expectedName), gotNames.end());
188     }
189 
190     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
191     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
192     g_impl->closeFile(file);
193     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
194 }
195 
196 // NOTE: fix after ets2bundle integrated into abckit unit tests
197 // Test: test-kind=api, api=InspectApiImpl::moduleIsExternal, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicModuleIsExternal)198 TEST_F(LibAbcKitInspectApiModulesTest, DynamicModuleIsExternal)
199 {
200     AbckitFile *file = nullptr;
201     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic_external.abc", &file);
202 
203     std::set<AbckitCoreModule *> gotModules;
204 
205     g_implI->fileEnumerateModules(file, &gotModules, ModuleCollector);
206     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
207 
208     std::unordered_map<std::string, bool> expected = {{"modules_dynamic_external", false},
209                                                       {"modules/module1", false},
210                                                       {"modules/module2", false},
211                                                       {"modules/module3", false},
212                                                       {"external_module", true}};
213     ASSERT_EQ(expected.size(), gotModules.size());
214     for (auto *module : gotModules) {
215         auto name = helpers::AbckitStringToString(g_implI->moduleGetName(module));
216         ASSERT_NE(expected.find(name.data()), expected.end());
217         ASSERT_EQ(g_implI->moduleIsExternal(module), expected[name.data()]);
218     }
219 
220     constexpr auto OUTPUT_PATH =
221         ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic_external_modified.abc";
222     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
223     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
224     g_impl->closeFile(file);
225     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
226 }
227 
228 // Test: test-kind=api, api=InspectApiImpl::moduleGetFile, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicModuleGetFile)229 TEST_F(LibAbcKitInspectApiModulesTest, DynamicModuleGetFile)
230 {
231     AbckitFile *file = nullptr;
232     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
233 
234     std::set<AbckitCoreModule *> gotModules;
235 
236     g_implI->fileEnumerateModules(file, &gotModules, ModuleCollector);
237     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
238 
239     ASSERT_EQ(gotModules.size(), 4U);
240     for (auto *module : gotModules) {
241         auto file = g_implI->moduleGetFile(module);
242         ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
243         ASSERT_EQ(file, file);
244     }
245 
246     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
247     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
248     g_impl->closeFile(file);
249     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
250 }
251 
252 // ========================================
253 // Imports
254 // ========================================
255 
256 // Test: test-kind=api, api=InspectApiImpl::moduleEnumerateImports, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicModuleEnumerateImports)257 TEST_F(LibAbcKitInspectApiModulesTest, DynamicModuleEnumerateImports)
258 {
259     AbckitFile *file = nullptr;
260     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
261 
262     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules_dynamic"};
263     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
264     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
265     ASSERT_NE(ctxFinder.module, nullptr);
266     auto *m = ctxFinder.module;
267 
268     std::set<AbckitCoreImportDescriptor *> gotImports;
269     g_implI->moduleEnumerateImports(m, &gotImports, helpers::ModuleImportsCollector);
270     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
271 
272     ASSERT_EQ(gotImports.size(), 5U);
273 
274     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
275     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
276     g_impl->closeFile(file);
277     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
278 }
279 
280 // Test: test-kind=api, api=InspectApiImpl::importDescriptorGetName, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicImportDescriptorGetName)281 TEST_F(LibAbcKitInspectApiModulesTest, DynamicImportDescriptorGetName)
282 {
283     AbckitFile *file = nullptr;
284     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
285 
286     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules_dynamic"};
287     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
288     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
289     ASSERT_NE(ctxFinder.module, nullptr);
290     auto *m = ctxFinder.module;
291 
292     std::unordered_map<std::string, size_t> gotImportNames;
293     g_implI->moduleEnumerateImports(m, &gotImportNames, ModuleImportNamesCollector);
294     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
295 
296     std::set<std::string> expectedNames = {"*", "regularImportFunc1FromModule1", "regularImportFunc1FromModule2",
297                                            "default"};
298     ASSERT_EQ(expectedNames.size(), gotImportNames.size());
299     for (auto &expectedName : expectedNames) {
300         [[maybe_unused]] auto found = gotImportNames.find(expectedName);
301         ASSERT_NE(found, gotImportNames.end());
302         if (expectedName == "default") {
303             ASSERT_EQ(found->second, 2U);
304         } else {
305             ASSERT_EQ(found->second, 1);
306         }
307     }
308 
309     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
310     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
311     g_impl->closeFile(file);
312     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
313 }
314 
315 // Test: test-kind=api, api=InspectApiImpl::importDescriptorGetAlias, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicImportDescriptorGetAlias)316 TEST_F(LibAbcKitInspectApiModulesTest, DynamicImportDescriptorGetAlias)
317 {
318     AbckitFile *file = nullptr;
319     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
320 
321     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules_dynamic"};
322     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
323     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
324     ASSERT_NE(ctxFinder.module, nullptr);
325     auto *m = ctxFinder.module;
326 
327     std::set<std::string> gotImportAliases;
328     g_implI->moduleEnumerateImports(m, &gotImportAliases, ModuleImportAliasCollector);
329     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
330 
331     std::set<std::string> expectedNames = {"NS", "regularImportFunc1FromModule1",
332                                            "regularDefaultImportFunc2FromModule2",
333                                            "regularDefaultImportFunc1FromModule3", "MF1M2"};
334     ASSERT_EQ(expectedNames.size(), gotImportAliases.size());
335     for (auto &expectedName : expectedNames) {
336         ASSERT_NE(gotImportAliases.find(expectedName), gotImportAliases.end());
337     }
338 
339     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
340     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
341     g_impl->closeFile(file);
342     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
343 }
344 
345 // Test: test-kind=api, api=InspectApiImpl::importDescriptorGetFile, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicImportDescriptorGetFile)346 TEST_F(LibAbcKitInspectApiModulesTest, DynamicImportDescriptorGetFile)
347 {
348     AbckitFile *file = nullptr;
349     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
350 
351     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules_dynamic"};
352     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
353     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
354     ASSERT_NE(ctxFinder.module, nullptr);
355     auto *m = ctxFinder.module;
356 
357     std::set<AbckitCoreImportDescriptor *> gotImports;
358     g_implI->moduleEnumerateImports(m, &gotImports, helpers::ModuleImportsCollector);
359     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
360 
361     ASSERT_EQ(gotImports.size(), 5U);
362     for (auto &gotImport : gotImports) {
363         auto file = g_implI->importDescriptorGetFile(gotImport);
364         ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
365         ASSERT_EQ(file, g_implI->moduleGetFile(m));
366     }
367 
368     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
369     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
370     g_impl->closeFile(file);
371     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
372 }
373 
374 // Test: test-kind=api, api=InspectApiImpl::importDescriptorGetImportingModule, abc-kind=ArkTS1, category=positive,
375 // extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicImportDescriptorGetImportingModule)376 TEST_F(LibAbcKitInspectApiModulesTest, DynamicImportDescriptorGetImportingModule)
377 {
378     AbckitFile *file = nullptr;
379     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
380 
381     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules_dynamic"};
382     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
383     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
384     ASSERT_NE(ctxFinder.module, nullptr);
385     auto *m = ctxFinder.module;
386 
387     std::set<AbckitCoreImportDescriptor *> gotImports;
388     g_implI->moduleEnumerateImports(m, &gotImports, helpers::ModuleImportsCollector);
389     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
390 
391     ASSERT_EQ(gotImports.size(), 5U);
392     for (auto &gotImport : gotImports) {
393         auto impM = g_implI->importDescriptorGetImportingModule(gotImport);
394         ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
395         ASSERT_EQ(impM, m);
396     }
397 
398     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
399     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
400     g_impl->closeFile(file);
401     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
402 }
403 
404 // Test: test-kind=api, api=InspectApiImpl::importDescriptorGetImportedModule, abc-kind=ArkTS1, category=positive,
405 // extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicImportDescriptorGetImportedModule)406 TEST_F(LibAbcKitInspectApiModulesTest, DynamicImportDescriptorGetImportedModule)
407 {
408     AbckitFile *file = nullptr;
409     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
410 
411     std::unordered_map<std::string, AbckitCoreModule *> gotModulesMap;
412 
413     g_implI->fileEnumerateModules(file, &gotModulesMap, helpers::NameToModuleCollector);
414     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
415 
416     std::set<std::string> expectedNames = {"modules_dynamic", "modules/module1", "modules/module2", "modules/module3"};
417     ASSERT_EQ(expectedNames.size(), gotModulesMap.size());
418     for (auto &expectedName : expectedNames) {
419         ASSERT_NE(gotModulesMap.find(expectedName), gotModulesMap.end());
420     }
421 
422     std::set<AbckitCoreImportDescriptor *> gotImports;
423     g_implI->moduleEnumerateImports(gotModulesMap.find("modules_dynamic")->second, &gotImports,
424                                     helpers::ModuleImportsCollector);
425     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
426     std::unordered_map<std::string, AbckitCoreModule *> expected = {
427         {"NS", gotModulesMap.find("modules/module1")->second},
428         {"regularImportFunc1FromModule1", gotModulesMap.find("modules/module1")->second},
429         {"regularDefaultImportFunc2FromModule2", gotModulesMap.find("modules/module2")->second},
430         {"regularDefaultImportFunc1FromModule3", gotModulesMap.find("modules/module3")->second},
431         {"MF1M2", gotModulesMap.find("modules/module2")->second}};
432 
433     ASSERT_EQ(gotImports.size(), 5U);
434     for (auto &gotImport : gotImports) {
435         auto impM = g_implI->importDescriptorGetImportedModule(gotImport);
436         ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
437         auto impName = g_implI->importDescriptorGetAlias(gotImport);
438         ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
439         auto strName = helpers::AbckitStringToString(impName);
440         ASSERT_NE(expected.find(strName.data()), expected.end());
441         ASSERT_EQ(impM, expected.find(strName.data())->second);
442     }
443 
444     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
445     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
446     g_impl->closeFile(file);
447     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
448 }
449 
450 // ========================================
451 // Exports
452 // ========================================
453 
454 // Test: test-kind=api, api=InspectApiImpl::moduleEnumerateExports, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicModuleEnumerateExports)455 TEST_F(LibAbcKitInspectApiModulesTest, DynamicModuleEnumerateExports)
456 {
457     AbckitFile *file = nullptr;
458     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
459 
460     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules_dynamic"};
461     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
462     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
463     ASSERT_NE(ctxFinder.module, nullptr);
464     auto *m = ctxFinder.module;
465 
466     std::set<AbckitCoreExportDescriptor *> gotExports;
467     g_implI->moduleEnumerateExports(m, &gotExports, helpers::ModuleExportsCollector);
468     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
469 
470     ASSERT_EQ(gotExports.size(), 10U);
471 
472     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
473     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
474     g_impl->closeFile(file);
475     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
476 }
477 
478 // Test: test-kind=api, api=InspectApiImpl::exportDescriptorGetName, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicExportDescriptorGetName)479 TEST_F(LibAbcKitInspectApiModulesTest, DynamicExportDescriptorGetName)
480 {
481     AbckitFile *file = nullptr;
482     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
483 
484     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules_dynamic"};
485     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
486     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
487     ASSERT_NE(ctxFinder.module, nullptr);
488     auto *m = ctxFinder.module;
489 
490     std::unordered_map<std::string, size_t> gotExportNames;
491     g_implI->moduleEnumerateExports(m, &gotExportNames, ModuleExportNamesCollector);
492     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
493 
494     std::set<std::string> expectedNames = {"*",
495                                            "default",
496                                            "LocalExportClass",
497                                            "LocalExportFunc",
498                                            "LocalExportLet",
499                                            "LocalExportVar",
500                                            "indirectExportFunc1FromModule1",
501                                            "indirectExportFunc2FromModule1"};
502     ASSERT_EQ(expectedNames.size(), gotExportNames.size());
503     for (auto &expectedName : expectedNames) {
504         [[maybe_unused]] auto found = gotExportNames.find(expectedName);
505         ASSERT_NE(found, gotExportNames.end());
506         if (expectedName == "*") {
507             ASSERT_EQ(found->second, 3U);
508         } else {
509             ASSERT_EQ(found->second, 1);
510         }
511     }
512 
513     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
514     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
515     g_impl->closeFile(file);
516     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
517 }
518 
519 // Test: test-kind=api, api=InspectApiImpl::exportDescriptorGetAlias, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicExportDescriptorGetAlias)520 TEST_F(LibAbcKitInspectApiModulesTest, DynamicExportDescriptorGetAlias)
521 {
522     AbckitFile *file = nullptr;
523     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
524 
525     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules_dynamic"};
526     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
527     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
528     ASSERT_NE(ctxFinder.module, nullptr);
529     auto *m = ctxFinder.module;
530 
531     std::set<std::string> gotExportAliases;
532     g_implI->moduleEnumerateExports(m, &gotExportAliases, ModuleExportAliasCollector);
533     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
534 
535     std::set<std::string> expectedNames = {"",
536                                            "indirectExportFunc1FromModule1",
537                                            "LocalDefaultExportClass",
538                                            "LocalExportClass",
539                                            "LocalExportFunc",
540                                            "LocalExportLet",
541                                            "LocalExportVar",
542                                            "StarExport",
543                                            "StarExport2",
544                                            "MF2M1"};
545     ASSERT_EQ(expectedNames.size(), gotExportAliases.size());
546     for (auto &expectedName : expectedNames) {
547         ASSERT_NE(gotExportAliases.find(expectedName), gotExportAliases.end());
548     }
549 
550     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
551     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
552     g_impl->closeFile(file);
553     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
554 }
555 
556 // Test: test-kind=api, api=InspectApiImpl::exportDescriptorGetFile, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicExportDescriptorGetFile)557 TEST_F(LibAbcKitInspectApiModulesTest, DynamicExportDescriptorGetFile)
558 {
559     AbckitFile *file = nullptr;
560     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
561 
562     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules_dynamic"};
563     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
564     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
565     ASSERT_NE(ctxFinder.module, nullptr);
566     auto *m = ctxFinder.module;
567 
568     std::set<AbckitCoreExportDescriptor *> gotExports;
569     g_implI->moduleEnumerateExports(m, &gotExports, helpers::ModuleExportsCollector);
570     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
571 
572     ASSERT_EQ(gotExports.size(), 10U);
573     for (auto &gotExport : gotExports) {
574         auto file = g_implI->exportDescriptorGetFile(gotExport);
575         ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
576         ASSERT_EQ(file, g_implI->moduleGetFile(m));
577     }
578 
579     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
580     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
581     g_impl->closeFile(file);
582     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
583 }
584 
585 // Test: test-kind=api, api=InspectApiImpl::exportDescriptorGetExportingModule, abc-kind=ArkTS1, category=positive,
586 // extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicExportDescriptorGetExportingModule)587 TEST_F(LibAbcKitInspectApiModulesTest, DynamicExportDescriptorGetExportingModule)
588 {
589     AbckitFile *file = nullptr;
590     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
591 
592     helpers::ModuleByNameContext ctxFinder = {nullptr, "modules_dynamic"};
593     g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
594     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
595     ASSERT_NE(ctxFinder.module, nullptr);
596     auto *m = ctxFinder.module;
597 
598     std::set<AbckitCoreExportDescriptor *> gotExports;
599     g_implI->moduleEnumerateExports(m, &gotExports, helpers::ModuleExportsCollector);
600     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
601 
602     ASSERT_EQ(gotExports.size(), 10U);
603     for (auto &gotExport : gotExports) {
604         auto expM = g_implI->exportDescriptorGetExportingModule(gotExport);
605         ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
606         ASSERT_EQ(expM, m);
607     }
608 
609     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
610     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
611     g_impl->closeFile(file);
612     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
613 }
614 
615 // Test: test-kind=api, api=InspectApiImpl::exportDescriptorGetExportedModule, abc-kind=ArkTS1, category=positive,
616 // extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicExportDescriptorGetExportedModule)617 TEST_F(LibAbcKitInspectApiModulesTest, DynamicExportDescriptorGetExportedModule)
618 {
619     AbckitFile *file = nullptr;
620     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic.abc", &file);
621 
622     std::unordered_map<std::string, AbckitCoreModule *> gotModulesMap;
623 
624     g_implI->fileEnumerateModules(file, &gotModulesMap, helpers::NameToModuleCollector);
625     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
626 
627     std::set<std::string> expectedNames = {"modules_dynamic", "modules/module1", "modules/module2", "modules/module3"};
628     ASSERT_EQ(expectedNames.size(), gotModulesMap.size());
629     for (auto &expectedName : expectedNames) {
630         ASSERT_NE(gotModulesMap.find(expectedName), gotModulesMap.end());
631     }
632 
633     std::set<AbckitCoreExportDescriptor *> gotExports;
634     g_implI->moduleEnumerateExports(gotModulesMap.find("modules_dynamic")->second, &gotExports,
635                                     helpers::ModuleExportsCollector);
636     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
637     std::unordered_map<std::string, AbckitCoreModule *> expected = {
638         {"", gotModulesMap.find("modules/module2")->second},
639         {"indirectExportFunc1FromModule1", gotModulesMap.find("modules/module1")->second},
640         {"MF2M1", gotModulesMap.find("modules/module1")->second},
641         {"LocalExportClass", gotModulesMap.find("modules_dynamic")->second},
642         {"LocalExportFunc", gotModulesMap.find("modules_dynamic")->second},
643         {"LocalExportLet", gotModulesMap.find("modules_dynamic")->second},
644         {"LocalExportVar", gotModulesMap.find("modules_dynamic")->second},
645         {"StarExport", gotModulesMap.find("modules/module1")->second},
646         {"StarExport2", gotModulesMap.find("modules/module2")->second},
647         {"LocalDefaultExportClass", gotModulesMap.find("modules_dynamic")->second}};
648 
649     ASSERT_EQ(gotExports.size(), 10U);
650     for (auto &gotExport : gotExports) {
651         auto impM = g_implI->exportDescriptorGetExportedModule(gotExport);
652         ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
653         auto impName = g_implI->exportDescriptorGetAlias(gotExport);
654         ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
655         auto strName = helpers::AbckitStringToString(impName);
656         ASSERT_NE(expected.find(strName.data()), expected.end());
657         ASSERT_EQ(impM, expected.find(strName.data())->second);
658     }
659 
660     g_impl->writeAbc(file, MODIFIED, strlen(MODIFIED));
661     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
662     g_impl->closeFile(file);
663     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
664 }
665 
666 // Test: test-kind=api, api=InspectApiImpl::fileEnumerateExternalModules, abc-kind=ArkTS1, category=positive,
667 // extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicFileEnumerateExternalModules)668 TEST_F(LibAbcKitInspectApiModulesTest, DynamicFileEnumerateExternalModules)
669 {
670     AbckitFile *file = nullptr;
671     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic_external.abc", &file);
672 
673     std::set<AbckitCoreModule *> gotModules;
674 
675     g_implI->fileEnumerateExternalModules(file, &gotModules, ModuleCollector);
676     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
677 
678     std::set<std::string> expected = {"external_module"};
679     ASSERT_EQ(expected.size(), gotModules.size());
680     for (auto *module : gotModules) {
681         auto name = helpers::AbckitStringToString(g_implI->moduleGetName(module));
682         ASSERT_NE(expected.find(name.data()), expected.end());
683     }
684 
685     constexpr auto OUTPUT_PATH =
686         ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/modules_dynamic_external_modified.abc";
687     g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
688     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
689     g_impl->closeFile(file);
690     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
691 }
692 
693 // Test: test-kind=api, api=InspectApiImpl::moduleGetTarget, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiModulesTest,DynamicModuleGetTarget)694 TEST_F(LibAbcKitInspectApiModulesTest, DynamicModuleGetTarget)
695 {
696     AbckitFile *jsFile = nullptr;
697     AbckitFile *tsFile = nullptr;
698 
699     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/targets/JS_target.abc", &jsFile);
700     helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/modules/targets/TS_target.abc", &tsFile);
701 
702     EXPECT_EQ(GetFileTarget(jsFile, "JS_target"), ABCKIT_TARGET_JS);
703     EXPECT_EQ(GetFileTarget(tsFile, "TS_target"), ABCKIT_TARGET_ARK_TS_V1);
704 
705     g_impl->closeFile(jsFile);
706     g_impl->closeFile(tsFile);
707 }
708 
709 }  // namespace libabckit::test
710