diff --git a/test/scripts/email_config.yaml b/test/scripts/auto_xts_test/config.yaml similarity index 38% rename from test/scripts/email_config.yaml rename to test/scripts/auto_xts_test/config.yaml index 329f3e79f2ef65b3a3f3b7f266e881620d976d14..c472bbd36bf7fa2b08d075127a140c85d1c8b811 100644 --- a/test/scripts/email_config.yaml +++ b/test/scripts/auto_xts_test/config.yaml @@ -1,35 +1,14 @@ -# Copyright (c) 2023 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. - -user_name : "" -sender_email_address : "" -auth_code : "" -receiver_list : - - "" -smtp_server: "" -smtp_port: "25" - -xts_report_file : "./auto_xts_test/result/summary_report.html" -sdk_report_file : "./sdk_test/sdk_test_report.html" -perf_report_file : "./performance_test/mail_data/email_msg.html" -attatchment_files : - - "./auto_xts_test/result/details_report.html" - - "./auto_xts_test/result/failures_report.html" - - "./performance_test/mail_data/performance_logs.zip" -image_files: - "./performance_test/mail_data/debug_full_time.jpg": performance00 - "./performance_test/mail_data/debug_incremental_time.jpg": performance01 - "./performance_test/mail_data/debug_size.jpg": performance02 - "./performance_test/mail_data/release_full_time.jpg": performance10 - "./performance_test/mail_data/release_incremental_time.jpg": performance11 - "./performance_test/mail_data/release_size.jpg": performance12 +# Copyright (c) 2023 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. + +path_xts_report : 'D:\\AutoXTSTest\\dayu200_xts\\suites\\acts\\reports' \ No newline at end of file diff --git a/test/scripts/auto_xts_test/get_resource/config.yaml b/test/scripts/auto_xts_test/get_resource/config.yaml deleted file mode 100644 index 392a034452314cabfc3bd78b87720e5f69cf8bae..0000000000000000000000000000000000000000 --- a/test/scripts/auto_xts_test/get_resource/config.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2023 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. - -url_dailybuilds : "http://ci.openharmony.cn/api/ci-backend/ci-portal/v1/dailybuilds" -headers : - 'Accept': 'application/json, text/plain, */*' - 'Accept-Encoding': 'gzip, deflate' - 'Accept-Language': 'zh-CN,zh;q=0.8' - 'Access-Control-Allow-Credentials': 'true' - 'Access-Control-Allow-Methods': 'POST, GET, PUT, OPTIONS, DELETE, PATCH' - 'Access-Control-Allow-Origin': '*' - 'Connection': 'keep-alive' - 'Content-Length': '216' - 'Content-Type': 'application/json;charset=UTF-8' - 'Cookie': '_frid=d54846f4e88e415587e14aed0e4a9d63;\ - __51vcke__JhI7USZ6OfAHQZUm=0af50c49-e1b6-5ca4-9356-a986a785be93;\ - __51vuft__JhI7USZ6OfAHQZUm=1684307559015;\ - _fr_ssid=c60810a1808f447b9f696d9534294dcb;\ - __51uvsct__JhI7USZ6OfAHQZUm=5;\ - __vtins__JhI7USZ6OfAHQZUm=%7B%22sid%22%3A%20%22972e7520-a952-52ff-b0f4-0c3ca53da01b%22%2C%20%22vd%22%3A%205%2C%20%22stt%22%3A%201947502%2C%20%22dr%22%3A%20409887%2C%20%22expires%22%3A%201684921552594%2C%20%22ct%22%3A%201684919752594%7D;\ - _fr_pvid=3a57d4c932eb4e10814323c8d3758b0d' - 'hide': 'false' - 'Host': 'ci.openharmony.cn' - 'Origin': 'http://ci.openharmony.cn' - 'Referer': 'http://ci.openharmony.cn/dailys/dailybuilds' - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64) \ - AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0\ - Safari/537.36 Edg/113.0.1774.50' -data: - 'branch': "master" - 'buildFailReason': "" - 'buildStatus': "success" - 'component': "dayu200" - 'deviceLevel': "" - 'endTime': "" - 'hardwareBoard': "" - 'pageNum': 1 - 'pageSize': 8 - 'projectName': "openharmony" - 'startTime': "" - 'testResult': "" -url_dayu200: - - "http://download.ci.openharmony.cn/version/Daily_Version/dayu200/" - - "/version-Daily_Version-dayu200-" - - "-dayu200.tar.gz" -url_tools : 'http://123.60.114.105:9999/RKDevTool.zip' -path_xts_pack : 'D:\\AutoXTSTest\\dayu200_xts.tar.gz' -path_xts_dir : 'D:\\AutoXTSTest\\dayu200_xts' -path_configfile : 'D:\\AutoXTSTest\\dayu200_xts\\suites\\acts\\config\\user_config.xml' -path_xts_report : 'D:\\AutoXTSTest\\dayu200_xts\\suites\\acts\\reports' \ No newline at end of file diff --git a/test/scripts/auto_xts_test/get_resource/get_tool.py b/test/scripts/auto_xts_test/get_resource/get_tool.py deleted file mode 100755 index 02c781bde7fdcd3ba549aa0a96130050fb548621..0000000000000000000000000000000000000000 --- a/test/scripts/auto_xts_test/get_resource/get_tool.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Copyright (c) 2023 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 json -import os -import stat -import zipfile - -import requests -from tqdm import tqdm -import yaml - - -def get_tool(url): - print(f"Getting RKDevTool from {url}") - r = requests.get(url, stream=True) - total = int(r.headers.get('content-length'), 0) - flags = os.O_WRONLY | os.O_CREAT - modes = stat.S_IWUSR | stat.S_IRUSR - - with os.fdopen(os.open(r".\RKDevTool.zip", flags, modes), "wb") as f, tqdm( - desc="RKDevTool.zip", - total=total, - unit='iB', - unit_scale=True, - unit_divisor=1024, - ) as bar: - for byte in r.iter_content(chunk_size=1024): - size = f.write(byte) - bar.update(size) - with zipfile.ZipFile(".\\RKDevTool.zip", 'r') as zfile: - zfile.extractall(path=".\\RKDevTool") - - -if __name__ == "__main__": - with open(r".\get_resource\config.yaml", 'r') as config_file: - data = yaml.safe_load(config_file.read()) - get_tool(data['url_tools']) \ No newline at end of file diff --git a/test/scripts/auto_xts_test/get_resource/spider.py b/test/scripts/auto_xts_test/get_resource/spider.py deleted file mode 100755 index 2c06247719915f64b2ff8b62600107235333a452..0000000000000000000000000000000000000000 --- a/test/scripts/auto_xts_test/get_resource/spider.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Copyright (c) 2023 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 json -import logging -import os -import stat -import tarfile -import xml.etree.ElementTree as ET - -import requests -from tqdm import tqdm -import yaml - - -def get_images_and_testcases(url, download_path, extract_path): - print(f"Get new image from {url},please wait!") - r = requests.get(url, stream=True) - total = int(r.headers.get('content-length'), 0) - flags = os.O_WRONLY | os.O_CREAT - modes = stat.S_IWUSR | stat.S_IRUSR - - with os.fdopen(os.open(download_path, flags, modes), "wb") as f, tqdm( - desc="dayu200_xts.tar.gz", - total=total, - unit='iB', - unit_scale=True, - unit_divisor=1024, - ) as bar: - for byte in r.iter_content(chunk_size=1024): - size = f.write(byte) - bar.update(size) - - print("extracrting file") - with tarfile.open(download_path, "r") as tar: - for member in tqdm(desc='dayu200_xts', iterable=tar.getmembers(), total=len(tar.getmembers())): - tar.extract(path=extract_path, member=member) - logging.basicConfig(filename="log.log", level='INFO') - logging.info(f'Downloading Success, url:{url}') - - -def get_url(url, headers, json_data, url_2): - response = requests.post(url, json=json_data, headers=headers) - json_obj = json.loads(response.text) - start_time = json_obj['result']['dailyBuildVos'][0]['buildStartTime'] - start_time = start_time[:8] + "_" + start_time[8:] - return url_2[0] + start_time + url_2[1] + start_time + url_2[2] - - -def change_port(xml_path, xml_dw="./environment/device/port"): - doc = ET.parse(xml_path) - root = doc.getroot() - port = root.find(xml_dw) - port.text = "8710" - doc.write(xml_path) - - -if __name__ == '__main__': - with open(r".\get_resource\config.yaml", 'r') as config_file: - data = yaml.safe_load(config_file.read()) - dest_url = get_url(data['url_dailybuilds'], data['headers'], data['data'], data['url_dayu200']) - get_images_and_testcases(dest_url, data['path_xts_pack'], data['path_xts_dir']) - change_port(data['path_configfile']) - \ No newline at end of file diff --git a/test/scripts/auto_xts_test/get_result.py b/test/scripts/auto_xts_test/result.py similarity index 89% rename from test/scripts/auto_xts_test/get_result.py rename to test/scripts/auto_xts_test/result.py index 4f3510ba241f38c706b5e9a60b1b77350f66e493..48a6294e5bd5ac5e36559d65797880ceedb3b13c 100755 --- a/test/scripts/auto_xts_test/get_result.py +++ b/test/scripts/auto_xts_test/result.py @@ -1,40 +1,39 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Copyright (c) 2023 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 shutil - -import yaml - -if __name__ == "__main__": - with open(r".\get_resource\config.yaml", 'r') as f: - data = yaml.safe_load(f.read()) - - path = data['path_xts_report'] - file_list = os.listdir(path) - - summary_report = os.path.join(path, file_list[-1], "summary_report.html") - if (os.path.exists(summary_report)): - shutil.copy2(summary_report, "result\\") - - details_report = os.path.join(path, file_list[-1], "details_report.html") - if (os.path.exists(details_report)): - shutil.copy2(details_report, "result\\") - - failures_report = os.path.join(path, file_list[-1], "failures_report.html") - if (os.path.exists(failures_report)): - shutil.copy2(failures_report, "result\\") \ No newline at end of file +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2023 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 shutil + +import yaml + +if __name__ == "__main__": + with open(r".\config.yaml", 'r') as f: + data = yaml.safe_load(f.read()) + + path = data['path_xts_report'] + file_list = os.listdir(path) + + summary_report = os.path.join(path, file_list[-1], "summary_report.html") + if (os.path.exists(summary_report)): + shutil.copy2(summary_report, "result\\") + + details_report = os.path.join(path, file_list[-1], "details_report.html") + if (os.path.exists(details_report)): + shutil.copy2(details_report, "result\\") + + failures_report = os.path.join(path, file_list[-1], "failures_report.html") + if (os.path.exists(failures_report)): + shutil.copy2(failures_report, "result\\") diff --git a/test/scripts/auto_xts_test/run.bat b/test/scripts/auto_xts_test/run.bat index f372bb6b7858a27b502f85e1e6d1264770ac8013..e588f7efbcd2e188d4470f8fdbd0cc7e8bd1101f 100755 --- a/test/scripts/auto_xts_test/run.bat +++ b/test/scripts/auto_xts_test/run.bat @@ -18,36 +18,14 @@ REM change to work directory cd /d %~dp0 REM log -echo "------------------------------------------------" >> log.log - -REM get tool -if not exist .\RKDevTool ( -python .\get_resource\get_tool.py -.\RKDevTool\DriverAssitant_v5.1.1\DriverAssitant_v5.1.1\DriverInstall.exe -del /q .\RKDevTool.zip -) -if not exist .\RKDevTool\RKDevTool.exe (goto ToolError) - -REM get image & XTS testcases -set var=D:\AutoXTSTest -if not exist %var% (md %var%) -rd /s /q %var%\dayu200_xts -python .\get_resource\spider.py -del /q %var%\dayu200_xts.tar.gz -if not exist %var%\dayu200_xts\suites (goto ResourceError) - -REM load image to rk3568 -hdc shell reboot bootloader -cd RKDevTool -python ..\autoburn.py -cd .. -for /f "tokens=*" %%i in ('hdc list targets') do (set target=%%i) -if "%var%"=="[Empty]" (goto BurnError) +echo "------------------------------------------------" >> log.txt REM run XTStest +set var=D:\AutoXTSTest timeout /t 15 hdc shell "power-shell setmode 602" hdc shell "hilog -Q pidoff" +cd /d %~dp0 for /f "tokens=1,2 delims==" %%i in (running_modules.txt) do ( if "%%i"=="modules" set value=%%j ) @@ -55,25 +33,12 @@ call %var%\dayu200_xts\suites\acts\run.bat run -l %value% REM get result cd /d %~dp0 -echo "Successfully excute script" >> log.log +echo "Successfully excute script" >> log.txt if exist result (rd /s /q result) md result -python get_result.py +python result.py ENDLOCAL exit -REM error process -: ToolError -echo "Error happens while getting tool" >> log.log -ENDLOCAL -exit -: ResourceError -echo "Error happens while getting dailybuilds resource" >> log.log -ENDLOCAL -exit -: BurnError -echo "Error happens while burnning images" >> log.log -ENDLOCAL -exit \ No newline at end of file diff --git a/test/scripts/timer.py b/test/scripts/entry.py similarity index 47% rename from test/scripts/timer.py rename to test/scripts/entry.py index 99b2630bf42789975027e5486b0ad15c88400648..aa1840b7ede97821e4d70bfdf0ca638ffdc58a45 100755 --- a/test/scripts/timer.py +++ b/test/scripts/entry.py @@ -1,46 +1,72 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Copyright (c) 2023 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 subprocess -import time - -import schedule - - -def job(cmd): - subprocess.run(cmd, shell=False) - - -def run(): - job(os.path.join(".", "auto_xts_test", "run.bat")) - job(f'python {os.path.join(".", "sdk_test", "entry.py")}') - if not os.path.exists("sdk_url.txt"): - print('SDK download failed') - return - - job(f'python {os.path.join(".", "performance_test", "performance_entry.py")}') - job(f'python {os.path.join(".", "send_email.py")}') - - -if __name__ == "__main__": - os.chdir(os.path.dirname(os.path.realpath(__file__))) - schedule.every().day.at("02:10").do(run) - run() - while True: - schedule.run_pending() - time.sleep(1) +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2023 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 argparse +import os +import subprocess +import time + +import schedule + +from utils.download_sdk_and_image.download import get_the_image + + +def prepare_test(): + arguments = parse_args() + prepared = True + if not arguments.skip_download_sdk: + sdk_prepared = get_the_image('sdk', '', None, None) + prepared = prepared and sdk_prepared + if not arguments.skip_download_dayu: + dayu_prepared = get_the_image('dayu', '', None, None) + job(['python', './utils/flash_image/burn_image.py']) + prepared = prepared and dayu_prepared + job(['python', './utils/commit_message/get_commit_message.py']) + return prepared + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--skipDownloadSdk', dest='skip_download_sdk', action='store_true', default=False, + help='specify whether to skip the download sdk or not') + parser.add_argument('--skipDownloadDayu', dest='skip_download_dayu', action='store_true', default=False, + help='specify whether to skip the download dayu or not') + + return parser.parse_args() + + +def job(cmd): + subprocess.run(cmd, shell=False) + + +def run(): + if not prepare_test(): + return + + job(os.path.join(".", "auto_xts_test", "run.bat")) + job(f'python {os.path.join(".", "sdk_test", "entry.py")}') + job(f'python {os.path.join(".", "performance_test", "performance_entry.py")}') + job(f'python {os.path.join(".", "utils", "send_email", "send_email.py")}') + + +if __name__ == '__main__': + schedule.every().day.at("02:10").do(run) + run() + while True: + schedule.run_pending() + time.sleep(1) + + diff --git a/test/scripts/readme.md b/test/scripts/readme.md index 4a8b71a3769700df8cb001c94fab946d87baa583..97e7e9b5c4f88779a9e2809bb95767b1cbd4b3c1 100644 --- a/test/scripts/readme.md +++ b/test/scripts/readme.md @@ -5,11 +5,12 @@ 2. Run xts test which in auto_xts_test 3. Run sdk_test which in sdk_test 4. Run performance test which in performance_test -5. Send the result by Email +5. Run spider script which in get commit log +6. Send the result by Email ## Usage ### How to work -In timer.py, it will run downloading sdk,xts, sdk_test,performance_test, and send email, you can delete any of them if you don't need run the test. +In entry.py, it will run downloading sdk,xts, sdk_test,performance_test, get commit log script, and send email, you can delete any of them if you don't need run the test. If you do not want to run test immediately, delete run_all() Set email infos in email_config ### Note diff --git a/test/scripts/readme_zh.md b/test/scripts/readme_zh.md index 0d8ac23b3bda48892b80aadc85dd3a78e9c88977..39e8adbb37ceece5fb5e4a006e3ca8a23f39c881 100644 --- a/test/scripts/readme_zh.md +++ b/test/scripts/readme_zh.md @@ -5,14 +5,15 @@ 2.xts自动化测试,在auto_xts_test中 3.sdk自动化测试套,在sdk_test中 4.端到端构建性能测试,在performance_test中 -5.自动发送结果至指定邮箱 +5.获取仓库提交信息,在get_commit_log中 +6.自动发送结果至指定邮箱 ## 脚本使用 -timer.py中,包含了下载sdk,xts, sdk_test,performance_test,以及发送邮件,如不需要可以去除。 -触发脚本时,如果不需要立即执行,可以去掉run_all() +timer.py中,包含了下载sdk,xts, sdk_test,performance_test,获取每日提交信息脚本,以及发送邮件,如不需要可以去除。 +输入时间参数将会对任务进行定时,否则立即开始测试任务 email_config中包含了邮箱的设置 ### 脚本运行 -使用命令python timer.py +使用命令python entry.py ### 注意事项 下载的SDK为24小时内的daily build,如果下载失败则会中断执行后续测试。 diff --git a/test/scripts/sdk_test/config.yaml b/test/scripts/sdk_test/config.yaml index ffd306bf0439f30ca75ddd1af3c3ebf2345de3e2..28739a8e6f8494a91c1083903f9967d6fdcbf707 100644 --- a/test/scripts/sdk_test/config.yaml +++ b/test/scripts/sdk_test/config.yaml @@ -15,12 +15,19 @@ # environment settings deveco_path: D:\Software\Deveco-0602\DevEco Studio -deveco_sdk_path: D:\deveco-sdk\deveco-sdk-0602 +deveco_harmonyos_sdk_path: D:\SDK\HarmonyOS_SDK +deveco_openharmony_sdk_path: D:\SDK\openHarmony_SDK node_js_path: D:\Software\nodejs # The nodejs which is used in Deveco +# the mapping between API and file name +api_version_file_name_map: + '4.0.0(10)': "HarmonyOS-NEXT-DP0" + '4.1.0(11)': "HarmonyOS-NEXT-DP1" + '5.0.0(12)': "HarmonyOS-NEXT-DB0" # output settings output_html_file: ./sdk_test_report.html log_file: ./sdk_test_log.txt +pictures_dic: ./pictures # descriptions about test haps list # each hap have the following attributes: @@ -67,8 +74,11 @@ haps: path: D:\sdk-test\DemoApplication_EmptyAbility type: [stage, ohosTest, exceed_length_error, error] build_path: [entry, build, default] + bundle_name: com.example.idestagedemoemptyability + ability_name: EntryAbility cache_path: [cache, default, default@CompileArkTS, esmodule] output_hap_path: [outputs, default, entry-default-unsigned.hap] + output_hap_path_signed: [outputs, default, entry-default-signed.hap] output_app_path: [outputs, default, app, entry-default.hap] inc_modify_file: [entry, src, main, ets, pages, Index.ets] description: @@ -77,8 +87,11 @@ haps: path: D:\sdk-test\DemoApplication_EmptyAbility_fa type: [fa, ohosTest, exceed_length_error, error] build_path: [entry, build, default] + bundle_name: com.example.idefademoemptyability + ability_name: com.example.idefademoemptyability.MainAbility cache_path: [cache, default, default@LegacyCompileArkTS, jsbundle] output_hap_path: [outputs, default, entry-default-unsigned.hap] + output_hap_path_signed: [outputs, default, entry-default-signed.hap] output_app_path: [outputs, default, app, entry-default.hap] inc_modify_file: [entry, src, main, ets, MainAbility, pages, index.ets] description: @@ -87,17 +100,23 @@ haps: path: D:\sdk-test\DemoApplication_EmptyAbility_compatible8 type: [compatible8, ohosTest, exceed_length_error, error] build_path: [entry, build, default] + bundle_name: com.example.idecompatible8demoemptyability + ability_name: com.example.idecompatible8demoemptyability.MainAbility cache_path: [cache, default, default@LegacyCompileArkTS, jsbundle] output_hap_path: [outputs, default, entry-default-unsigned.hap] + output_hap_path_signed: [outputs, default, entry-default-signed.hap] output_app_path: [outputs, default, app, entry-default.hap] inc_modify_file: [entry, src, main, ets, MainAbility, pages, index.ets] description: - idedemo_03: name: IdeJsDemoEmptyAbility - path: D:\sdk-test\DemoApplication_EmptyAbility_js + path: D:\sdk-test\DemoApplication_EmptyAbility_js type: [js, ohosTest, exceed_length_error, error] build_path: [entry, build, default] + bundle_name: com.example.idejsdemoemptyability + ability_name: com.example.idejsdemoemptyability.MainAbility cache_path: [cache, default, default@LegacyCompileJS, jsbundle] + output_hap_path_signed: [ outputs, default, entry-default-signed.hap] output_hap_path: [outputs, default, entry-default-unsigned.hap] output_app_path: [outputs, default, app, entry-default.hap] inc_modify_file: [entry, src, main, js, MainAbility, pages, index, index.js] diff --git a/test/scripts/sdk_test/entry.py b/test/scripts/sdk_test/entry.py index fea78fdc33a431f70171cb9f939b92a2829aa4e8..721397e4957bb12fd1558e8f94bab5f96f932d33 100644 --- a/test/scripts/sdk_test/entry.py +++ b/test/scripts/sdk_test/entry.py @@ -25,13 +25,11 @@ import utils def run(): - sdk_url = utils.get_sdk_url() - cmd = ['python', 'run.py'] - cmd.extend(['--sdkPath', sdk_url]) cmd.extend(['--hapMode', 'all']) cmd.extend(['--compileMode', 'all']) cmd.extend(['--logLevel', 'debug']) + cmd.extend(['--runHaps']) cmd.extend(['--logFile', 'log' + '_' + utils.get_time_string() + '.txt']) current_dir = os.path.dirname(os.path.abspath(__file__)) diff --git a/test/scripts/sdk_test/execution.py b/test/scripts/sdk_test/execution.py index bcdeb614e66b7eb8a41eb7addb8d2cecb95764bc..d2a5d46cbb0ef82eb88dd8ff8f80518a790a31ed 100644 --- a/test/scripts/sdk_test/execution.py +++ b/test/scripts/sdk_test/execution.py @@ -24,6 +24,7 @@ import re import shutil import signal import subprocess +import time import zipfile import json5 @@ -48,7 +49,8 @@ class IncrementalTest: logging.debug(f"new module hap file: {new_module_name_output_file}") passed = validate(inc_task, task, is_debug, stdout, - stderr, new_module_name_output_file) + stderr, 'incremental_compile_change_module_name', + new_module_name_output_file) logging.debug(f"validate new module hap file, passed {passed}") if not passed: return @@ -66,7 +68,7 @@ class IncrementalTest: modules_pa = disasm_abc(task, modules_abc_path) if not modules_pa or not os.path.exists(modules_pa): inc_info.result = options.TaskResult.failed - inc_info.error_message = f'ark_disasm failed, module name change not verified' + inc_info.error_message = 'ark_disasm failed, module name change not verified' return func_str = '' @@ -172,7 +174,7 @@ class IncrementalTest: logging.info(f"==========> Running {test_name} for task: {task.name}") [stdout, stderr] = compile_project(task, is_debug) - passed = validate(inc_task, task, is_debug, stdout, stderr) + passed = validate(inc_task, task, is_debug, stdout, stderr, 'incremental_compile_no_change') if passed: IncrementalTest.validate_compile_incremental_file( task, inc_task, is_debug, []) @@ -193,7 +195,7 @@ class IncrementalTest: 'patch_lines_2').get('tail')) [stdout, stderr] = compile_project(task, is_debug) - passed = validate(inc_task, task, is_debug, stdout, stderr) + passed = validate(inc_task, task, is_debug, stdout, stderr, 'incremental_compile_add_oneline') if passed: modified_files = [os.path.join(*modify_file_item)] IncrementalTest.validate_compile_incremental_file( @@ -238,7 +240,7 @@ class IncrementalTest: file.write(patch_lines.get('tail')) [stdout, stderr] = compile_project(task, is_debug) - passed = validate(inc_task, task, is_debug, stdout, stderr) + passed = validate(inc_task, task, is_debug, stdout, stderr, 'incremental_compile_add_file') if passed: modified_files = [os.path.join(*modify_file_item)] IncrementalTest.validate_compile_incremental_file( @@ -256,7 +258,7 @@ class IncrementalTest: # this test is after 'add_file', and in test 'add_file' already done remove file, # so here just call compile [stdout, stderr] = compile_project(task, is_debug) - passed = validate(inc_task, task, is_debug, stdout, stderr) + passed = validate(inc_task, task, is_debug, stdout, stderr, 'incremental_compile_delete_file') if passed: modify_file_item = task.inc_modify_file modified_files = [os.path.join(*modify_file_item)] @@ -271,7 +273,7 @@ class IncrementalTest: logging.info(f"==========> Running {test_name} for task: {task.name}") hap_mode = not is_debug [stdout, stderr] = compile_project(task, hap_mode) - validate(inc_task, task, hap_mode, stdout, stderr) + validate(inc_task, task, hap_mode, stdout, stderr, 'incremental_compile_reverse_hap_mode') @staticmethod def compile_incremental_modify_module_name(task, is_debug): @@ -426,6 +428,8 @@ class OtherTest: passed = validate_compile_output(test_info, task, is_debug) if passed: test_info.result = options.TaskResult.passed + if options.arguments.run_haps: + run_compile_output(test_info, task, True, 'other_tests_break_continue_compile') @staticmethod def compile_full_with_error(task, is_debug): @@ -751,11 +755,23 @@ def validate_compile_output(info, task, is_debug, output_file=''): return passed -def run_compile_output(info, task_path): - # TODO: - # 1)install hap - # 2)run hap and verify - return False +def run_compile_output(info, task, is_debug, picture_name): + picture_suffix = 'debug' + if not is_debug: + picture_suffix = 'release' + picture_name = f'{picture_name}_{picture_suffix}' + utils.get_running_screenshot(task, picture_name) + time.sleep(2) + runtime_passed = utils.verify_runtime(task, picture_name) + if not runtime_passed: + logging.error(f'The runtime of the {task.name} is inconsistent with the reference screenshot,' + f' when running {picture_name}') + info.runtime_result = options.TaskResult.failed + info.error_message = "The runtime result is inconsistent with the reference" + else: + info.runtime_result = options.TaskResult.passed + + return runtime_passed def is_compile_success(compile_stdout): @@ -767,7 +783,7 @@ def is_compile_success(compile_stdout): return [True, match_result.group(0)] -def validate(compilation_info, task, is_debug, stdout, stderr, output_file=''): +def validate(compilation_info, task, is_debug, stdout, stderr, picture_name, output_file=''): info = {} if is_debug: info = compilation_info.debug_info @@ -784,7 +800,7 @@ def validate(compilation_info, task, is_debug, stdout, stderr, output_file=''): passed = validate_compile_output(info, task, is_debug, output_file) if options.arguments.run_haps: - passed &= run_compile_output(info) + runtime_passed = run_compile_output(info, task, is_debug, picture_name) if passed: collect_compile_time(info, time_string) @@ -852,7 +868,7 @@ def compile_incremental(task, is_debug): if options.arguments.compile_mode == 'incremental': passed = validate(task.full_compilation_info, - task, is_debug, stdout, stderr) + task, is_debug, stdout, stderr, 'incremental_compile_first') if not passed: logging.error( "Incremental compile failed due to first compile failed!") @@ -939,14 +955,14 @@ def execute_full_compile(task): if options.arguments.hap_mode in ['all', 'release']: [stdout, stderr] = compile_project(task, False) passed = validate(task.full_compilation_info, - task, False, stdout, stderr) + task, False, stdout, stderr, 'full_compile') if passed: backup_compile_output(task, False) clean_compile(task) if options.arguments.hap_mode in ['all', 'debug']: [stdout, stderr] = compile_project(task, True) passed = validate(task.full_compilation_info, - task, True, stdout, stderr) + task, True, stdout, stderr, 'full_compile') if passed: backup_compile_output(task, True) clean_compile(task) diff --git a/test/scripts/sdk_test/options.py b/test/scripts/sdk_test/options.py index 0f5e58b17399b65a2446ea83e70d46186452d295..febc2604f91b85f380612c3ec070a76fda32e8eb 100644 --- a/test/scripts/sdk_test/options.py +++ b/test/scripts/sdk_test/options.py @@ -42,6 +42,7 @@ class TaskResult(Enum): class CompilationInfo: def __init__(self): self.result = TaskResult.undefind + self.runtime_result = TaskResult.undefind self.error_message = '' self.time = 0 self.abc_size = 0 @@ -73,9 +74,12 @@ class TestTask: def __init__(self): self.name = '' self.path = '' + self.bundle_name = '' + self.ability_name = '' self.type = '' self.build_path = [] self.output_hap_path = '' + self.output_hap_path_signed = '' self.output_app_path = '' self.inc_modify_file = [] @@ -127,13 +131,19 @@ def parse_configs(): def get_ark_disasm_path(task_path): - sdk_path = configs.get('deveco_sdk_path') ark_disasm = 'ark_disasm.exe' if utils.is_windows() else 'ark_disasm' profile_file = os.path.join(task_path, 'build-profile.json5') with open(profile_file, 'r') as file: profile_data = json5.load(file) - return os.path.join(sdk_path, str(profile_data['app']['products'][0]['compileSdkVersion']), - 'toolchains', ark_disasm) + api_version = profile_data['app']['products'][0]['compileSdkVersion'] + if isinstance(api_version, int): + openharmony_sdk_path = configs.get('deveco_openharmony_sdk_path') + return os.path.join(openharmony_sdk_path, str(api_version), 'toolchains', ark_disasm) + else: + harmonyos_sdk_path = configs.get('deveco_harmonyos_sdk_path') + api_version_file_map = configs.get('api_version_file_name_map') + file_name = api_version_file_map.get(api_version) + return os.path.join(harmonyos_sdk_path, file_name, 'base', 'toolchains', ark_disasm) def create_test_tasks(): @@ -156,10 +166,13 @@ def create_test_tasks(): task = TestTask() task.name = hap['name'] task.path = hap['path'] + task.bundle_name = hap['bundle_name'] + task.ability_name = hap['ability_name'] task.type = hap['type'] task.build_path = hap['build_path'] task.cache_path = hap['cache_path'] task.output_hap_path = hap['output_hap_path'] + task.output_hap_path_signed = hap['output_hap_path_signed'] task.output_app_path = hap['output_app_path'] task.inc_modify_file = hap['inc_modify_file'] task.backup_info.cache_path = os.path.join(task.path, 'test_suite_cache') diff --git a/test/scripts/sdk_test/preparation.py b/test/scripts/sdk_test/preparation.py index 32cdc805e25f19b21e0473e84473bbe87ec5dc56..04afa4d127dd0eefb978c5165b2f5370a28f4e48 100644 --- a/test/scripts/sdk_test/preparation.py +++ b/test/scripts/sdk_test/preparation.py @@ -21,14 +21,9 @@ Description: prepare environment for test import logging import os import shutil -import tarfile -import zipfile - -import validators import options -from utils import is_linux, is_mac, get_time_string, add_executable_permission -from utils import get_api_version, check_gzip_file, download, get_remote_sdk_name +from utils import is_mac, is_linux def setup_env(): @@ -62,93 +57,11 @@ def check_deveco_env(): return True -def get_sdk_from_remote(sdk_url): - deveco_sdk_path = options.configs.get('deveco_sdk_path') - temp_floder = deveco_sdk_path + '_temp' - sdk_name = get_remote_sdk_name() - sdk_zip_path_list = [temp_floder, 'ohos-sdk', 'windows'] - if is_mac(): - sdk_zip_path_list = [temp_floder, 'sdk', - 'packages', 'ohos-sdk', 'darwin'] - sdk_temp_file = os.path.join(temp_floder, sdk_name) - - if os.path.exists(temp_floder): - shutil.rmtree(temp_floder) - os.mkdir(temp_floder) - download(sdk_url, sdk_temp_file, sdk_name) - if not check_gzip_file(sdk_temp_file): - logging.error('The downloaded file is not a valid gzip file.') - return '', '' - with tarfile.open(sdk_temp_file, 'r:gz') as tar: - tar.extractall(temp_floder) - - sdk_floder = os.path.join(temp_floder, 'SDK_TEMP') - sdk_zip_path = os.path.join(*sdk_zip_path_list) - for item in os.listdir(sdk_zip_path): - if item != '.DS_Store': - logging.info(f'Unpacking {item}') - with zipfile.ZipFile(os.path.join(sdk_zip_path, item)) as zip_file: - zip_file.extractall(os.path.join(sdk_floder)) - logging.info(f'Decompression {item} completed') - - api_version = get_api_version(os.path.join( - *[sdk_floder, 'ets', 'oh-uni-package.json'])) - return sdk_floder, api_version - - -def update_sdk_to_deveco(sdk_path, api_version): - deveco_sdk_path = options.configs.get('deveco_sdk_path') - deveco_sdk_version_path = os.path.join(deveco_sdk_path, api_version) - for sdk_item in os.listdir(deveco_sdk_path): - if sdk_item.startswith(f'{api_version}-'): - shutil.rmtree(os.path.join(deveco_sdk_path, sdk_item)) - if os.path.exists(deveco_sdk_version_path): - shutil.move(deveco_sdk_version_path, - deveco_sdk_version_path + '-' + get_time_string()) - for item in os.listdir(sdk_path): - if item != '.DS_Store': - if is_mac(): - if item == 'toolchains': - add_executable_permission( - os.path.join(sdk_path, item, 'restool')) - add_executable_permission( - os.path.join(sdk_path, item, 'ark_disasm')) - elif item == 'ets': - add_executable_permission(os.path.join(sdk_path, item, 'build-tools', - 'ets-loader', 'bin', 'ark', 'build-mac', 'bin', 'es2abc')) - add_executable_permission(os.path.join(sdk_path, item, 'build-tools', - 'ets-loader', 'bin', 'ark', 'build-mac', 'legacy_api8', 'bin', 'js2abc')) - elif item == 'js': - add_executable_permission(os.path.join(sdk_path, item, 'build-tools', - 'ace-loader', 'bin', 'ark', 'build-mac', 'bin', 'es2abc')) - add_executable_permission(os.path.join(sdk_path, item, 'build-tools', - 'ace-loader', 'bin', 'ark', 'build-mac', 'legacy_api8', 'bin', 'js2abc')) - shutil.move(os.path.join(sdk_path, item), - os.path.join(deveco_sdk_version_path, item)) - - -def prepare_sdk(): - sdk_arg = options.arguments.sdk_path - if sdk_arg == '': - return True # use the sdk specified in config.yaml - - api_version = '9' - sdk_path = sdk_arg - if validators.url(sdk_arg): - sdk_path, api_version = get_sdk_from_remote(sdk_arg) - - if not sdk_path or not os.path.exists(sdk_path): - return False - - update_sdk_to_deveco(sdk_path, api_version) - return True - - def prepare_image(): if options.arguments.run_haps: return True - # TODO: 1)download image, 2)flash image + # TODO: get pictures reference return True @@ -156,15 +69,18 @@ def prepare_image(): def clean_log(): output_log_file = options.configs.get('log_file') daily_report_file = options.configs.get('output_html_file') + pictures_dic = options.configs.get('pictures_dic') if os.path.exists(output_log_file): os.remove(output_log_file) if os.path.exists(daily_report_file): os.remove(daily_report_file) + if os.path.exists(pictures_dic): + shutil.rmtree(pictures_dic) def prepare_test_env(): clean_log() prepared = check_deveco_env() setup_env() - prepared = prepared and prepare_sdk() and prepare_image() + prepared = prepared and prepare_image() return prepared diff --git a/test/scripts/sdk_test/readme.md b/test/scripts/sdk_test/readme.md index a34eea22bd4a2f34468269a9848bac3b5040aec6..5bbbcedad11a0983bb219f6825372f7bed382b6e 100644 --- a/test/scripts/sdk_test/readme.md +++ b/test/scripts/sdk_test/readme.md @@ -11,12 +11,13 @@ The SDK test automation script runs on Windows, Python 3.9 and above. ### Test Preparation 1. Ensure that Deveco is installed in the environment. 2. Install dependencies of the test suite: -`python3 -m pip install pyyaml validators requests httpx tqdm json5 pandas` +`python3 -m pip install pyyaml validators requests httpx tqdm json5 pandas pillow` 3. Modify the configuration file `config.yaml`, configure relevant parameters of Deveco and the test application. Detailed configuration instructions can be found in the file. 4. To add a new test application, you can modify the config.yaml configuration file and add the configuration under the “haps” field. You can refer to the existing application configurations for guidance. ### Running Tests The test suite supports daily and manual runs. +The test functionality requires a connection to the RK board for testing. You can control whether to execute the test by using the "runHap" parameter. #### Daily Run The daily run will download the SDK built on the current day from the trunk branch and use it to perform a full test verification. diff --git a/test/scripts/sdk_test/readme_zh.md b/test/scripts/sdk_test/readme_zh.md index 756da5af27c5ac1b734ece803ab4e66533c4e89b..01309b7aa77d5d5a3f5a47159c266c610d24819e 100644 --- a/test/scripts/sdk_test/readme_zh.md +++ b/test/scripts/sdk_test/readme_zh.md @@ -10,12 +10,13 @@ SDK测试自动化脚本运行环境为windows,python3.9及以上。 ### 测试准备 1. 确保环境中已安装Deveco 2. 安装测试套依赖: -`python3 -m pip install pyyaml validators requests httpx tqdm json5 pandas` +`python3 -m pip install pyyaml validators requests httpx tqdm json5 pandas pillow` 3. 修改配置文件config.yaml,配置Deveco和测试应用的相关参数。各项配置说明详见该文件。 4. 如需新增测试应用,可修改配置文件config.yaml,在haps字段中增加配置。可参考配置中的已有应用进行配置。 ### 测试运行 测试套支持daily运行和手动单次运行。 +运行测试功能需要连接rk板进行测试,可通过参数runHap控制是否执行该测试 #### daily运行 daily运行将从主干分支下载当日构建的sdk,使用该sdk进行全量的测试项验证: 执行命令: diff --git a/test/scripts/sdk_test/result.py b/test/scripts/sdk_test/result.py index be8167ee8f7697e3e66d863e84ba03c50d049ab9..4c1cc7fe88860809145d6d949e70d30fd0444c55 100644 --- a/test/scripts/sdk_test/result.py +++ b/test/scripts/sdk_test/result.py @@ -22,6 +22,7 @@ import copy import logging import os import time +import zipfile import pandas @@ -213,20 +214,32 @@ def generate_detail_data(test_tasks): '[Full Compilation]\n[Release]\n[Compilation Time(s)]'] = full_compilation_release.time task_result_data['[Debug]'] = get_result_symbol( full_compilation_debug.result) + task_result_data['[Debug-runtime]'] = get_result_symbol( + full_compilation_debug.runtime_result) task_result_data['[Release]'] = get_result_symbol( full_compilation_release.result) + task_result_data['[Release-runtime]'] = get_result_symbol( + full_compilation_release.runtime_result) for test in incremetal_compile_tests: debug_result = options.TaskResult.undefind + debug_runtime_result = options.TaskResult.undefind release_result = options.TaskResult.undefind + release_runtime_result = options.TaskResult.undefind if test in task.incre_compilation_info.keys(): inc_task_info = task.incre_compilation_info[test] debug_result = inc_task_info.debug_info.result + debug_runtime_result = inc_task_info.debug_info.runtime_result release_result = inc_task_info.release_info.result + release_runtime_result = inc_task_info.release_info.runtime_result task_result_data[f'[Debug]\n{test}'] = get_result_symbol( debug_result) + task_result_data[f'[Debug-runtime]\n{test}'] = get_result_symbol( + debug_runtime_result) task_result_data[f'[Release]\n{test}'] = get_result_symbol( release_result) + task_result_data[f'[Release-runtime]\n{test}'] = get_result_symbol( + release_runtime_result) if test == 'add_oneline': debug_test_time = 0 @@ -243,10 +256,14 @@ def generate_detail_data(test_tasks): for test in other_tests: result = options.TaskResult.undefind + runtime_result = options.TaskResult.undefind if test in task.other_tests.keys(): task_info = task.other_tests[test] result = task_info.result + # todo + runtime_result = task_info.runtime_result task_result_data[f'{test}'] = get_result_symbol(result) + task_result_data[f'{test}-runtime'] = get_result_symbol(runtime_result) task_time_size_data['[Abc Size(byte)]\n[Debug]'] = full_compilation_debug.abc_size task_time_size_data['[Abc Size(byte)]\n[Release]'] = full_compilation_release.abc_size @@ -260,6 +277,52 @@ def generate_detail_data(test_tasks): return detail_data +def rotate_data(df): + num_rows, num_cols = df.shape + rotated_df = pandas.DataFrame(columns=range(num_rows), index=range(num_cols)) + for i in range(num_rows): + for j in range(num_cols): + rotated_df.iloc[j, i] = df.iloc[i, j] + return rotated_df + + +def get_merge_data(rotated_df): + data = rotated_df.iloc[3:, :].values.tolist() + merged_data = [] + for i in range(0, len(data) - 1, 2): + row = [value for sublist in zip(data[i], data[i + 1]) for value in sublist] + merged_data.append(row) + return merged_data + + +def get_result_table_content(result_df_rotate): + merged_data = get_merge_data(result_df_rotate) + content = 'Full Compilation[Debug]' + \ + ''.join( + [f'{column}' for column in merged_data[0]]) + '' + content += '[Release]' + \ + ''.join( + [f'{column}' for column in merged_data[1]]) + '' + content += f'Incremental Compilation' + start_index = 2 + for index, item in enumerate(incremetal_compile_tests): + content += f'{item}[Debug]' + \ + ''.join( + [f'{column}' for column in merged_data[start_index]]) + '' + content += '[Release]' + \ + ''.join( + [f'{column}' for column in merged_data[start_index+1]]) + '' + start_index = start_index + 2 + content += f'Other Tests' + for index, item in enumerate(other_tests): + content += f'{item}' + \ + ''.join( + [f'{column}' for column in merged_data[start_index]]) + '' + start_index = start_index + 1 + + return content + + def generate_data_html(summary_data, detail_data): # summary table key_value_pairs = [ @@ -291,22 +354,20 @@ def generate_data_html(summary_data, detail_data): # result table result_data = detail_data.get('result_data') result_df = pandas.DataFrame(result_data) + result_df_rotate = rotate_data(result_df) + + result_table_header = 'Task Index' + \ + ''.join( + [f'{column}' for column in result_df.iloc[:, 0].tolist()]) + '' + result_table_header += 'Task Name' + \ + ''.join( + [f'{column}' for column in result_df.iloc[:, 1].tolist()]) + '' + result_table_header += 'Task Type' + \ + ''.join( + [f'{column}' for column in result_df.iloc[:, 2].tolist()]) + '' + result_table_sub_header = f"Build && Run {'[build][runtime]' * result_df.shape[0]}" + result_table_content = get_result_table_content(result_df_rotate) - result_table_header = '' + \ - ''.join( - [f'{column}' for column in result_df.columns[:3]]) - result_table_header += 'Full Compilation' + \ - f'Incremental Compilation' + \ - f'Other Tests' - - result_table_sub_header = '' + \ - ''.join( - [f'{column}' for column in result_df.columns[3:]]) + '' - result_table_content = ''.join([ - '' + ''.join([f'{value}' for _, - value in row.items()]) + '' - for _, row in result_df.iterrows() - ]) result_table = f' \ {result_table_header}{result_table_sub_header}{result_table_content}
' @@ -320,6 +381,7 @@ def generate_report_html(summary_data, detail_data): html_content = f''' + + """ + + return table_style + + +def render_html(data): + table_rows = generate_html_table(data) + table_style = get_table_style() + html = f""" + + + + + 提交记录 + {table_style} + + +
+
+ + + + + + + + + + + + + {table_rows} + +
提交记录
仓库描述作者时间链接
+
+
+ + + + """ + + return html + + +def get_result(): + data_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data.txt') + with open(data_file, 'r', encoding='utf-8') as file: + lines = file.readlines() + + data = {} + for line in lines: + item = json.loads(line) + + repo_name = item['repo_name'] + if repo_name in data: + data[repo_name].append(item) + else: + data[repo_name] = [item] + + html = render_html(data) + + commit_log_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'commit_log.html') + with open(commit_log_file, 'w', encoding='utf-8') as file: + file.write(html) + + +if __name__ == '__main__': + get_result() diff --git a/test/scripts/utils/config.yaml b/test/scripts/utils/config.yaml new file mode 100755 index 0000000000000000000000000000000000000000..d157d094ce2183f07ecdee1f16380cf31be07c9f --- /dev/null +++ b/test/scripts/utils/config.yaml @@ -0,0 +1,76 @@ +# Copyright (c) 2024 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. + +# download_sdk_and image_config +# decide whether to save the download file or not[True,False] +is_save: True +# where to store your download files +download_save_path: D:\save_path +# choice download task and decide where to update the image +download_list: + - sdk: + name: sdk + url: '' + date: null + output_path_list: + - D:\SDK\openHarmony_SDK\11 + - D:\SDK\HarmonyOS_SDK\HarmonyOS-NEXT-DP1\base + # the mapping between API and file name + api_version_file_name_map: + "HarmonyOS-NEXT-DP0": 10 + "HarmonyOS-NEXT-DP1": 11 + "HarmonyOS-NEXT-DB0": 12 + - dayu200: + name: dayu200 + url: '' + date: null + output_path_list: + - D:\AutoXTSTest\dayu200_xts + +# commit_message_config +# Specify the date for which you want to retrieve the commit information, Use the following format: '2024-01-01' +commit_start_time: null +# which repo you want to get commit message +repo_list: + - 'arkcompiler_ets_frontend' + - 'developtools_ace_ets2bundle' + - 'third_party_typescript' + - 'arkcompiler_runtime_core' + +# flash_image_config +url_tools : 'http://123.60.114.105:9999/RKDevTool.zip' + +# send_email_config +user_name : "" +sender_email_address : "" +auth_code : "" +receiver_list : + - "" +smtp_server: "" +smtp_port: "25" + +xts_report_file : "../../auto_xts_test/result/summary_report.html" +sdk_report_file : "../../sdk_test/sdk_test_report.html" +perf_report_file : "../../performance_test/mail_data/email_msg.html" +commit_log_report_file : "../get_commit_log/commit_log.html" +attatchment_files : + - "../../auto_xts_test/result/details_report.html" + - "../../auto_xts_test/result/failures_report.html" + - "../../performance_test/mail_data/performance_logs.zip" +image_files: + "../../performance_test/mail_data/debug_full_time.jpg": performance00 + "../../performance_test/mail_data/debug_incremental_time.jpg": performance01 + "../../performance_test/mail_data/debug_size.jpg": performance02 + "../../performance_test/mail_data/release_full_time.jpg": performance10 + "../../performance_test/mail_data/release_incremental_time.jpg": performance11 + "../../performance_test/mail_data/release_size.jpg": performance12 \ No newline at end of file diff --git a/test/scripts/utils/download_sdk_and_image/download.py b/test/scripts/utils/download_sdk_and_image/download.py new file mode 100755 index 0000000000000000000000000000000000000000..04d1983ea126f73a4b0ef3fa22bf22f68a86628a --- /dev/null +++ b/test/scripts/utils/download_sdk_and_image/download.py @@ -0,0 +1,352 @@ +#!/usr/bin/env python3 +# coding: utf-8 + +""" +Copyright (c) 2024 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 awriting, 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 argparse +import re +import subprocess +import tarfile +import datetime +import gzip +from urllib.parse import urlparse + +import httpx +import json +import os +import requests +import shutil +import stat +import sys +import time +import tqdm +import yaml +import zipfile + + +def is_windows(): + return sys.platform == 'win32' or sys.platform == 'cygwin' + + +def is_mac(): + return sys.platform == 'darwin' + + +def parse_configs(): + config_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../config.yaml') + with open(config_file_path, 'r', encoding='utf-8') as config_file: + configs = yaml.safe_load(config_file) + return configs + + +def parse_file_name(download_url): + parsed_url = urlparse(download_url) + path = parsed_url.path + file_full_name = path.split("/")[-1] + file_name = file_full_name.split(".tar.gz")[0] + return file_name + + +def convert_to_datetime(date_str): + date_format = '%Y%m%d%H%M%S' + date_time = datetime.datetime.strptime(date_str, date_format) + return date_time + + +def get_download_url(task_name, image_date): + if image_date is None: + image_date = datetime.datetime.now().strftime('%Y%m%d%H%M%S') + else: + time_str = datetime.datetime.strptime(image_date, '%Y-%m-%d') + image_date = time_str.strftime('%Y%m%d') + '235959' + last_hour = (convert_to_datetime(image_date) + + datetime.timedelta(hours=-24)).strftime('%Y%m%d%H%M%S') + url = 'http://ci.openharmony.cn/api/daily_build/build/tasks' + downnload_job = { + 'pageNum': 1, + 'pageSize': 1000, + 'startTime': '', + 'endTime': '', + 'projectName': 'openharmony', + 'branch': 'master', + 'component': '', + 'deviceLevel': '', + 'hardwareBoard': '', + 'buildStatus': '', + 'buildFailReason': '', + 'testResult': '', + } + downnload_job['startTime'] = str(last_hour) + downnload_job['endTime'] = str(image_date) + post_result = requests.post(url, json=downnload_job) + post_data = json.loads(post_result.text) + download_url_suffix = '' + for ohos_sdk_list in post_data['data']['dailyBuildVos']: + try: + if get_remote_download_name(task_name) in ohos_sdk_list['obsPath']: + download_url_suffix = ohos_sdk_list['obsPath'] + break + except BaseException as err: + print(err) + if download_url_suffix == '': + return None + download_url = 'http://download.ci.openharmony.cn/' + download_url_suffix + return download_url + + +def retry_after_download_failed(download_url, temp_file, temp_file_name, max_retries=3): + for i in range(max_retries): + try: + download(download_url, temp_file, temp_file_name) + return True + except Exception as e: + print(f"download failed! retrying... ({i + 1}/{max_retries})") + time.sleep(2) + return False + + +def download_progress_bar(response, temp, temp_file_name): + total_length = int(response.headers.get("content-length")) + with tqdm.tqdm(total=total_length, unit="B", unit_scale=True) as pbar: + pbar.set_description(temp_file_name) + chunk_sum = 0 + count = 0 + for chunk in response.iter_bytes(): + temp.write(chunk) + chunk_sum += len(chunk) + percentage = chunk_sum / total_length * 100 + while str(percentage).startswith(str(count)): + count += 1 + pbar.update(len(chunk)) + + +def download(download_url, temp_file, temp_file_name): + with httpx.stream('GET', download_url) as response: + with open(temp_file, "wb") as temp: + download_progress_bar(response, temp, temp_file_name) + return True + + +def check_gzip_file(file_path): + try: + with gzip.open(file_path, 'rb') as gzfile: + gzfile.read(1) + except Exception as e: + print(e) + return False + return True + + +def check_zip_file(file_path): + try: + if zipfile.is_zipfile(file_path): + with zipfile.ZipFile(file_path, 'r') as zip_file: + pass + else: + return False + except Exception as e: + print(e) + return False + return True + + +def get_remote_download_name(task_name): + if is_windows(): + if 'sdk' in task_name: + return 'ohos-sdk-full.tar.gz' + return 'dayu200.tar.gz' + elif is_mac(): + if 'sdk' in task_name: + return 'L2-MAC-SDK-FULL.tar.gz' + else: + print('Unsuport platform to get sdk from daily build') + return '' + + +def get_api_version(json_path): + with open(json_path, 'r') as uni: + uni_cont = uni.read() + uni_data = json.loads(uni_cont) + api_version = uni_data['apiVersion'] + return api_version + + +def copy_to_output_path(file_name, file_path, output_path_list): + update_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'update.py') + cmd = ['python', update_file_path] + if 'sdk' in file_name.lower(): + sdk_temp_file = os.path.join(file_path, 'sdk_temp') + cmd.extend(['--sdkFilePath', sdk_temp_file]) + cmd.extend(['--sdkOutputPath']) + for output_path in output_path_list: + cmd.extend([output_path]) + + if 'dayu' in file_name: + dayu_temp_file = os.path.join(file_path, 'dayu200_xts') + cmd.extend(['--dayuFilePath', dayu_temp_file]) + cmd.extend(['--dayuOutputPath']) + for output_path in output_path_list: + cmd.extend([output_path]) + print(cmd) + subprocess.run(cmd, shell=False) + + +def get_the_unzip_file(download_url, save_path): + download_name = get_remote_download_name(download_url) + download_temp_file = os.path.join(save_path, download_name) + if not os.path.exists(save_path): + os.mkdir(save_path) + print(f'download {download_name} from {download_url}, please wait!!!') + success = retry_after_download_failed(download_url, download_temp_file, download_name) + if not success: + return False + if check_gzip_file(download_temp_file): + with tarfile.open(download_temp_file, 'r:gz') as tar: + print(f'Unpacking {download_temp_file}') + if 'dayu' in download_name: + save_path = os.path.join(save_path, 'dayu200_xts') + tar.extractall(save_path) + print(f'Decompression {download_temp_file} completed') + elif check_zip_file(download_temp_file): + with zipfile.ZipFile(download_temp_file, 'r') as zip_file: + print(f'Unpacking {download_temp_file}') + zip_file.extractall(save_path) + print(f'Decompression {download_temp_file} completed') + else: + print('The downloaded file is not a valid gzip or zip file.') + + if 'sdk' in download_name: + unpack_sdk_file(save_path) + + return True + + +def unpack_sdk_file(path): + sdk_zip_path_list = [path, 'ohos-sdk', 'windows'] + if is_mac(): + sdk_zip_path_list = [path, 'sdk', + 'packages', 'ohos-sdk', 'darwin'] + sdk_floder = os.path.join(path, 'sdk_temp') + sdk_zip_path = os.path.join(*sdk_zip_path_list) + for item in os.listdir(sdk_zip_path): + if item != '.DS_Store': + print(f'Unpacking {item}') + with zipfile.ZipFile(os.path.join(sdk_zip_path, item)) as zip_file: + zip_file.extractall(os.path.join(sdk_floder)) + print(f'Decompression {item} completed') + + +def get_task_config(file_name): + configs = parse_configs() + download_list = configs['download_list'] + for item in download_list: + if item['name'] in file_name: + url = item['url'] + date = item['date'] + output_path_list = item['output_path_list'] + return url, date, output_path_list + + +def delete_redundant_files(task_name, file_name, download_save_path, is_save): + if is_save: + date_time = re.search(r"\d{8}", file_name).group() + new_file_path = os.path.join(download_save_path, f'{date_time}-{task_name}') + if not os.path.exists(new_file_path): + temp_file_name = 'sdk_temp' if 'sdk' in task_name else 'dayu200_xts' + temp_file_path = os.path.join(download_save_path, temp_file_name) + os.rename(temp_file_path, new_file_path) + subdirs_and_files = [subdir_or_file for subdir_or_file in os.listdir(download_save_path)] + for subdir_or_file in subdirs_and_files: + if not subdir_or_file[0].isdigit(): + path = os.path.join(download_save_path, subdir_or_file) + if os.path.isdir(path): + shutil.rmtree(path) + elif os.path.isfile(path): + os.remove(path) + + +def write_download_url_to_txt(task_name, download_url): + download_url_txt = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'download_url.txt') + with open(download_url_txt, 'a+') as file: + file.write(f'{task_name}, {download_url}\n') + + +def get_the_image(task_name, download_url, image_date, output_path_list): + configs = parse_configs() + is_save = configs.get('is_save') + download_save_path = configs.get('download_save_path') + if download_url == '': + download_url = get_download_url(task_name, image_date) + file_name = parse_file_name(download_url) + if output_path_list is None: + output_path_list = get_task_config(file_name)[2] + print(f'output_path_list: {output_path_list}') + success = get_the_unzip_file(download_url, download_save_path) + if not success: + print(f'get {task_name} unzip file failed') + return False + + copy_to_output_path(file_name, download_save_path, output_path_list) + delete_redundant_files(task_name, file_name, download_save_path, is_save) + write_download_url_to_txt(task_name, download_url) + + return True + + +def clean_download_log(): + download_url_txt = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'download_url.txt') + if os.path.exists(download_url_txt): + os.remove(download_url_txt) + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--sdkUrl', type=str, dest='sdk_url', nargs='?', const='', default=None, + help='specify which sdk you want to download') + parser.add_argument('--dayuUrl', type=str, dest='dayu_url', nargs='?', const='', default=None, + help='specify which dayu200 you want to download') + parser.add_argument('--sdkDate', type=str, dest='sdk_date', default=None, + help='specify which day you want to download the sdk') + parser.add_argument('--dayuDate', type=str, dest='dayu_date', default=None, + help='specify which day you want to download the dayu') + parser.add_argument('--sdkPath', type=str, dest='sdk_path', default=None, + nargs='+', + help='specify where you want to store the sdk') + parser.add_argument('--dayuPath', type=str, dest='dayu_path', default=None, + nargs='+', + help='specify where you want to store the dayu200') + + return parser.parse_args() + + +def main(): + clean_download_log() + arguments = parse_args() + if arguments.sdk_url is not None: + get_the_image('sdk', arguments.sdk_url, arguments.sdk_date, arguments.sdk_path) + else: + sdk_config = get_task_config('sdk') + get_the_image('sdk', sdk_config[0], sdk_config[1], sdk_config[2]) + if arguments.dayu_url is not None: + get_the_image('dayu', arguments.dayu_url, arguments.dayu_date, arguments.dayu_path) + else: + dayu_config = get_task_config('sdk') + get_the_image('dayu', dayu_config[0], dayu_config[1], dayu_config[2]) + + +if __name__ == '__main__': + main() diff --git a/test/scripts/utils/download_sdk_and_image/update.py b/test/scripts/utils/download_sdk_and_image/update.py new file mode 100755 index 0000000000000000000000000000000000000000..a7180c22abad76e2720d9fed7859652880dbd29c --- /dev/null +++ b/test/scripts/utils/download_sdk_and_image/update.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python3 +# coding: utf-8 + +""" +Copyright (c) 2024 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 argparse +import asyncio +import json +import os +import shutil +import sys + +import yaml + + +def parse_configs(): + config_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../config.yaml') + with open(config_file_path, 'r', encoding='utf-8') as config_file: + configs = yaml.safe_load(config_file) + return configs + + +def get_output_path_list(file_name): + configs = parse_configs() + download_list = configs['download_list'] + for item in download_list: + if item['name'] in file_name: + output_path_list = item['output_path_list'] + return output_path_list + + +def is_mac(): + return sys.platform == 'darwin' + + +def get_api_version(json_path): + with open(json_path, 'r') as uni: + uni_cont = uni.read() + uni_data = json.loads(uni_cont) + api_version = uni_data['apiVersion'] + return api_version + + +def before_update_sdk(file_path): + pass + + +def after_update_sdk(file_path, output_path): + if is_mac(): + add_executable_permission_for_mac(output_path) + # modify sdk version while api version is different from your download + modify_package_json(file_path, output_path) + + +def add_executable_permission(file_path): + current_mode = os.stat(file_path).st_mode + new_mode = current_mode | 0o111 + os.chmod(file_path, new_mode) + + +def add_executable_permission_for_mac(sdk_path): + for item in os.listdir(sdk_path): + if item != '.DS_Store': + if item == 'toolchains': + add_executable_permission( + os.path.join(sdk_path, item, 'restool')) + add_executable_permission( + os.path.join(sdk_path, item, 'ark_disasm')) + elif item == 'ets': + add_executable_permission(os.path.join(sdk_path, item, 'build-tools', + 'ets-loader', 'bin', 'ark', 'build-mac', 'bin', 'es2abc')) + add_executable_permission(os.path.join(sdk_path, item, 'build-tools', + 'ets-loader', 'bin', 'ark', 'build-mac', 'legacy_api8', + 'bin', 'js2abc')) + elif item == 'js': + add_executable_permission(os.path.join(sdk_path, item, 'build-tools', + 'ace-loader', 'bin', 'ark', 'build-mac', 'bin', 'es2abc')) + add_executable_permission(os.path.join(sdk_path, item, 'build-tools', + 'ace-loader', 'bin', 'ark', 'build-mac', 'legacy_api8', + 'bin', 'js2abc')) + + +def get_output_path_api_version(output_path): + api_version = os.path.basename(output_path) + if api_version == 'base': + parts = output_path.split(os.sep) + if len(parts) >= 2: + filename = parts[-2] + configs = parse_configs() + download_list = configs.get('download_list') + sdk_item = next((item for item in download_list if item.get('name') == 'sdk'), None) + api_version_file_map = sdk_item.get('api_version_file_name_map') if sdk_item else {} + api_version = api_version_file_map.get(filename) + else: + api_version = None + + return api_version + + +def modify_package_json(file_path, output_path): + output_path_version = get_output_path_api_version(output_path) + if output_path_version is None: + print('Modify package json failed, Please check your configuration file' + ' to ensure the mapping between API and file names is correct.') + return + api_version = get_api_version(os.path.join( + *[file_path, 'ets', 'oh-uni-package.json'])) + if output_path_version != api_version: + for file_name in os.listdir(output_path): + if file_name == '.DS_Store': + continue + package_json_path = os.path.join(output_path, rf'{file_name}/oh-uni-package.json') + with open(package_json_path, 'r+') as json_file: + json_file.seek(0) + data = json.load(json_file) + data['apiVersion'] = get_output_path_api_version(output_path) + json_file.seek(0) + json.dump(data, json_file, indent=2) + json_file.truncate() + + +async def update_sdk_to_output_path(file_path, output_path): + before_update_sdk(file_path) + await copy_image_async(file_path, output_path) + after_update_sdk(file_path, output_path) + + +async def update_dayu_to_output_path(file_path, output_path): + await copy_image_async(file_path, output_path) + + +async def copy_image_async(file_path, output_path): + if os.path.exists(output_path): + loop = asyncio.get_event_loop() + await loop.run_in_executor(None, shutil.rmtree, output_path) + print(f'Copy from {file_path} to {output_path}, please wait!!!') + loop = asyncio.get_event_loop() + await loop.run_in_executor(None, shutil.copytree, file_path, output_path) + + +async def update_image_async(file_path, output_path, semaphore): + await semaphore.acquire() + try: + update_task_mapping = { + "sdk": update_sdk_to_output_path, + "dayu": update_dayu_to_output_path + } + for task in update_task_mapping: + if task in file_path: + await update_task_mapping[task](file_path, output_path) + await asyncio.sleep(1) + print(f'File copied to {output_path} successfully') + break + finally: + semaphore.release() + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--sdkFilePath', type=str, dest='sdk_file_path', default=None, + help='specify which sdk image you want to copy') + parser.add_argument('--sdkOutputPath', type=str, dest='sdk_output_path', default=None, + nargs='+', + help='specify where you want to store the file') + parser.add_argument('--dayuFilePath', type=str, dest='dayu_file_path', default=None, + help='specify which dayu image you want to copy') + parser.add_argument('--dayuOutputPath', type=str, dest='dayu_output_path', default=None, + nargs='+', + help='specify where you want to store the file') + + return parser.parse_args() + + +async def start_update_image_task(file_path, output_path_list, max_async_tasks=3): + if output_path_list is None: + output_path_list = get_output_path_list(file_path) + semaphore = asyncio.Semaphore(max_async_tasks) + tasks = [asyncio.create_task(update_image_async(file_path, output_path, semaphore)) + for output_path in output_path_list] + + await asyncio.gather(*tasks) + + +async def run(): + arguments = parse_args() + + if arguments.sdk_file_path is not None: + await start_update_image_task(arguments.sdk_file_path, arguments.sdk_output_path) + if arguments.dayu_file_path is not None: + await start_update_image_task(arguments.dayu_file_path, arguments.dayu_output_path) + if arguments.sdk_file_path is None and arguments.dayu_file_path is None: + print('please input which image you want to copy') + return + + +if __name__ == '__main__': + asyncio.run(run()) diff --git a/test/scripts/auto_xts_test/autoburn.py b/test/scripts/utils/flash_image/burn_image.py similarity index 32% rename from test/scripts/auto_xts_test/autoburn.py rename to test/scripts/utils/flash_image/burn_image.py index e4f682df31c31fc89b429b3b108170a219adae4e..bc4e57d44e1b349f9017e97162bacf447bd87d4e 100755 --- a/test/scripts/auto_xts_test/autoburn.py +++ b/test/scripts/utils/flash_image/burn_image.py @@ -1,57 +1,100 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Copyright (c) 2023 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 time - -from pywinauto.application import Application - - -def end_burn(dlg): - timeout = 300 - while True: - if timeout < 0: - return - mode = dlg.window(control_type="Tab").window_text() - if mode == 'Found One MASKROM Device': - dlg.Button16.click() - print("image burnning finished") - return - else: - print("please wait for a while...") - time.sleep(5) - timeout -= 5 - - -def auto_burn(): - app = Application(backend='uia').start('RKDevTool.exe') - dlg = app.top_window() - - while True: - mode = dlg.window(control_type="Tab").window_text() - if mode == 'Found One LOADER Device': - print('start burning') - dlg.window(title="Run").click() - time.sleep(100) - end_burn(dlg) - return - else: - time.sleep(1) - - -if __name__ == "__main__": - auto_burn() - \ No newline at end of file +#!/usr/bin/env python3 +# coding: utf-8 + +""" +Copyright (c) 2024 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 awriting, 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 stat +import subprocess +import time +import zipfile + +import requests +import yaml +from pywinauto import Application +from tqdm import tqdm + + +def job(cmd): + subprocess.run(cmd, shell=False) + + +def get_tool(): + config_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../config.yaml') + with open(config_file_path, 'r') as config_file: + data = yaml.safe_load(config_file.read()) + url = data['url_tools'] + print(f"Getting RKDevTool from {url}") + r = requests.get(url, stream=True) + total = int(r.headers.get('content-length'), 0) + flags = os.O_WRONLY | os.O_CREAT + modes = stat.S_IWUSR | stat.S_IRUSR + + with os.fdopen(os.open(r".\RKDevTool.zip", flags, modes), "wb") as f, tqdm( + desc="RKDevTool.zip", + total=total, + unit='iB', + unit_scale=True, + unit_divisor=1024, + ) as bar: + for byte in r.iter_content(chunk_size=1024): + size = f.write(byte) + bar.update(size) + with zipfile.ZipFile(".\\RKDevTool.zip", 'r') as zfile: + zfile.extractall(path=".\\RKDevTool") + + os.remove('./RKDevtool.zip') + + +def end_burn(dlg): + timeout = 300 + while True: + if timeout < 0: + return + mode = dlg.window(control_type="Tab").window_text() + if mode == 'Found One MASKROM Device': + dlg.Button16.click() + print("image burnning finished") + return + else: + print("please wait for a while...") + time.sleep(5) + timeout -= 5 + + +def auto_burn(): + rk_tool_exe_path = os.path.join(os.path.abspath(__file__), r'..\RKDevTool') + if not os.path.exists(rk_tool_exe_path): + get_tool() + os.chdir(rk_tool_exe_path) + job('hdc shell reboot bootloader') + app = Application(backend='uia').start('RKDevTool.exe') + dlg = app.top_window() + + while True: + mode = dlg.window(control_type="Tab").window_text() + if mode == 'Found One LOADER Device': + print('start burning') + dlg.window(title="Run").click() + time.sleep(100) + end_burn(dlg) + return + else: + time.sleep(1) + + +if __name__ == '__main__': + auto_burn() \ No newline at end of file diff --git a/test/scripts/utils/readme.md b/test/scripts/utils/readme.md new file mode 100755 index 0000000000000000000000000000000000000000..63f01c7680dee3c33276453cbb4e380021366681 --- /dev/null +++ b/test/scripts/utils/readme.md @@ -0,0 +1,17 @@ +# Instructions for using the utils package + +## Script Purpose +* Download the necessary image files for testing +* Obtain the burning tool and burn the downloaded Dayu image +* Retrieve the repository commit information from 00:00 on the day before the script run to the time the script is executed +* Automatically send test results via email + +## Dependency Installation +``` +python3 -m pip install pywinauto lxml requests +``` + +## Notes +* The storage path for the SDK needs to be strictly filled in according to the structure of the SDK path in the new version of IDEA +* If no content is provided for sdkUrl、dayuUrl, the script will automatically retrieve the image address from the official website +* Executing without providing parameters will follow the configured settings \ No newline at end of file diff --git a/test/scripts/utils/readme_zh.md b/test/scripts/utils/readme_zh.md new file mode 100755 index 0000000000000000000000000000000000000000..87b7557e79c47141c22d29b666dde211a88f1f52 --- /dev/null +++ b/test/scripts/utils/readme_zh.md @@ -0,0 +1,16 @@ +# utils包使用说明 +## 脚本目的 +* 下载测试所需要的镜像文件 +* 获取烧录工具并烧录下载好的dayu镜像 +* 获取前一天0点到脚本运行时这个时间段内仓库的提交信息 +* 邮件自动发送测试结果 + +## 依赖安装 +``` +python3 -m pip install pywinauto lxml requests +``` + +## 注意事项 +* sdk的存放路径需要按照新版idea中sdk路径的结构去严格填写 +* 镜像地址这个参数如果后面不输入内容就会自动去官网获取镜像地址 +* 不输入参数将按照配置去执行 diff --git a/test/scripts/send_email.py b/test/scripts/utils/send_email/send_email.py similarity index 92% rename from test/scripts/send_email.py rename to test/scripts/utils/send_email/send_email.py index 07f7030f065291aca271c3e2356f3264c14c48bd..55457a1cf603e0e6dd3eff4e327897439b356d02 100755 --- a/test/scripts/send_email.py +++ b/test/scripts/utils/send_email/send_email.py @@ -1,95 +1,98 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Copyright (c) 2023 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 smtplib - -from email.mime.image import MIMEImage -from email.mime.multipart import MIMEMultipart -from email.mime.text import MIMEText -import yaml - - -def add_content(content, file_name, test_part): - if file_name == "": - content += f'

