1 /*
2 * Copyright (c) 2022 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 "ability_delegator_registry.h"
17 #include "hilog_wrapper.h"
18 #include "js_runtime_utils.h"
19 #include "runner_runtime/js_test_runner.h"
20
21 extern const char _binary_delegator_mgmt_abc_start[];
22 extern const char _binary_delegator_mgmt_abc_end[];
23 namespace OHOS {
24 namespace RunnerRuntime {
Create(const std::unique_ptr<Runtime> & runtime,const std::shared_ptr<AbilityDelegatorArgs> & args,const AppExecFwk::BundleInfo & bundleInfo,bool isFaJsModel)25 std::unique_ptr<TestRunner> JsTestRunner::Create(const std::unique_ptr<Runtime> &runtime,
26 const std::shared_ptr<AbilityDelegatorArgs> &args, const AppExecFwk::BundleInfo &bundleInfo, bool isFaJsModel)
27 {
28 if (!runtime) {
29 HILOG_ERROR("Invalid runtime");
30 return nullptr;
31 }
32
33 if (!args) {
34 HILOG_ERROR("Invalid ability delegator args");
35 return nullptr;
36 }
37
38 auto pTestRunner = new (std::nothrow) JsTestRunner(static_cast<JsRuntime &>(*runtime), args, bundleInfo,
39 isFaJsModel);
40 if (!pTestRunner) {
41 HILOG_ERROR("Failed to create test runner");
42 return nullptr;
43 }
44
45 return std::unique_ptr<JsTestRunner>(pTestRunner);
46 }
47
JsTestRunner(JsRuntime & jsRuntime,const std::shared_ptr<AbilityDelegatorArgs> & args,const AppExecFwk::BundleInfo & bundleInfo,bool isFaJsModel)48 JsTestRunner::JsTestRunner(
49 JsRuntime &jsRuntime, const std::shared_ptr<AbilityDelegatorArgs> &args, const AppExecFwk::BundleInfo &bundleInfo,
50 bool isFaJsModel)
51 : jsRuntime_(jsRuntime), isFaJsModel_(isFaJsModel)
52 {
53 std::string moduleName;
54 if (args) {
55 std::string srcPath;
56 if (bundleInfo.hapModuleInfos.back().isModuleJson) {
57 srcPath.append(args->GetTestModuleName());
58 if (args->GetTestRunnerClassName().find("/") == std::string::npos) {
59 srcPath.append("/ets/TestRunner/");
60 }
61 moduleName = args->GetTestModuleName();
62 } else {
63 srcPath.append(args->GetTestPackageName());
64 srcPath.append("/assets/js/TestRunner/");
65 moduleName = args->GetTestPackageName();
66 }
67 srcPath.append(args->GetTestRunnerClassName());
68 srcPath.append(".abc");
69 srcPath_ = srcPath;
70 }
71 HILOG_DEBUG("JsTestRunner srcPath is %{public}s", srcPath_.c_str());
72 if (isFaJsModel) {
73 return;
74 }
75 if (!moduleName.empty()) {
76 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
77 if ((hapModuleInfo.isModuleJson && hapModuleInfo.name == moduleName) ||
78 hapModuleInfo.package == moduleName) {
79 hapPath_ = hapModuleInfo.hapPath;
80 break;
81 }
82 }
83 } else {
84 hapPath_ = bundleInfo.hapModuleInfos.back().hapPath;
85 }
86 HILOG_DEBUG("JsTestRunner hapPath is %{public}s", hapPath_.c_str());
87 moduleName.append("::").append("TestRunner");
88 jsTestRunnerObj_ = jsRuntime_.LoadModule(moduleName, srcPath_, hapPath_,
89 bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE);
90 }
91
92 JsTestRunner::~JsTestRunner() = default;
93
Initialize()94 bool JsTestRunner::Initialize()
95 {
96 if (isFaJsModel_) {
97 if (!jsRuntime_.RunScript("/system/etc/strip.native.min.abc", "")) {
98 HILOG_ERROR("RunScript err");
99 return false;
100 }
101 std::vector<uint8_t> buffer((uint8_t*)_binary_delegator_mgmt_abc_start,
102 (uint8_t*)_binary_delegator_mgmt_abc_end);
103 auto mgmtResult = jsRuntime_.GetNativeEngine().RunBufferScript(buffer);
104 if (mgmtResult == nullptr) {
105 HILOG_ERROR("mgmtResult init error");
106 return false;
107 }
108 if (!jsRuntime_.RunSandboxScript(srcPath_, hapPath_)) {
109 HILOG_ERROR("RunScript srcPath_ err");
110 return false;
111 }
112 NativeEngine& engine = jsRuntime_.GetNativeEngine();
113 NativeObject* object = ConvertNativeValueTo<NativeObject>(engine.GetGlobal());
114 if (object == nullptr) {
115 HILOG_ERROR("Failed to get global object");
116 return false;
117 }
118 NativeValue* mainEntryFunc = object->GetProperty("___mainEntry___");
119 if (mainEntryFunc == nullptr) {
120 HILOG_ERROR("Failed to get mainEntryFunc");
121 return false;
122 }
123 NativeValue* value = engine.GetGlobal();
124 if (value == nullptr) {
125 HILOG_ERROR("Failed to get global");
126 return false;
127 }
128 engine.CallFunction(engine.GetGlobal(), mainEntryFunc, &value, 1);
129 }
130 return true;
131 }
132
Prepare()133 void JsTestRunner::Prepare()
134 {
135 HILOG_INFO("Enter");
136 TestRunner::Prepare();
137 CallObjectMethod("onPrepare");
138 HILOG_INFO("End");
139 }
140
Run()141 void JsTestRunner::Run()
142 {
143 HILOG_INFO("Enter");
144 TestRunner::Run();
145 CallObjectMethod("onRun");
146 HILOG_INFO("End");
147 }
148
CallObjectMethod(const char * name,NativeValue * const * argv,size_t argc)149 void JsTestRunner::CallObjectMethod(const char *name, NativeValue *const *argv, size_t argc)
150 {
151 HILOG_INFO("JsTestRunner::CallObjectMethod(%{public}s)", name);
152 if (isFaJsModel_) {
153 NativeEngine& engine = jsRuntime_.GetNativeEngine();
154 NativeObject* global = ConvertNativeValueTo<NativeObject>(engine.GetGlobal());
155 if (global == nullptr) {
156 HILOG_ERROR("Failed to get global object");
157 return;
158 }
159
160 NativeObject* exportObject = ConvertNativeValueTo<NativeObject>(global->GetProperty("exports"));
161 if (exportObject == nullptr) {
162 HILOG_ERROR("Failed to get exportObject");
163 return;
164 }
165
166 NativeObject* defaultObject = ConvertNativeValueTo<NativeObject>(exportObject->GetProperty("default"));
167 if (defaultObject == nullptr) {
168 HILOG_ERROR("Failed to get defaultObject");
169 return;
170 }
171
172 NativeValue* func = defaultObject->GetProperty(name);
173 if (func == nullptr || !func->IsCallable()) {
174 HILOG_ERROR("CallRequest func is %{public}s", func == nullptr ? "nullptr" : "not func");
175 return;
176 }
177 engine.CallFunction(engine.CreateUndefined(), func, argv, argc);
178 return;
179 }
180
181 if (!jsTestRunnerObj_) {
182 HILOG_ERROR("Not found %{public}s", srcPath_.c_str());
183 ReportFinished("Not found " + srcPath_);
184 return;
185 }
186
187 HandleScope handleScope(jsRuntime_);
188 auto &nativeEngine = jsRuntime_.GetNativeEngine();
189
190 NativeValue *value = jsTestRunnerObj_->Get();
191 NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
192 if (obj == nullptr) {
193 HILOG_ERROR("Failed to get Test Runner object");
194 ReportFinished("Failed to get Test Runner object");
195 return;
196 }
197
198 NativeValue *methodOnCreate = obj->GetProperty(name);
199 if (methodOnCreate == nullptr) {
200 HILOG_ERROR("Failed to get '%{public}s' from Test Runner object", name);
201 ReportStatus("Failed to get " + std::string(name) + " from Test Runner object");
202 return;
203 }
204 nativeEngine.CallFunction(value, methodOnCreate, argv, argc);
205 }
206
ReportFinished(const std::string & msg)207 void JsTestRunner::ReportFinished(const std::string &msg)
208 {
209 HILOG_INFO("Enter");
210 auto delegator = AbilityDelegatorRegistry::GetAbilityDelegator();
211 if (!delegator) {
212 HILOG_ERROR("delegator is null");
213 return;
214 }
215
216 delegator->FinishUserTest(msg, -1);
217 }
218
ReportStatus(const std::string & msg)219 void JsTestRunner::ReportStatus(const std::string &msg)
220 {
221 HILOG_INFO("Enter");
222 auto delegator = AbilityDelegatorRegistry::GetAbilityDelegator();
223 if (!delegator) {
224 HILOG_ERROR("delegator is null");
225 return;
226 }
227
228 delegator->Print(msg);
229 }
230 } // namespace RunnerRuntime
231 } // namespace OHOS
232