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