{test_part} not complete yet

' - return content - if not os.path.exists(file_name): - content += f'

{test_part} run failed

' - return content - with open(file_name, 'r', encoding='utf-8') as f: - content += f.read() - return content - - -def add_attachment(msg, file_list): - for file in file_list: - if os.path.exists(file): - with open(file, 'rb') as f: - attachment = MIMEText(f.read(), 'base64', 'utf-8') - attachment['Content-Disposition'] = f'attachment; filename="{os.path.basename(file)}"' - msg.attach(attachment) - - -def add_image(msg, img_dic): - for path in img_dic: - if os.path.exists(path): - with open(path, 'rb') as f: - img = MIMEImage(f.read()) - img.add_header('Content-ID', img_dic[path]) - msg.attach(img) - - -def send_email(): - with open(r".\email_config.yaml", 'r') as f: - data = yaml.safe_load(f.read()) - - user_name = data["user_name"] - sender = data["sender_email_address"] - auth_code = data["auth_code"] - receiver = data["receiver_list"] - smtp_server = data["smtp_server"] - smtp_port = data["smtp_port"] - xts_test = data["xts_report_file"] - sdk_test = data["sdk_report_file"] - perf_test = data["perf_report_file"] - attachment_files = data["attatchment_files"] - image_files = data["image_files"] - - msg = MIMEMultipart() - msg['From'] = sender - msg['To'] = ", ".join(receiver) - msg['Subject'] = "Arkcompiler Test" - - html = "" - dividing_line = '
' - html = add_content(html, xts_test, "xts_test") - html += dividing_line - html = add_content(html, sdk_test, "sdk_test") - html += dividing_line - html = add_content(html, perf_test, "perf_test") - msg.attach(MIMEText(html, 'html', 'utf-8')) - add_attachment(msg, attachment_files) - add_image(msg, image_files) - smtp = smtplib.SMTP(smtp_server, smtp_port) - smtp.login(user_name, auth_code) - smtp.sendmail(sender, receiver, msg.as_string()) - smtp.quit() - - -if __name__ == "__main__": +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2023 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 smtplib + +from email.mime.image import MIMEImage +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText +import yaml + + +def add_content(content, file_name, test_part): + if file_name == "": + content += f'

