• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 <regex>
17 
18 #include "ability_delegator_registry.h"
19 #include "hilog_tag_wrapper.h"
20 #include "js_runtime_utils.h"
21 #include "runner_runtime/js_test_runner.h"
22 
23 namespace OHOS {
24 namespace RunnerRuntime {
25 
Create(const std::unique_ptr<Runtime> & runtime,const std::shared_ptr<AbilityDelegatorArgs> & args,const AppExecFwk::BundleInfo & bundleInfo,bool isFaJsModel)26 std::unique_ptr<TestRunner> JsTestRunner::Create(const std::unique_ptr<Runtime> &runtime,
27     const std::shared_ptr<AbilityDelegatorArgs> &args, const AppExecFwk::BundleInfo &bundleInfo, bool isFaJsModel)
28 {
29     if (!runtime) {
30         TAG_LOGE(AAFwkTag::DELEGATOR, "invalid runtime");
31         return nullptr;
32     }
33 
34     if (!args) {
35         TAG_LOGE(AAFwkTag::DELEGATOR, "invalid args");
36         return nullptr;
37     }
38 
39     auto pTestRunner = new (std::nothrow) JsTestRunner(static_cast<JsRuntime &>(*runtime), args, bundleInfo,
40         isFaJsModel);
41     if (!pTestRunner) {
42         TAG_LOGE(AAFwkTag::DELEGATOR, "null testRunner");
43         return nullptr;
44     }
45 
46     return std::unique_ptr<JsTestRunner>(pTestRunner);
47 }
48 
JsTestRunner(JsRuntime & jsRuntime,const std::shared_ptr<AbilityDelegatorArgs> & args,const AppExecFwk::BundleInfo & bundleInfo,bool isFaJsModel)49 JsTestRunner::JsTestRunner(
50     JsRuntime &jsRuntime, const std::shared_ptr<AbilityDelegatorArgs> &args, const AppExecFwk::BundleInfo &bundleInfo,
51     bool isFaJsModel)
52     : jsRuntime_(jsRuntime), isFaJsModel_(isFaJsModel)
53 {
54     std::string moduleName;
55     if (args) {
56         std::string srcPath;
57         if (bundleInfo.hapModuleInfos.back().isModuleJson) {
58             srcPath.append(GetTestRunnerPath(args));
59             moduleName = args->GetTestModuleName();
60         } else {
61             srcPath.append(args->GetTestPackageName());
62             srcPath.append("/assets/js/TestRunner/");
63             moduleName = args->GetTestPackageName();
64             srcPath.append(args->GetTestRunnerClassName());
65         }
66         srcPath.append(".abc");
67         srcPath_ = srcPath;
68     }
69     TAG_LOGI(AAFwkTag::DELEGATOR, "srcPath: %{public}s", srcPath_.c_str());
70 
71     if (!moduleName.empty()) {
72         for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
73             if ((hapModuleInfo.isModuleJson && hapModuleInfo.name == moduleName) ||
74                 hapModuleInfo.package == moduleName) {
75                 hapPath_ = hapModuleInfo.hapPath;
76                 break;
77             }
78         }
79     } else {
80         hapPath_ = bundleInfo.hapModuleInfos.back().hapPath;
81     }
82     TAG_LOGD(AAFwkTag::DELEGATOR, "hapPath: %{public}s", hapPath_.c_str());
83 
84     if (isFaJsModel) {
85         return;
86     }
87 
88     moduleName.append("::").append("TestRunner");
89     jsTestRunnerObj_ = jsRuntime_.LoadModule(moduleName, srcPath_, hapPath_,
90         bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE);
91     if (!jsTestRunnerObj_ &&
92         srcPath_.find(AbilityRuntime::LOWERCASETESTRUNNER) != std::string::npos &&
93         !args->GetTestRunnerClassName().empty()) {
94         TAG_LOGI(AAFwkTag::DELEGATOR, "not found %{public}s , retry load capital address", srcPath_.c_str());
95         std::regex src_pattern(AbilityRuntime::LOWERCASETESTRUNNER);
96         srcPath_ = std::regex_replace(srcPath_, src_pattern, AbilityRuntime::CAPITALTESTRUNNER);
97         TAG_LOGD(AAFwkTag::DELEGATOR, "capital address is %{public}s", srcPath_.c_str());
98         jsTestRunnerObj_ = jsRuntime_.LoadModule(moduleName, srcPath_, hapPath_,
99             bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE);
100     }
101 }
102 
103 JsTestRunner::~JsTestRunner() = default;
104 
Initialize()105 bool JsTestRunner::Initialize()
106 {
107     if (isFaJsModel_) {
108         if (!jsRuntime_.RunScript("/system/etc/strip.native.min.abc", "")) {
109             TAG_LOGE(AAFwkTag::DELEGATOR, "runScript err");
110             return false;
111         }
112 
113         if (!jsRuntime_.RunScript("/system/etc/abc/ability/delegator_mgmt.abc", "")) {
114             TAG_LOGE(AAFwkTag::DELEGATOR, "run delegator failed");
115             return false;
116         }
117 
118         if (!jsRuntime_.RunSandboxScript(srcPath_, hapPath_)) {
119             TAG_LOGE(AAFwkTag::DELEGATOR, "runScript srcPath_ err");
120             return false;
121         }
122 
123         napi_env env = jsRuntime_.GetNapiEnv();
124         napi_value object = nullptr;
125         napi_get_global(env, &object);
126         if (object == nullptr) {
127             TAG_LOGE(AAFwkTag::DELEGATOR, "null object");
128             return false;
129         }
130         napi_value mainEntryFunc = nullptr;
131         napi_get_named_property(env, object, "___mainEntry___", &mainEntryFunc);
132         if (mainEntryFunc == nullptr) {
133             TAG_LOGE(AAFwkTag::DELEGATOR, "null mainEntryFunc");
134             return false;
135         }
136         napi_value value = nullptr;
137         napi_get_global(env, &value);
138         if (value == nullptr) {
139             TAG_LOGE(AAFwkTag::DELEGATOR, "null value");
140             return false;
141         }
142         napi_call_function(env, value, mainEntryFunc, 1, &value, nullptr);
143     }
144     return true;
145 }
146 
Prepare()147 void JsTestRunner::Prepare()
148 {
149     TAG_LOGI(AAFwkTag::DELEGATOR, "Enter");
150     TestRunner::Prepare();
151     CallObjectMethod("onPrepare");
152 }
153 
Run()154 void JsTestRunner::Run()
155 {
156     TAG_LOGI(AAFwkTag::DELEGATOR, "Enter");
157     TestRunner::Run();
158     CallObjectMethod("onRun");
159 }
160 
CallObjectMethod(const char * name,napi_value const * argv,size_t argc)161 void JsTestRunner::CallObjectMethod(const char *name, napi_value const *argv, size_t argc)
162 {
163     TAG_LOGI(AAFwkTag::DELEGATOR, "callJsMethod(%{public}s)", name);
164     auto env = jsRuntime_.GetNapiEnv();
165     if (isFaJsModel_) {
166         napi_value global = nullptr;
167         napi_get_global(env, &global);
168         napi_value exportObject = nullptr;
169         napi_get_named_property(env, global, "exports", &exportObject);
170         if (!CheckTypeForNapiValue(env, exportObject, napi_object)) {
171             TAG_LOGE(AAFwkTag::DELEGATOR, "get exportObject failed");
172             return;
173         }
174 
175         napi_value defaultObject = nullptr;
176         napi_get_named_property(env, exportObject, "default", &defaultObject);
177         if (!CheckTypeForNapiValue(env, defaultObject, napi_object)) {
178             TAG_LOGE(AAFwkTag::DELEGATOR, "get defaultObject failed");
179             return;
180         }
181 
182         napi_value func = nullptr;
183         napi_get_named_property(env, defaultObject, name, &func);
184         if (!CheckTypeForNapiValue(env, func, napi_function)) {
185             TAG_LOGE(AAFwkTag::DELEGATOR, "callRequest func:%{public}s", func == nullptr ? "nullptr" : "not func");
186             return;
187         }
188         napi_call_function(env, CreateJsUndefined(env), func, argc, argv, nullptr);
189         return;
190     }
191 
192     if (!jsTestRunnerObj_) {
193         TAG_LOGE(AAFwkTag::DELEGATOR, "not found %{public}s", srcPath_.c_str());
194         ReportFinished("Not found " + srcPath_);
195         return;
196     }
197 
198     HandleScope handleScope(jsRuntime_);
199     napi_value obj = jsTestRunnerObj_->GetNapiValue();
200     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
201         TAG_LOGE(AAFwkTag::DELEGATOR, "get TestRunner object failed");
202         ReportFinished("Failed to get Test Runner object");
203         return;
204     }
205 
206     napi_value methodOnCreate = nullptr;
207     napi_get_named_property(env, obj, name, &methodOnCreate);
208     if (methodOnCreate == nullptr) {
209         TAG_LOGE(AAFwkTag::DELEGATOR, "get '%{public}s' from TestRunner object failed", name);
210         ReportStatus("Failed to get " + std::string(name) + " from Test Runner object");
211         return;
212     }
213     napi_call_function(env, obj, methodOnCreate, argc, argv, nullptr);
214 }
215 
ReportFinished(const std::string & msg)216 void JsTestRunner::ReportFinished(const std::string &msg)
217 {
218     TAG_LOGI(AAFwkTag::DELEGATOR, "enter");
219     auto delegator = AbilityDelegatorRegistry::GetAbilityDelegator();
220     if (!delegator) {
221         TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
222         return;
223     }
224 
225     delegator->FinishUserTest(msg, -1);
226 }
227 
ReportStatus(const std::string & msg)228 void JsTestRunner::ReportStatus(const std::string &msg)
229 {
230     TAG_LOGI(AAFwkTag::DELEGATOR, "enter");
231     auto delegator = AbilityDelegatorRegistry::GetAbilityDelegator();
232     if (!delegator) {
233         TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
234         return;
235     }
236 
237     delegator->Print(msg);
238 }
239 
GetTestRunnerPath(const std::shared_ptr<AbilityDelegatorArgs> & args)240 std::string JsTestRunner::GetTestRunnerPath(const std::shared_ptr<AbilityDelegatorArgs> &args)
241 {
242     std::string result;
243     if (!args->GetTestRunnerClassName().empty()) {
244         result.append(args->GetTestModuleName());
245         if (args->GetTestRunnerClassName().find("/") == std::string::npos) {
246             result.append(LOWERCASETESTRUNNER);
247         }
248         result.append(args->GetTestRunnerClassName());
249     } else {
250         result.append(args->GetTestRunnerPath());
251     }
252     return result;
253 }
254 }  // namespace RunnerRuntime
255 }  // namespace OHOS
256