• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <cstdint>
17 #include <fstream>
18 #include <memory>
19 #include <string>
20 #include <utility>
21 
22 #include "gtest/gtest.h"
23 
24 #include "ecmascript/napi/include/jsnapi.h"
25 #include "ecmascript/ohos/ohos_pkg_args.h"
26 #include "ecmascript/ohos/enable_aot_list_helper.h"
27 #include "ecmascript/ohos/tests/mock/mock_enable_aot_list_helper.h"
28 #include "ecmascript/platform/file.h"
29 #include "ecmascript/tests/test_helper.h"
30 
31 using namespace panda;
32 using namespace panda::ecmascript;
33 using namespace panda::ecmascript::kungfu;
34 
35 namespace panda::test {
36 class OhosTest : public testing::Test {
37 public:
SetUpTestCase()38     static void SetUpTestCase()
39     {
40         GTEST_LOG_(INFO) << "SetUpTestCase";
41     }
42 
TearDownTestCase()43     static void TearDownTestCase()
44     {
45         GTEST_LOG_(INFO) << "TearDownCase";
46     }
47 
SetUp()48     void SetUp() override
49     {
50         runtimeOptions_.SetPGOProfilerPath("");
51         runtimeOptions_.SetTargetCompilerMode("partial");
52         runtimeOptions_.SetAOTOutputFile("/data/app/el1/public/aot_compiler/ark_cache/com.ohos.test/arm64/phone");
53         runtimeOptions_.SetCompilerPkgJsonInfo(
54             BuildOhosPkgJson("/data/app/el1/100/aot_compiler/ark_profile/com.ohos.test"));
55         runtimeOptions_.SetCompilerFrameworkAbcPath("/etc/abc/framework");
56         runtimeOptions_.SetCompilerEnableExternalPkg(true);
57         runtimeOptions_.SetCompilerExternalPkgJsonInfo(BuildOhosExternalPkgJson());
58         vm_ = JSNApi::CreateEcmaVM(runtimeOptions_);
59         ASSERT(vm_ != nullptr);
60         vm_->GetJSThread()->ManagedCodeBegin();
61     }
62 
TearDown()63     void TearDown() override
64     {
65         vm_->GetJSThread()->ManagedCodeEnd();
66         ohos::EnableAotJitListHelper::GetInstance()->Clear();
67         JSNApi::DestroyJSVM(vm_);
68         vm_ = nullptr;
69     }
70 
BuildOhosExternalPkgJson()71     static std::string BuildOhosExternalPkgJson()
72     {
73         return "[" + BuildOhosPkgJson("", TEST_BUNDLE_NAME, "entry1") + ", " +
74                BuildOhosPkgJson("", TEST_BUNDLE_NAME, "entry2") + "]";
75     }
76 
BuildOhosPkgJson(const std::string & pgoDir,const std::string & bundleName=TEST_BUNDLE_NAME,const std::string & moduleName="entry")77     static std::string BuildOhosPkgJson(const std::string &pgoDir, const std::string &bundleName = TEST_BUNDLE_NAME,
78                                         const std::string &moduleName = "entry")
79     {
80         std::string pkgJson;
81         pkgJson += R"({"bundleName": ")" + bundleName + "\"";
82         pkgJson += R"(,"moduleName": ")" + moduleName + "\"";
83         pkgJson += R"(,"pkgPath": "/data/app/el1/bundle/public/com.ohos.test/entry.hap","abcName": "ets/modules.abc")";
84         pkgJson += R"(,"abcOffset": "0x6bb3c","abcSize": "0x51adfc")";
85         if (!pgoDir.empty()) {
86             pkgJson += R"(,"pgoDir": ")" + pgoDir + "\"";
87         }
88         return pkgJson + "}";
89     }
90 
91 protected:
92     static constexpr const char *TEST_BUNDLE_NAME = "com.ohos.test";
93     JSRuntimeOptions runtimeOptions_;
94     EcmaVM *vm_ {nullptr};
95 };
96 
HWTEST_F_L0(OhosTest,AotWhiteListTest)97 HWTEST_F_L0(OhosTest, AotWhiteListTest)
98 {
99     const char *whiteListTestDir = "ohos-whiteList/";
100     const char *enableListName = "ohos-whiteList/app_aot_jit_enable_list.conf";
101     std::string bundleScope = "com.bundle.scope.test";
102     std::string bundleScope1 = "com.bundle.scope.test1";
103     std::string bundleScope2 = "com.bundle.scope.test2";
104     mkdir(whiteListTestDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
105     std::ofstream file(enableListName);
106     file << bundleScope << std::endl;
107     file << bundleScope1 << ":aot" << std::endl;
108     file << bundleScope2 << ":jit" << std::endl;
109 
110     file.close();
111     auto helper = std::make_unique<ohos::EnableAotJitListHelper>(enableListName);
112     ASSERT_TRUE(helper->IsEnableAot(bundleScope));
113     ASSERT_TRUE(helper->IsEnableJit(bundleScope));
114     ASSERT_TRUE(helper->IsEnableAot(bundleScope1));
115     ASSERT_FALSE(helper->IsEnableJit(bundleScope1));
116     ASSERT_FALSE(helper->IsEnableAot(bundleScope2));
117     ASSERT_TRUE(helper->IsEnableJit(bundleScope2));
118     unlink(enableListName);
119     rmdir(whiteListTestDir);
120 }
121 
HWTEST_F_L0(OhosTest,AotWhiteListPassBy)122 HWTEST_F_L0(OhosTest, AotWhiteListPassBy)
123 {
124     const char *enableListName = "ohos-AotWhiteListPassBy/app_aot_jit_enable_list.conf";
125     std::string bundleScope = "com.bundle.scope.test";
126 
127     auto helper = std::make_unique<ohos::EnableAotJitListHelper>(enableListName);
128     ASSERT_FALSE(helper->IsEnableAot(bundleScope));
129     ASSERT_FALSE(helper->IsEnableJit(bundleScope));
130 }
131 
HWTEST_F_L0(OhosTest,OhosPkgArgsParse)132 HWTEST_F_L0(OhosTest, OhosPkgArgsParse)
133 {
134     const char *pgoDir = "ohos-OhosPkgArgsParse";
135     std::string runtimeAp = std::string(pgoDir) + "/rt_entry.ap";
136     mkdir(pgoDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
137     std::ofstream file(runtimeAp);
138     file.close();
139 
140     arg_list_t pandaFileNames {};
141     std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
142     PGOProfilerDecoder decoder;
143 
144     runtimeOptions_.SetPGOProfilerPath(runtimeAp);
145     runtimeOptions_.SetCompilerPkgJsonInfo(BuildOhosPkgJson(""));
146 
147     CompilationOptions cOptions(runtimeOptions_);
148     AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
149     OhosPkgArgs::ParseArgs(preProcessor, cOptions);
150 
151     ASSERT_EQ(preProcessor.GetMainPkgArgs()->GetBundleName(), TEST_BUNDLE_NAME);
152     ASSERT_EQ(preProcessor.GetMainPkgArgs()->GetModuleName(), "entry");
153     ASSERT_EQ(preProcessor.GetMainPkgArgs()->GetPath(), "/data/app/el1/bundle/public/com.ohos.test/entry.hap");
154     ASSERT_EQ(preProcessor.GetMainPkgArgs()->GetSize(), 0x51adfc);
155     ASSERT_EQ(preProcessor.GetMainPkgArgs()->GetOffset(), 0x6bb3c);
156     ASSERT_EQ(preProcessor.GetMainPkgArgs()->GetPgoDir(), pgoDir);
157 
158     ASSERT_EQ(preProcessor.GetPkgsArgs().size(), 3);
159 
160     unlink(runtimeAp.c_str());
161     rmdir(pgoDir);
162 }
163 
HWTEST_F_L0(OhosTest,OhosPkgArgsParsePgoDir)164 HWTEST_F_L0(OhosTest, OhosPkgArgsParsePgoDir)
165 {
166     arg_list_t pandaFileNames {};
167     std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
168     PGOProfilerDecoder decoder;
169     CompilationOptions cOptions(runtimeOptions_);
170     AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
171     OhosPkgArgs::ParseArgs(preProcessor, cOptions);
172 
173     ASSERT_EQ(preProcessor.GetMainPkgArgs()->GetPgoDir(), "/data/app/el1/100/aot_compiler/ark_profile/com.ohos.test");
174 }
175 
HWTEST_F_L0(OhosTest,UseBaselineApFromPgoDir)176 HWTEST_F_L0(OhosTest, UseBaselineApFromPgoDir)
177 {
178     const char *pgoDir = "ohos-UseBaselineApFromPgoDir";
179     std::string baselineAp = std::string(pgoDir) + "/entry.ap";
180     std::string runtimeAp = std::string(pgoDir) + "/rt_entry.ap";
181     std::string mergedAp = std::string(pgoDir) + "/merged_entry.ap";
182     mkdir(pgoDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
183     std::ofstream file(baselineAp);
184     file.close();
185     file.open(runtimeAp);
186     file.close();
187     // do not add to white list
188 
189     arg_list_t pandaFileNames {};
190     std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
191     PGOProfilerDecoder decoder;
192     CompilationOptions cOptions(runtimeOptions_);
193     AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
194     runtimeOptions_.SetCompilerPkgJsonInfo(BuildOhosPkgJson(pgoDir));
195     // Input format is correct, but there is no available ap file for pgoDir, return success.
196     ASSERT_TRUE(preProcessor.HandleTargetCompilerMode(cOptions));
197 
198     ASSERT_FALSE(cOptions.profilerIn_.empty());
199     unlink(runtimeAp.c_str());
200     unlink(baselineAp.c_str());
201     unlink(mergedAp.c_str());
202     rmdir(pgoDir);
203 }
204 
HWTEST_F_L0(OhosTest,UseRuntimeApWhenOnlyRuntimeExits)205 HWTEST_F_L0(OhosTest, UseRuntimeApWhenOnlyRuntimeExits)
206 {
207     const char *pgoDir = "ohos-UseRuntimeApWhenOnlyRuntimeExits";
208     std::string baselineAp = std::string(pgoDir) + "/entry.ap";
209     std::string runtimeAp = std::string(pgoDir) + "/rt_entry.ap";
210     std::string mergedAp = std::string(pgoDir) + "/merged_entry.ap";
211     mkdir(pgoDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
212     std::ofstream file(baselineAp);
213     file.close();
214     file.open(runtimeAp);
215     file.close();
216 
217     arg_list_t pandaFileNames {};
218     std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
219     PGOProfilerDecoder decoder;
220     CompilationOptions cOptions(runtimeOptions_);
221     AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
222     runtimeOptions_.SetCompilerPkgJsonInfo(BuildOhosPkgJson(pgoDir));
223     ASSERT_TRUE(FileExist(runtimeAp.c_str()));
224     ASSERT_TRUE(preProcessor.HandleTargetCompilerMode(cOptions));
225 
226     ASSERT_EQ(cOptions.profilerIn_, mergedAp);
227     ASSERT_TRUE(FileExist(mergedAp.c_str()));
228     ASSERT_TRUE(FileExist(baselineAp.c_str()));
229     ASSERT_FALSE(FileExist(runtimeAp.c_str()));
230     unlink(runtimeAp.c_str());
231     unlink(baselineAp.c_str());
232     unlink(mergedAp.c_str());
233     rmdir(pgoDir);
234 }
235 
HWTEST_F_L0(OhosTest,UseMergedApWhenOnlyMergedExist)236 HWTEST_F_L0(OhosTest, UseMergedApWhenOnlyMergedExist)
237 {
238     const char *pgoDir = "ohos-UseMergedApWhenOnlyMergedExist";
239     std::string baselineAp = std::string(pgoDir) + "/entry.ap";
240     std::string mergedAp = std::string(pgoDir) + "/merged_entry.ap";
241     mkdir(pgoDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
242     std::ofstream file(baselineAp);
243     file.close();
244     file.open(mergedAp);
245     file.close();
246 
247     arg_list_t pandaFileNames {};
248     std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
249     PGOProfilerDecoder decoder;
250     CompilationOptions cOptions(runtimeOptions_);
251     AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
252     runtimeOptions_.SetCompilerPkgJsonInfo(BuildOhosPkgJson(pgoDir));
253     ASSERT_TRUE(preProcessor.HandleTargetCompilerMode(cOptions));
254 
255     ASSERT_EQ(cOptions.profilerIn_, mergedAp);
256     ASSERT_TRUE(FileExist(mergedAp.c_str()));
257     ASSERT_TRUE(FileExist(baselineAp.c_str()));
258     unlink(baselineAp.c_str());
259     unlink(mergedAp.c_str());
260     rmdir(pgoDir);
261 }
262 
HWTEST_F_L0(OhosTest,UseMergedApWhenBothRuntimeAndMergedExist)263 HWTEST_F_L0(OhosTest, UseMergedApWhenBothRuntimeAndMergedExist)
264 {
265     const char *pgoDir = "ohos-UseMergedApWhenBothRuntimeAndMergedExist";
266     std::string baselineAp = std::string(pgoDir) + "/entry.ap";
267     std::string runtimeAp = std::string(pgoDir) + "/rt_entry.ap";
268     std::string mergedAp = std::string(pgoDir) + "/merged_entry.ap";
269     mkdir(pgoDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
270     std::ofstream file(baselineAp);
271     file.close();
272     file.open(mergedAp);
273     file.close();
274     file.open(runtimeAp);
275     file.close();
276 
277     arg_list_t pandaFileNames {};
278     std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
279     PGOProfilerDecoder decoder;
280     CompilationOptions cOptions(runtimeOptions_);
281     AotCompilerPreprocessor preProcessor(vm_, runtimeOptions_, pkgArgsMap, decoder, pandaFileNames);
282     runtimeOptions_.SetCompilerPkgJsonInfo(BuildOhosPkgJson(pgoDir));
283     ASSERT_TRUE(OhosPkgArgs::ParseArgs(preProcessor, cOptions));
284 
285     ASSERT_EQ(cOptions.profilerIn_, mergedAp + ":" + runtimeAp);
286     ASSERT_TRUE(FileExist(mergedAp.c_str()));
287     ASSERT_TRUE(FileExist(baselineAp.c_str()));
288     unlink(baselineAp.c_str());
289     unlink(runtimeAp.c_str());
290     unlink(mergedAp.c_str());
291     rmdir(pgoDir);
292 }
293 
HWTEST_F_L0(OhosTest,AotIsEnableArkProfileTrue)294 HWTEST_F_L0(OhosTest, AotIsEnableArkProfileTrue)
295 {
296     const char *whiteListTestDir = "ohos-whiteList/";
297     const char *enableListName = "ohos-whiteList/app_aot_jit_enable_list.conf";
298     std::string bundleScope = "com.bundle.scope.test";
299     std::string bundleScope1 = "com.bundle.scope.test1";
300     std::string bundleScope2 = "com.bundle.scope.test2";
301     mkdir(whiteListTestDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
302     ohos::EnableAotJitListHelper *helper = new MockEnableAotJitListHelper(enableListName);
303 
304     ASSERT_TRUE(helper->IsEnableAot(bundleScope));
305     ASSERT_TRUE(helper->IsEnableAot(bundleScope1));
306     ASSERT_TRUE(helper->IsEnableAot(bundleScope2));
307 
308     unlink(enableListName);
309     rmdir(whiteListTestDir);
310 }
311 
HWTEST_F_L0(OhosTest,AotIsEnableArkProfileFalse)312 HWTEST_F_L0(OhosTest, AotIsEnableArkProfileFalse)
313 {
314     const char *whiteListTestDir = "ohos-whiteList/";
315     const char *enableListName = "ohos-whiteList/app_aot_jit_enable_list.conf";
316     std::string bundleScope = "com.bundle.scope.test";
317     std::string bundleScope1 = "com.bundle.scope.test1";
318     std::string bundleScope2 = "com.bundle.scope.test2";
319     mkdir(whiteListTestDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
320     std::ofstream file(enableListName);
321     file << bundleScope << std::endl;
322     file.close();
323     auto helper = std::make_unique<ohos::EnableAotJitListHelper>(enableListName);
324 
325     ASSERT_TRUE(helper->IsEnableAot(bundleScope));
326     ASSERT_FALSE(helper->IsEnableAot(bundleScope1));
327     ASSERT_FALSE(helper->IsEnableAot(bundleScope2));
328 
329     unlink(enableListName);
330     rmdir(whiteListTestDir);
331 }
332 
333 }  // namespace panda::test