{test_part} not complete yet

' + return content + if not os.path.exists(file_name): + content += f'

{test_part} run failed

' + return content + with open(file_name, 'r', encoding='utf-8') as f: + content += f.read() + return content + + +def add_attachment(msg, file_list): + for file in file_list: + if os.path.exists(file): + with open(file, 'rb') as f: + attachment = MIMEText(f.read(), 'base64', 'utf-8') + attachment['Content-Disposition'] = f'attachment; filename="{os.path.basename(file)}"' + msg.attach(attachment) + + +def add_image(msg, img_dic): + for path in img_dic: + if os.path.exists(path): + with open(path, 'rb') as f: + img = MIMEImage(f.read()) + img.add_header('Content-ID', img_dic[path]) + msg.attach(img) + + +def send_email(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + with open(r"../config.yaml", 'r') as f: + data = yaml.safe_load(f.read()) + + user_name = data["user_name"] + sender = data["sender_email_address"] + auth_code = data["auth_code"] + receiver = data["receiver_list"] + smtp_server = data["smtp_server"] + smtp_port = data["smtp_port"] + xts_test = data["xts_report_file"] + sdk_test = data["sdk_report_file"] + perf_test = data["perf_report_file"] + commit_log = data["commit_log_report_file"] + attachment_files = data["attatchment_files"] + image_files = data["image_files"] + + msg = MIMEMultipart() + msg['From'] = sender + msg['To'] = ", ".join(receiver) + msg['Subject'] = "Arkcompiler Test" + + html = "" + dividing_line = '
' + html = add_content(html, xts_test, "xts_test") + html += dividing_line + html = add_content(html, sdk_test, "sdk_test") + html += dividing_line + html = add_content(html, perf_test, "perf_test") + msg.attach(MIMEText(html, 'html', 'utf-8')) + html = add_content(html, commit_log, "commit_log") + msg.attach(MIMEText(html, 'html', 'utf-8')) + add_attachment(msg, attachment_files) + add_image(msg, image_files) + smtp = smtplib.SMTP(smtp_server, smtp_port) + smtp.login(user_name, auth_code) + smtp.sendmail(sender, receiver, msg.as_string()) + smtp.quit() + + +if __name__ == "__main__": send_email() \ No newline at end of file