diff --git a/examples/app_info/BUILD.gn b/examples/app_info/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..f19459b2349b6ca16af96de19ac4740db2f0a959
--- /dev/null
+++ b/examples/app_info/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright (c) 2021 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build/ohos.gni")
+
+###############################################################################
+config("app_info_config") {
+ visibility = [ ":*" ]
+ include_dirs = [ "include" ]
+}
+
+ohos_shared_library("app_info") {
+ sources = []
+ public_configs = [ ":app_info_config" ]
+ subsystem_name = "subsystem_examples"
+}
+###############################################################################
diff --git a/examples/app_info/test/BUILD.gn b/examples/app_info/test/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..3f38132198b65c7429d0d2b5038a71d1c59149d0
--- /dev/null
+++ b/examples/app_info/test/BUILD.gn
@@ -0,0 +1,23 @@
+# Copyright (c) 2021 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build/test.gni")
+
+#################################group#########################################
+group("unittest") {
+ testonly = true
+ deps = []
+
+ deps += [ "unittest/common/get_app_info:unittest" ]
+}
+###############################################################################
diff --git a/examples/app_info/test/unittest/common/get_app_info/BUILD.gn b/examples/app_info/test/unittest/common/get_app_info/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..2b4c186b21cc52c216cdb00da17e8d4d088f08af
--- /dev/null
+++ b/examples/app_info/test/unittest/common/get_app_info/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright (C) 2021 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build/test.gni")
+
+module_output_path = "subsystem_examples/app_info"
+
+ohos_js_unittest("GetAppInfoJsTest") {
+ module_out_path = module_output_path
+
+ hap_profile = "./config.json"
+ certificate_profile = "//test/developertest/signature/openharmony_sx.p7b"
+}
+
+group("unittest") {
+ testonly = true
+ deps = [ ":GetAppInfoJsTest" ]
+}
diff --git a/examples/app_info/test/unittest/common/get_app_info/ExampleJsunit.test.js b/examples/app_info/test/unittest/common/get_app_info/ExampleJsunit.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..26e84e5f71805e789a93f89d96179a334c071432
--- /dev/null
+++ b/examples/app_info/test/unittest/common/get_app_info/ExampleJsunit.test.js
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import app from '@system.app'
+
+import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index'
+
+describe("AppInfoTest", function () {
+ beforeAll(function() {
+ /*
+ * @tc.setup: setup invoked before all testcases
+ */
+ console.info('beforeAll caled')
+ })
+
+ afterAll(function() {
+ /*
+ * @tc.teardown: teardown invoked after all testcases
+ */
+ console.info('afterAll caled')
+ })
+
+ beforeEach(function() {
+ /*
+ * @tc.setup: setup invoked before each testcases
+ */
+ console.info('beforeEach caled')
+ })
+
+ afterEach(function() {
+ /*
+ * @tc.teardown: teardown invoked after each testcases
+ */
+ console.info('afterEach caled')
+ })
+
+ /*
+ * @tc.name:appInfoTest001
+ * @tc.desc:verify app info is not null
+ * @tc.author:renxiang
+ */
+ it("appInfoTest001", 0, function () {
+ var info = app.getInfo()
+ expect(info != null).assertEqual(true)
+ })
+
+ /*
+ * @tc.name:appInfoTest002
+ * @tc.desc:verify app info name and code
+ * @tc.author:renxiang
+ */
+ it("appInfoTest002", 0, function () {
+ var info = app.getInfo()
+ expect(info.versionName).assertEqual('')
+ expect(info.versionCode).assertEqual('0')
+ })
+
+})
diff --git a/examples/app_info/test/unittest/common/get_app_info/config.json b/examples/app_info/test/unittest/common/get_app_info/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..9889c145cf45093c6b938d34bb050c555653f09e
--- /dev/null
+++ b/examples/app_info/test/unittest/common/get_app_info/config.json
@@ -0,0 +1,59 @@
+{
+ "app": {
+ "bundleName": "com.example.myapplication",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 5
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.myapplication",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "name": "com.example.myapplication.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "MyApplication",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ],
+ "js": [
+ {
+ "pages": [
+ "pages/index/index"
+ ],
+ "name": "default",
+ "window": {
+ "designWidth": 720,
+ "autoDesignWidth": false
+ }
+ }
+ ]
+ }
+}
diff --git a/examples/ohos.build b/examples/ohos.build
index ba3c3da48f4615e2475007e2da2f073c7286d5e9..8bea01699242c13464bc91aca3d9b2561e44603b 100755
--- a/examples/ohos.build
+++ b/examples/ohos.build
@@ -3,11 +3,13 @@
"parts": {
"subsystem_examples": {
"module_list": [
+ "//test/developertest/examples/app_info:app_info",
"//test/developertest/examples/detector:detector",
"//test/developertest/examples/calculator:calculator",
"//test/developertest/examples/calculator:calculator_static"
],
"test_list": [
+ "//test/developertest/examples/app_info/test:unittest",
"//test/developertest/examples/calculator/test:unittest",
"//test/developertest/examples/calculator/test:fuzztest",
"//test/developertest/examples/detector/test:unittest",
diff --git a/libs/js_template/src/main/js/default/app.js b/libs/js_template/src/main/js/default/app.js
new file mode 100644
index 0000000000000000000000000000000000000000..83cc355c87c42fd4f00b239657d2c081cf0e9aa0
--- /dev/null
+++ b/libs/js_template/src/main/js/default/app.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import device from '@system.device';
+
+export default {
+ onCreate() {
+ console.info('AceApplication onCreate');
+ },
+ onDestroy() {
+ console.info('AceApplication onDestroy');
+ }
+};
diff --git a/libs/js_template/src/main/js/default/i18n/en-US.json b/libs/js_template/src/main/js/default/i18n/en-US.json
new file mode 100644
index 0000000000000000000000000000000000000000..e63c70d978a3a53be988388c87182f81785e170c
--- /dev/null
+++ b/libs/js_template/src/main/js/default/i18n/en-US.json
@@ -0,0 +1,6 @@
+{
+ "strings": {
+ "hello": "Hello",
+ "world": "World"
+ }
+}
\ No newline at end of file
diff --git a/libs/js_template/src/main/js/default/i18n/zh-CN.json b/libs/js_template/src/main/js/default/i18n/zh-CN.json
new file mode 100644
index 0000000000000000000000000000000000000000..de6ee5748322f44942c1b003319d8e66c837675f
--- /dev/null
+++ b/libs/js_template/src/main/js/default/i18n/zh-CN.json
@@ -0,0 +1,6 @@
+{
+ "strings": {
+ "hello": "您好",
+ "world": "世界"
+ }
+}
\ No newline at end of file
diff --git a/libs/js_template/src/main/js/default/pages/index/index.css b/libs/js_template/src/main/js/default/pages/index/index.css
new file mode 100644
index 0000000000000000000000000000000000000000..a6053c61f9615fcd50fefb51f878568f3e39e59b
--- /dev/null
+++ b/libs/js_template/src/main/js/default/pages/index/index.css
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.container {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+}
+
+.title {
+ font-size: 60px;
+ text-align: center;
+ width: 100%;
+ height: 40%;
+ margin: 10px;
+}
+.btn {
+ width: 50%;
+ height: 100px;
+ font-size: 40px;
+}
diff --git a/libs/js_template/src/main/js/default/pages/index/index.hml b/libs/js_template/src/main/js/default/pages/index/index.hml
new file mode 100644
index 0000000000000000000000000000000000000000..6069a046a35c4409ab85e4595a079a1670a9c7fe
--- /dev/null
+++ b/libs/js_template/src/main/js/default/pages/index/index.hml
@@ -0,0 +1,21 @@
+
+
+
+
+ {{ $t('strings.hello') }} {{title}}
+
+
+
diff --git a/libs/js_template/src/main/js/default/pages/index/index.js b/libs/js_template/src/main/js/default/pages/index/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..37d3d82171002a3214286dc10315e4baef40f4e6
--- /dev/null
+++ b/libs/js_template/src/main/js/default/pages/index/index.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import app from '@system.app'
+
+import {Core, ExpectExtend} from 'deccjsunit/index'
+
+export default {
+ data: {
+ title: ""
+ },
+ onInit() {
+ this.title = this.$t('strings.world');
+ },
+ onShow() {
+ console.info('onShow finish')
+ const core = Core.getInstance()
+ const expectExtend = new ExpectExtend({
+ 'id': 'extend'
+ })
+
+ core.addService('expect', expectExtend)
+ core.init()
+
+ const configService = core.getDefaultService('config')
+ configService.setConfig(this)
+
+ require('../../test/List.test')
+ core.execute()
+ },
+ onReady() {
+ },
+}
diff --git a/libs/js_template/src/main/js/default/test/List.test.js b/libs/js_template/src/main/js/default/test/List.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..b12d92d99666f2c83ecc116a470dc2f4fa1d10c2
--- /dev/null
+++ b/libs/js_template/src/main/js/default/test/List.test.js
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
diff --git a/libs/js_template/src/main/resources/base/element/string.json b/libs/js_template/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..76e501f214f84c96a44d08973dbbdeab8515e1de
--- /dev/null
+++ b/libs/js_template/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "JsHelloWorld"
+ },
+ {
+ "name": "mainability_description",
+ "value": "hap sample empty page"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/libs/js_template/src/main/resources/base/media/icon.png b/libs/js_template/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/libs/js_template/src/main/resources/base/media/icon.png differ
diff --git a/signature/openharmony_sx.p7b b/signature/openharmony_sx.p7b
new file mode 100644
index 0000000000000000000000000000000000000000..9be1e98fa4c0c28ca997ed660112fa16b194f0f5
Binary files /dev/null and b/signature/openharmony_sx.p7b differ
diff --git a/src/core/build/build_manager.py b/src/core/build/build_manager.py
index 04192552db515ea9ddcebde43edbc03a55da48e4..839da9aa799b7aad39175a2124dddf88db16cc92 100755
--- a/src/core/build/build_manager.py
+++ b/src/core/build/build_manager.py
@@ -21,6 +21,7 @@ from xdevice import platform_logger
from core.utils import scan_support_product
from core.config.config_manager import UserConfigManager
from core.build.select_targets import SelectTargets
+from core.build.pretreat_targets import PretreatTargets
from core.build.build_testcases import BuildTestcases
from core.command.gen import Gen
@@ -95,6 +96,7 @@ class BuildManager(object):
LOG.warning("No build target found.")
return False
+ PretreatTargets(target_list).pretreat_targets_from_list()
build_cfg_filepath = os.path.join(project_root_path,
"test",
"developertest",
@@ -111,6 +113,7 @@ class BuildManager(object):
para.productform,
"make_temp_test")
self._make_gn_file(build_cfg_filepath, [])
+ PretreatTargets(target_list).disassemble_targets_from_list()
return build_result
diff --git a/src/core/build/pretreat_targets.py b/src/core/build/pretreat_targets.py
new file mode 100644
index 0000000000000000000000000000000000000000..bc6e9dc7cfb1da9b245ff94c2b5af943cbd600ce
--- /dev/null
+++ b/src/core/build/pretreat_targets.py
@@ -0,0 +1,282 @@
+#!/usr/bin/env python3
+# coding=utf-8
+
+#
+# Copyright (c) 2021 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import os
+import sys
+import json
+import shutil
+
+from core.constants import JsTestConst
+from xdevice import platform_logger
+
+LOG = platform_logger("PretreatTargets")
+
+
+##############################################################################
+##############################################################################
+
+class PretreatTargets(object):
+ def __init__(self, target_list):
+ self.target_list = target_list
+
+ def pretreat_targets_from_list(self):
+ path_list, name_list = self.parse_target_info()
+ self.pretreat_by_target_name(path_list, name_list)
+
+ def disassemble_targets_from_list(self):
+ path_list, name_list = self.parse_target_info()
+ self.disassemble_by_target_name(path_list, name_list)
+
+ def parse_target_info(self):
+ path_list = []
+ name_list = []
+
+ for line in self.target_list:
+ path = line.split(':')[0][2:]
+ name = line.split(':')[1].split('(')[0]
+ path_list.append(path)
+ name_list.append(name)
+
+ LOG.info("path_list: %s" % path_list)
+ LOG.info("name_list: %s" % name_list)
+ return path_list, name_list
+
+ def pretreat_by_target_name(self, path_list, name_list):
+ for name, path in zip(name_list, path_list):
+ LOG.info("name: %s path: %s" % (name, path))
+ if name.endswith("JsTest"):
+ self.pretreat_js_target(path, name)
+ LOG.info("js test pretreat success")
+
+ def pretreat_js_target(self, path, name):
+ template_path = os.path.join(sys.framework_root_dir, "libs",
+ "js_template", "src")
+ target_path = os.path.join(sys.source_code_root_path, path)
+ config_path = os.path.join(target_path, "config.json")
+ gn_path = os.path.join(target_path, "BUILD.gn")
+ gn_bak_path = os.path.join(target_path, "BuildBak")
+ test_path = os.path.join(target_path, "src", "main", "js",
+ "default", "test")
+ if not os.path.exists(config_path):
+ LOG.error("js test needs config.json file")
+ return
+ if not os.path.exists(gn_path):
+ LOG.error("js test needs BUILD.gn file")
+ return
+ LOG.info("template_path: %s" % template_path)
+ LOG.info("target_path: %s" % target_path)
+
+ #modify BUILD.gn file to compile hap
+ output_path = self.parse_output_path_in_gn(gn_path)
+ if output_path == "":
+ LOG.error(" BUILD.gn needs 'module_output_path'")
+ return
+ os.rename(gn_path, gn_bak_path)
+ template_args = {'output_path': output_path, 'suite_name': name}
+ with open(gn_path, 'w') as filehandle:
+ filehandle.write(JsTestConst.BUILD_GN_FILE_TEMPLATE %
+ template_args)
+
+ #copy js hap template to target path
+ shutil.copytree(template_path, os.path.join(target_path, "src"))
+ shutil.copy(config_path, os.path.join(target_path, "src", "main"))
+ file_name = os.listdir(target_path)
+ for file in file_name:
+ LOG.info("file: %s" % file)
+ if file.endswith(".js"):
+ shutil.copy(os.path.join(target_path, file), test_path)
+ with open(os.path.join(test_path, "List.test.js"), 'a') \
+ as list_data:
+ list_data.write("require('./%s')" % file)
+
+ def parse_output_path_in_gn(self, gn_path):
+ output_path = ""
+ with open(gn_path, 'r') as gn_file:
+ for line in gn_file.readlines():
+ if line.startswith("module_output_path"):
+ LOG.info("output path: %s" % line.split()[2].strip('"'))
+ output_path = line.split()[2].strip('"')
+ break
+ return output_path
+
+ def disassemble_by_target_name(self, path_list, name_list):
+ for name, path in zip(name_list, path_list):
+ LOG.info("name: %s path: %s" % (name, path))
+ if name.endswith("JsTest"):
+ self.disassemble_js_target(path, name)
+ LOG.info("js test disassemble success")
+
+ def disassemble_js_target(self, path, name):
+ target_path = os.path.join(sys.source_code_root_path, path)
+ src_path = os.path.join(target_path, "src")
+ gn_path = os.path.join(target_path, "BUILD.gn")
+ gn_bak_path = os.path.join(target_path, "BuildBak")
+
+ if os.path.exists(src_path):
+ shutil.rmtree(src_path)
+ if os.path.exists(gn_path) and os.path.exists(gn_bak_path):
+ os.remove(gn_path)
+ os.rename(gn_bak_path, gn_path)
+
+
+ @classmethod
+ def _get_mlf_data_from_file(cls, filepath):
+ data_list = []
+ if os.path.exists(filepath):
+ with open(filepath, 'r') as mlf_file:
+ data_list = json.load(mlf_file)
+ if not data_list:
+ LOG.warning("The %s file load error." % filepath)
+ data_list = []
+ return data_list
+
+ @classmethod
+ def _get_part_path_data(cls, productform):
+ part_path_dic = {}
+ parser = ParsePartsConfig(productform)
+
+ part_infos = parser.get_part_infos()
+ if part_infos is None:
+ LOG.error("part_infos is None.")
+ return part_path_dic
+
+ for part_name in part_infos:
+ part_info = part_infos.get(part_name, None)
+ if part_info is None:
+ continue
+
+ origin_part_name = part_info.get("origin_part_name")
+ build_out_dir = part_info.get("build_out_dir")
+
+ part_path_list = []
+ default_part_path = os.path.join(
+ get_build_output_path(productform),
+ "module_list_files",
+ origin_part_name)
+ if os.path.exists(default_part_path):
+ part_path_list.append(default_part_path)
+
+ if build_out_dir != ".":
+ product_part_path = os.path.join(
+ get_build_output_path(productform),
+ build_out_dir,
+ "module_list_files",
+ origin_part_name)
+ if os.path.exists(product_part_path):
+ part_path_list.append(product_part_path)
+ part_path_dic[part_name] = part_path_list
+ return part_path_dic
+
+ def _get_target_list_from_path(self, typelist, check_path):
+ target_list = []
+ if os.path.exists(check_path):
+ mlf_file_list = get_file_list_by_postfix(
+ check_path, ".mlf")
+ for filepath in mlf_file_list:
+ mlf_info_list = self._get_mlf_data_from_file(filepath)
+ for data in mlf_info_list:
+ test_type = data.get("test_type")
+ target_path = data.get("label")
+ if "ALL" in typelist:
+ target_list.append(target_path)
+ continue
+ if test_type in typelist:
+ target_list.append(target_path)
+ return target_list
+
+ def _get_target_list_by_type(self, productform, typelist):
+ target_list = []
+ part_path_dic = self._get_part_path_data(productform)
+ for item in part_path_dic:
+ part_path_list = part_path_dic.get(item)
+ for part_path in part_path_list:
+ print("part_path = %s" % part_path)
+ temp_list = self._get_target_list_from_path(typelist,
+ part_path)
+ target_list.extend(temp_list)
+ return target_list
+
+ def _get_target_list_by_part(self, productform, typelist, partlist):
+ target_list = []
+ part_path_dic = self._get_part_path_data(productform)
+ for partname in partlist:
+ part_path_list = part_path_dic.get(partname, [])
+ for part_path in part_path_list:
+ temp_list = self._get_target_list_from_path(typelist,
+ part_path)
+ target_list.extend(temp_list)
+ return target_list
+
+ def _get_target_list_by_module(self, productform, typelist, partlist,
+ testmodule):
+ target_list = []
+ part_path_dic = self._get_part_path_data(productform)
+ for partname in partlist:
+ part_path_list = part_path_dic.get(partname, [])
+ for part_path in part_path_list:
+ module_path = os.path.join(part_path, testmodule)
+ LOG.info("module_path = %s." % module_path)
+ if os.path.exists(module_path):
+ temp_list = self._get_target_list_from_path(typelist,
+ module_path)
+ target_list.extend(temp_list)
+ return target_list
+
+ def get_build_targets(self, productform, typelist, partlist, testmodule):
+ target_list = []
+
+ if productform == "" or len(typelist) == 0:
+ LOG.warning("Error: productform or typelist is empty.")
+ return []
+
+ if len(partlist) == 0 and testmodule != "":
+ LOG.warning(
+ "The part cannot be empty When the module is not empty.")
+ return []
+
+ if len(partlist) == 0 and testmodule == "":
+ target_list = self._get_target_list_by_type(productform, typelist)
+ return target_list
+
+ if len(partlist) != 0 and testmodule == "":
+ target_list = self._get_target_list_by_part(productform, typelist,
+ partlist)
+ return target_list
+
+ if len(partlist) != 0 and testmodule != "":
+ target_list = self._get_target_list_by_module(productform,
+ typelist,
+ partlist,
+ testmodule)
+
+ return target_list
+
+ def filter_build_targets(self, para):
+ productform = para.productform
+ typelist = para.testtype
+ partlist = para.partname_list
+ testmodule = para.testmodule
+
+ print("partlist = %s" % str(partlist))
+ target_list = self.get_build_targets(productform, typelist,
+ partlist, testmodule)
+ return target_list
+
+
+##############################################################################
+##############################################################################
diff --git a/src/core/constants.py b/src/core/constants.py
index 29dc0c4d61af1d805f0eda4fa7091f53b5bc0c80..a1a3187a8c7a5d4924569780f8b3702f50e8fe1e 100755
--- a/src/core/constants.py
+++ b/src/core/constants.py
@@ -75,3 +75,51 @@ class ConfigFileConst(object):
def user_config_file(self):
return ConfigFileConst.USERCONFIG_FILEPATH
+
+class JsTestConst(object):
+ BUILD_GN_FILE_TEMPLATE = """\
+# Copyright (C) 2021 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build/test.gni")
+
+module_output_path = "%(output_path)s"
+
+ohos_js_unittest("%(suite_name)s") {
+ module_out_path = module_output_path
+ hap_profile = "./src/main/config.json"
+ deps = [
+ ":%(suite_name)s_js_assets",
+ ":%(suite_name)s_resources",
+ ]
+
+ certificate_profile = "//test/developertest/signature/openharmony_sx.p7b"
+ hap_name = "%(suite_name)s"
+}
+ohos_js_assets("%(suite_name)s_js_assets") {
+ source_dir = "./src/main/js/default"
+}
+ohos_resources("%(suite_name)s_resources") {
+ sources = [ "./src/main/resources" ]
+ hap_profile = "./src/main/config.json"
+}
+
+group("unittest") {
+ testonly = true
+ deps = [ ":%(suite_name)s" ]
+}
+"""
+
+ @property
+ def build_gn_template(self):
+ return JsTestConst.BUILD_GN_FILE_TEMPLATE
diff --git a/src/core/driver/drivers.py b/src/core/driver/drivers.py
index 51e1cf6e573fc351a9fea572d1b7f8c9ed953872..4ea53429d85c9c303e6d69ca50f577ca196626ef 100755
--- a/src/core/driver/drivers.py
+++ b/src/core/driver/drivers.py
@@ -16,20 +16,26 @@
# limitations under the License.
#
+import json
import os
import re
+import shutil
import time
import platform
+import zipfile
from dataclasses import dataclass
from xdevice import DeviceTestType
from xdevice import DeviceLabelType
from xdevice import ExecuteTerminate
from xdevice import DeviceError
+from xdevice import ShellHandler
from xdevice import IDriver
from xdevice import platform_logger
from xdevice import Plugin
+from xdevice import get_plugin
+from xdevice_extension._core.constants import CommonParserType
from core.utils import get_decode
from core.utils import get_fuzzer_path
from core.config.resource_manager import ResourceManager
@@ -38,6 +44,7 @@ from core.config.config_manager import FuzzerConfigManager
__all__ = [
"CppTestDriver",
+ "JSUnitTestDriver",
"disable_keyguard",
"GTestConst"]
@@ -564,3 +571,239 @@ class CppTestDriver(IDriver):
##############################################################################
##############################################################################
+
+@Plugin(type=Plugin.DRIVER, id=DeviceTestType.jsunit_test)
+class JSUnitTestDriver(IDriver):
+ """
+ JSUnitTestDriver is a Test that runs a native test package on given device.
+ """
+
+ def __init__(self):
+ self.config = None
+ self.result = ""
+ self.start_time = None
+ self.ability_name = ""
+ self.package_name = ""
+
+ def __check_environment__(self, device_options):
+ pass
+
+ def __check_config__(self, config):
+ pass
+
+ def __result__(self):
+ return self.result if os.path.exists(self.result) else ""
+
+ def __execute__(self, request):
+ try:
+ LOG.info("developertest driver")
+ self.result = os.path.join(request.config.report_path,
+ "result",
+ '.'.join((request.get_module_name(),
+ "xml")))
+ self.config = request.config
+ self.config.target_test_path = DEFAULT_TEST_PATH
+ self.config.device = request.config.environment.devices[0]
+
+ suite_file = request.root.source.source_file
+ if not suite_file:
+ LOG.error("test source '%s' not exists" %
+ request.root.source.source_string)
+ return
+
+ if not self.config.device:
+ result = ResultManager(suite_file, self.config)
+ result.set_is_coverage(False)
+ result.make_empty_result_file(
+ "No test device is found")
+ return
+
+ package_name, ability_name = self._get_package_and_ability_name(
+ suite_file)
+ self.package_name = package_name
+ self.ability_name = ability_name
+ self.config.test_hap_out_path = \
+ "/data/data/%s/files/" % self.package_name
+
+ self._init_jsunit_test()
+ self._run_jsunit(suite_file)
+ self.generate_console_output(request)
+
+ finally:
+ self.config.device.stop_catch_device_log()
+
+ def _init_jsunit_test(self):
+ self.config.device.hdc_command("target mount")
+ self.config.device.execute_shell_command(
+ "rm -rf %s" % self.config.target_test_path)
+ self.config.device.execute_shell_command(
+ "mkdir -p %s" % self.config.target_test_path)
+ self.config.device.execute_shell_command(
+ "mount -o rw,remount,rw /%s" % "system")
+ self.config.device.hdc_command("shell hilog -r")
+
+
+ def _run_jsunit(self, suite_file):
+ filename = os.path.basename(suite_file)
+
+ resource_manager = ResourceManager()
+ resource_data_dic, resource_dir = \
+ resource_manager.get_resource_data_dic(suite_file)
+ resource_manager.process_preparer_data(resource_data_dic, resource_dir,
+ self.config.device)
+
+ main_result = self._install_hap(suite_file)
+ result = ResultManager(suite_file, self.config)
+
+ if main_result:
+ self._execute_hapfile_jsunittest()
+ self._uninstall_hap(self.package_name)
+ else:
+ self.result = result.get_test_results("Error: install hap failed")
+ LOG.error("Error: install hap failed")
+
+ resource_manager.process_cleaner_data(resource_data_dic, resource_dir,
+ self.config.device)
+
+ def generate_console_output(self, request):
+ report_name = request.get_module_name()
+ parsers = get_plugin(
+ Plugin.PARSER, CommonParserType.jsunit)
+ if parsers:
+ parsers = parsers[:1]
+ for listener in request.listeners:
+ listener.device_sn = self.config.device.device_sn
+ parser_instances = []
+
+ for parser in parsers:
+ parser_instance = parser.__class__()
+ parser_instance.suites_name = "{}_suites".format(report_name)
+ parser_instance.suites_name = request.listeners
+ parser_instance.listeners = request.listeners
+ parser_instances.append(parser_instance)
+ handler = ShellHandler(parser_instances)
+
+ from xdevice_extension._core import utils
+ command = "hdc_std -t %s shell hilog -x " % self.config.device. \
+ device_sn
+
+ output = utils.start_standing_subprocess(command, return_result=True)
+ LOG.debug("start to parsing hilog")
+ handler.__read__(output)
+ handler.__done__()
+
+
+ def _execute_hapfile_jsunittest(self):
+ _unlock_screen(self.config.device)
+ _unlock_device(self.config.device)
+
+ try:
+ return_message = self.start_hap_activity()
+ except (ExecuteTerminate, DeviceError) as exception:
+ return_message = str(exception.args)
+
+ _lock_screen(self.config.device)
+ return return_message
+
+ def _install_hap(self, suite_file):
+ message = self.config.device.hdc_command("install %s" % suite_file)
+ message = str(message).rstrip()
+ if message == "" or "success" in message:
+ return_code = True
+ if message != "":
+ LOG.info(message)
+ else:
+ return_code = False
+ if message != "":
+ LOG.warning(message)
+
+ _sleep_according_to_result(return_code)
+ return return_code
+
+ def start_hap_activity(self):
+ try:
+ command = "aa start -d 123 -a %s.MainAbility -b %s" \
+ % (self.package_name, self.package_name)
+ self.start_time = time.time()
+ result_value = self.config.device.execute_shell_command(
+ command, timeout=TIME_OUT)
+ LOG.info("result_value [[[[[%s]]]]]" % result_value)
+
+ if "success" in str(result_value).lower():
+ LOG.info("execute %s's testcase success. result value=%s"
+ % (self.package_name, result_value))
+ time.sleep(60)
+ else:
+ LOG.info("execute %s's testcase failed. result value=%s"
+ % (self.package_name, result_value))
+
+ _sleep_according_to_result(result_value)
+ return_message = result_value
+ except (ExecuteTerminate, DeviceError) as exception:
+ return_message = exception.args
+
+ return return_message
+
+ def _uninstall_hap(self, package_name):
+ return_message = self.config.device.execute_shell_command(
+ "bm uninstall -n %s" % package_name)
+ _sleep_according_to_result(return_message)
+ return return_message
+
+ @staticmethod
+ def _get_package_and_ability_name(hap_filepath):
+ package_name = ""
+ ability_name = ""
+
+ if os.path.exists(hap_filepath):
+ filename = os.path.basename(hap_filepath)
+
+ #unzip the hap file
+ hap_bak_path = os.path.abspath(os.path.join(
+ os.path.dirname(hap_filepath),
+ "%s.bak" % filename))
+ zf_desc = zipfile.ZipFile(hap_filepath)
+ try:
+ zf_desc.extractall(path=hap_bak_path)
+ except RuntimeError as error:
+ print(error)
+ zf_desc.close()
+
+ #verify config.json file
+ app_profile_path = os.path.join(hap_bak_path, "config.json")
+ if not os.path.exists(app_profile_path):
+ print("file %s not exist" % app_profile_path)
+ return package_name, ability_name
+
+ if os.path.isdir(app_profile_path):
+ print("%s is a folder, and not a file" % app_profile_path)
+ return package_name, ability_name
+
+ #get package_name and ability_name value
+ load_dict = {}
+ with open(app_profile_path, 'r') as load_f:
+ load_dict = json.load(load_f)
+ profile_list = load_dict.values()
+ for profile in profile_list:
+ package_name = profile.get("package")
+ if not package_name:
+ continue
+
+ abilities = profile.get("abilities")
+ for abilitie in abilities:
+ abilities_name = abilitie.get("name")
+ if abilities_name.startswith("."):
+ ability_name = package_name + abilities_name[
+ abilities_name.find("."):]
+ else:
+ ability_name = abilities_name
+ break
+ break
+
+ #delete hap_bak_path
+ if os.path.exists(hap_bak_path):
+ shutil.rmtree(hap_bak_path)
+ else:
+ print("file %s not exist" % hap_filepath)
+
+ return package_name, ability_name
diff --git a/src/core/testcase/testcase_manager.py b/src/core/testcase/testcase_manager.py
index fcfa13ef3b7bc6b3cedf624c79bb50a8ac7162f7..d0ac52af924604fa789f25c1dff2895ea3282e7c 100755
--- a/src/core/testcase/testcase_manager.py
+++ b/src/core/testcase/testcase_manager.py
@@ -30,6 +30,7 @@ TESTFILE_TYPE_DATA_DIC = {
"PYT": [],
"CXX": [],
"BIN": [],
+ "JST": [],
}
FILTER_SUFFIX_NAME_LIST = [".TOC", ".info", ".pyc"]
@@ -109,7 +110,7 @@ class TestCaseManager(object):
if suffix_name == ".dex":
suite_file_dictionary["DEX"].append(suite_file)
elif suffix_name == ".hap":
- suite_file_dictionary["HAP"].append(suite_file)
+ suite_file_dictionary["JST"].append(suite_file)
elif suffix_name == ".py":
if not self.check_python_test_file(suite_file):
continue