diff --git a/test/scripts/auto_xts_test/autoburn.py b/test/scripts/auto_xts_test/autoburn.py deleted file mode 100755 index e4f682df31c31fc89b429b3b108170a219adae4e..0000000000000000000000000000000000000000 --- a/test/scripts/auto_xts_test/autoburn.py +++ /dev/null @@ -1,57 +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 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 diff --git a/test/scripts/auto_xts_test/get_resource/config.yaml b/test/scripts/auto_xts_test/config.yaml similarity index 30% rename from test/scripts/auto_xts_test/get_resource/config.yaml rename to test/scripts/auto_xts_test/config.yaml index 392a034452314cabfc3bd78b87720e5f69cf8bae..a015df39ead19b24f05dae0708d8bcc4981fc141 100644 --- a/test/scripts/auto_xts_test/get_resource/config.yaml +++ b/test/scripts/auto_xts_test/config.yaml @@ -1,60 +1,17 @@ -# 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' +# 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_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/readme.md b/test/scripts/auto_xts_test/readme.md index fed82512e0358fb5488cf253e704ed32faa54f07..7ffa59becaa67908bffd52565a7ec56dbe0b78d5 100644 --- a/test/scripts/auto_xts_test/readme.md +++ b/test/scripts/auto_xts_test/readme.md @@ -9,8 +9,6 @@ and run the xts testcase on the target to get the test result. This script will be running on windows, python3.7 or above needed. ### How to work Double click the run.bat or in the cmd condition input the path of run.bat -### Add xts testcases -To add xts testcases, you need to add module names to the running_modules.txt file. Module names should be splited by ';'. The module names are given in xts system, please refer to [this link]{https://gitee.com/openharmony/xts_acts#%E5%85%A8%E9%87%8F%E7%94%A8%E4%BE%8B%E6%89%A7%E8%A1%8C%E6%8C%87%E5%AF%BC%E9%80%82%E7%94%A8%E4%BA%8E%E5%B0%8F%E5%9E%8B%E7%B3%BB%E7%BB%9F%E6%A0%87%E5%87%86%E7%B3%BB%E7%BB%9F} ### Note - Only for the first time of running the script will download the burnning tool and need to install the driver for the tool by yourself. After the pragram run for a while(downloading the tool), there comes the User Account Control interface. diff --git a/test/scripts/auto_xts_test/readme_zh.md b/test/scripts/auto_xts_test/readme_zh.md index 401b774e1281bb224b706f7cc36c09340e006cd8..c7e286a35f08917b550b6e59432eedd68d615ab4 100644 --- a/test/scripts/auto_xts_test/readme_zh.md +++ b/test/scripts/auto_xts_test/readme_zh.md @@ -8,8 +8,6 @@ XTS测试自动化脚本会自动从每日构建dailybuilds上获取最新dayu20 XTS测试自动化脚本运行环境为windows,python3.7及以上 ### 脚本运行 点击run.bat运行或在cmd中输入run.bat所在路径 -### 添加xts用例 -在running_modules.txt文件中添加xts用例模块名,模块名之间用';'分割。xts用例模块参考[xts仓说明](https://gitee.com/openharmony/xts_acts#%E5%85%A8%E9%87%8F%E7%94%A8%E4%BE%8B%E6%89%A7%E8%A1%8C%E6%8C%87%E5%AF%BC%E9%80%82%E7%94%A8%E4%BA%8E%E5%B0%8F%E5%9E%8B%E7%B3%BB%E7%BB%9F%E6%A0%87%E5%87%86%E7%B3%BB%E7%BB%9F) ### 注意事项 - 初次使用会下载镜像烧录工具并需要手动安装驱动,在程序运行一小段时间(下载烧录工具)之后会跳出用户账户控制界面,点击“确认”后进入驱动安装界面,如下:
![](https://gitee.com/huyunhui1/images/raw/build/%E6%8D%95%E8%8E%B7.PNG) diff --git a/test/scripts/auto_xts_test/get_result.py b/test/scripts/auto_xts_test/result.py old mode 100755 new mode 100644 similarity index 90% rename from test/scripts/auto_xts_test/get_result.py rename to test/scripts/auto_xts_test/result.py index 4f3510ba241f38c706b5e9a60b1b77350f66e493..27b6d0ed646ba62c23fedfc776309ebd040e0e33 --- a/test/scripts/auto_xts_test/get_result.py +++ b/test/scripts/auto_xts_test/result.py @@ -1,40 +1,40 @@ -#!/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)): +#!/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__": + yl = open(r".\config.yaml", 'r') + data = yaml.safe_load(yl.read()) + path = data['path_xts_report'] + yl.close() + 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 diff --git a/test/scripts/auto_xts_test/run.bat b/test/scripts/auto_xts_test/run.bat index f372bb6b7858a27b502f85e1e6d1264770ac8013..e6520f9296148aad0951dc2e077a5727e812525b 100755 --- a/test/scripts/auto_xts_test/run.bat +++ b/test/scripts/auto_xts_test/run.bat @@ -20,34 +20,12 @@ 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) - 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 ) @@ -58,22 +36,7 @@ cd /d %~dp0 echo "Successfully excute script" >> log.log 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/auto_xts_test/running_modules.txt b/test/scripts/auto_xts_test/running_modules.txt index cd30d5e8cabdc811202c8af7eecb948e55a57679..e99bcdd5e39d1bb29dab460b6b5191fa8e9a2932 100644 --- a/test/scripts/auto_xts_test/running_modules.txt +++ b/test/scripts/auto_xts_test/running_modules.txt @@ -1 +1 @@ -modules=ActsAceEtsTest \ No newline at end of file +modules=ActsAceEtsTest;ActsEsmoduleEntryTest;ActsEsmoduleOhostestTest \ No newline at end of file diff --git a/test/scripts/download/__pycache__/download.cpython-310.pyc b/test/scripts/download/__pycache__/download.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a0eb9878d5c5abad71009afb3c81a7ccedba54c Binary files /dev/null and b/test/scripts/download/__pycache__/download.cpython-310.pyc differ diff --git a/test/scripts/download/__pycache__/preparation.cpython-310.pyc b/test/scripts/download/__pycache__/preparation.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d591d39eb2652252dbda534f90c4b666bf87770d Binary files /dev/null and b/test/scripts/download/__pycache__/preparation.cpython-310.pyc differ diff --git a/test/scripts/download/__pycache__/utils.cpython-310.pyc b/test/scripts/download/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07ca7f078fbe3a16c5c36709c2ca6d65a277051e Binary files /dev/null and b/test/scripts/download/__pycache__/utils.cpython-310.pyc differ diff --git a/test/scripts/download/config.yaml b/test/scripts/download/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..04c5f0a38b84110741143ae4f02803d8bcb8debd --- /dev/null +++ b/test/scripts/download/config.yaml @@ -0,0 +1,47 @@ +# 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. + +# test env config +deveco_path: D:\complier\DevEco Studio +deveco_sdk_path: D:\enviorment\SDK\openHarmony_SDK +node_js_path: D:\enviorment\nodejs-huawei # The nodejs which is used in Deveco +pictures_download_path: 'http://123.60.114.105:9999/pictures_reference.zip' +pictures_output_path: './sdk_test/pictures_reference' + +RKdevtool_download_path : 'http://123.60.114.105:9999/RKDevTool.zip' +RKdevtool_output_path: './auto_xts_test/RKDevTool' + +#download list +download_save_path: D:\save_path +output_path_list: + - sdk: + name: sdk + output_path: + - D:\output_path\openHarmony_SDK + - D:\output_path2\openHarmony_SDK + - dayu200: + name: dayu200 + output_path: + - D:\output_path\dayu200_xts + +# image list +download_list: + - sdk: + name: sdk + path: D:\enviorment\SDK\openHarmony_SDK # The directory where the compressed files are stored + output_path: D:\enviorment\SDK\openHarmony_SDK\temp # File replacement path + - dayu200: + name: dayu200 + path: D:\AutoXTSTest + output_path: D:\AutoXTSTest\dayu200_xts + diff --git a/test/scripts/download/download.py b/test/scripts/download/download.py new file mode 100644 index 0000000000000000000000000000000000000000..d89e09c0623a720bec67c2f8cadefad88ec94dec --- /dev/null +++ b/test/scripts/download/download.py @@ -0,0 +1,227 @@ +import argparse +import os +import shutil +import subprocess +import tarfile +import zipfile + +import utils +from preparation import prepare_test_dev + + +configs = {} +arguments = {} + + +class downloadTask: + def __init__(self): + self.name = '' + self.path = '' + self.output_path = '' + + +def create_download_task(): + task_list = [] + download_list = configs.get('download_list') + for download_task in download_list: + task = downloadTask() + task.name = download_task['name'] + task.path = download_task['path'] + task.output_path = download_task['output_path'] + task_list.append(task) + + return task_list + + +def get_download_image_simple(download_url): + download_name = utils.parse_file_name(download_url) + download_save_path = configs.get('download_save_path') + task_name = 'dayu200' + if 'sdk' in download_name: + task_name = 'sdk' + download_zip_file(task_name, download_url, download_save_path, download_name) + + file_path = download_save_path + '_temp' + zip_file_path = os.path.join(file_path, download_name) + # todo + utils.before_update_sdk() + + output_path_list = [] + if arguments.output_path is not None: + output_path_list = arguments.output_path + else: + for item in configs['output_path_list']: + if item.get('name') == task_name: + output_path_list = item.get('output_path', []) + break + + for output_path in output_path_list: + if task_name == 'sdk': + sdk_temp_file = os.path.join(file_path, 'SDK_TEMP') + update_sdk_to_output_path(sdk_temp_file, output_path) + # todo + utils.after_update_sdk(output_path) + else: + if os.path.exists(output_path): + shutil.rmtree(output_path) + if os.path.exists(zip_file_path): + os.remove(zip_file_path) + if os.path.exists(file_path): + shutil.copytree(file_path, output_path) + shutil.rmtree(file_path) + + +def update_sdk_to_output_path(file_path, output_path): + api_version = utils.get_api_version(os.path.join( + *[file_path, 'ets', 'oh-uni-package.json'])) + output_path = os.path.join(output_path, api_version) + if os.path.exists(output_path): + shutil.rmtree(output_path) + shutil.copytree(file_path, output_path) + + +def download_zip_file(task_name, download_url, path, download_name=''): + temp_floder = path + '_temp' + if download_name == '': + download_name = utils.get_remote_download_name(task_name) + download_temp_file = os.path.join(temp_floder, download_name) + if os.path.exists(temp_floder): + shutil.rmtree(temp_floder) + os.mkdir(temp_floder) + print(f'download {task_name} from {download_url}, please wait!!!') + success = utils.download(download_url, download_temp_file, download_name) + if not success: + return False + if not utils.check_gzip_file(download_temp_file): + print('The downloaded file is not a valid gzip file.') + return False + + with tarfile.open(download_temp_file, 'r:gz') as tar: + print(f'Unpacking {download_temp_file}') + tar.extractall(temp_floder) + print(f'Decompression {download_temp_file} completed') + + if task_name == 'sdk': + sdk_zip_path_list = [temp_floder, 'ohos-sdk', 'windows'] + if utils.is_mac(): + sdk_zip_path_list = [temp_floder, 'sdk', + 'packages', 'ohos-sdk', 'darwin'] + 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': + 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') + return True + + +def update_to_output_path(task_name, path, output_path, temp_floder=''): + if task_name == 'sdk': + if temp_floder == '': + deveco_sdk_path = configs.get('deveco_sdk_path') + temp_floder = deveco_sdk_path + '_temp' + sdk_floder = os.path.join(temp_floder, 'SDK_TEMP') + api_version = utils.get_api_version(os.path.join( + *[sdk_floder, 'ets', 'oh-uni-package.json'])) + + update_sdk_to_deveco(sdk_floder, api_version) + + else: + if os.path.exists(output_path): + shutil.rmtree(output_path) + + if os.path.exists(path): + shutil.move(path, output_path) + + +def update_sdk_to_deveco(sdk_path, api_version, deveco_sdk_path=''): + if deveco_sdk_path == '': + deveco_sdk_path = 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 + '-' + utils.get_time_string()) + for item in os.listdir(sdk_path): + if item != '.DS_Store': + if utils.is_mac(): + if item == 'toolchains': + utils.add_executable_permission( + os.path.join(sdk_path, item, 'restool')) + utils.add_executable_permission( + os.path.join(sdk_path, item, 'ark_disasm')) + elif item == 'ets': + utils.add_executable_permission(os.path.join(sdk_path, item, 'build-tools', + 'ets-loader', 'bin', 'ark', 'build-mac', 'bin', 'es2abc')) + utils.add_executable_permission(os.path.join(sdk_path, item, 'build-tools', + 'ets-loader', 'bin', 'ark', 'build-mac', 'legacy_api8', + 'bin', 'js2abc')) + elif item == 'js': + utils.add_executable_permission(os.path.join(sdk_path, item, 'build-tools', + 'ace-loader', 'bin', 'ark', 'build-mac', 'bin', 'es2abc')) + utils.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)) + # todo + utils.after_update_sdk_to_deveco() + + +def burn_system_image(): + RKDevTool_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../auto_xts_test/RKDevTool') + os.chdir(RKDevTool_path) + cmd = 'hdc shell reboot bootloader' + subprocess.run(cmd, shell=False) + utils.auto_burn() + print('burn_system_image_success') + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--downloadUrl', type=str, dest='download_url', default=None, + help='specify what you want to download') + parser.add_argument('--outputPath', type=str, dest='output_path', default=None, + nargs='+', + help='specify where you want to store the file') + return parser.parse_args() + + +def get_the_latest_image(): + 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) + download_task_list = create_download_task() + with open(download_url_txt, 'a') as file: + for task in download_task_list: + download_url = utils.get_download_url(task.name) + success = download_zip_file(task.name, download_url, task.path) + if not success: + return + temp_file = task.path + '_temp' + update_to_output_path(task.name, temp_file, task.output_path) + file.write(f'{task.name}, {download_url}\n') + file.write('all tasks download successfully!!!') + burn_system_image() + print('complete all tasks successfully') + + +def main(): + if not prepare_test_dev(): + return + + if arguments.download_url is not None: + get_download_image_simple(arguments.download_url) + else: + get_the_latest_image() + + +if __name__ == '__main__': + configs = utils.parse_configs() + arguments = parse_args() + main() diff --git a/test/scripts/download/preparation.py b/test/scripts/download/preparation.py new file mode 100644 index 0000000000000000000000000000000000000000..5003652a45d8d4b3808c1a624251c590df1d56f4 --- /dev/null +++ b/test/scripts/download/preparation.py @@ -0,0 +1,73 @@ +import os +import shutil + +from utils import get_tool, is_linux +from utils import parse_configs + +configs = {} +arguments = {} + + +def clean_log(): + download_url_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'result') + if os.path.exists(download_url_path): + shutil.rmtree(download_url_path) + + +def check_deveco_dev(): + if is_linux(): + return False + + java_path = os.path.join(configs.get('deveco_path'), 'jbr') + if not os.path.exists(java_path): + print("Java not found!") + return False + + if not os.path.exists(configs.get('node_js_path')): + print("Node js not found!") + return False + + return True + + +def check_rkDevTool(): + rKDevTool_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../auto_xts_test/RKDevTool') + if not os.path.exists(rKDevTool_path): + url = configs.get('RKdevtool_download_path') + output_path = configs.get('RKdevtool_output_path') + get_tool('RKDevTool.zip', url, output_path) + + rKDevTool_exe_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), + '../auto_xts_test/RKDevTool/RKDevTool.exe') + if not rKDevTool_exe_path: + return False + + return True + + +def check_pictures_reference(): + pictures_reference_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), + '../sdk_test/pictures_reference') + if not os.path.exists(pictures_reference_path): + url = configs.get('pictures_download_path') + output_path = configs.get('pictures_output_path') + get_tool('pictures_references.zip', url, output_path) + if not os.path.exists(pictures_reference_path): + return False + + return True + + +def prepare_test_dev(): + global configs + configs = parse_configs() + clean_log() + sdk_prepared = check_deveco_dev() and check_pictures_reference + xts_prepared = check_rkDevTool() + prepared = sdk_prepared and xts_prepared + return prepared + + +if __name__ == '__main__': + prepare_test_dev() + diff --git a/test/scripts/download/utils.py b/test/scripts/download/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..bb7f408cd2da2faf6fb10361ee428d7bbf1eaead --- /dev/null +++ b/test/scripts/download/utils.py @@ -0,0 +1,213 @@ +import gzip +import os +import sys +import datetime +import zipfile +from urllib.parse import urlparse, unquote +import time +import json +import stat + +import httpx +import requests +import tqdm +import yaml +from pywinauto.application import Application + + +def is_windows(): + return sys.platform == 'win32' or sys.platform == 'cygwin' + + +def is_mac(): + return sys.platform == 'darwin' + + +def is_linux(): + return sys.platform == 'linux' + + +def get_time_string(): + return time.strftime('%Y%m%d-%H%M%S') + + +def get_encoding(): + if is_windows(): + return 'utf-8' + else: + return sys.getfilesystemencoding() + + +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_tool(tar_name, url, output_path): + print(f"Getting {tar_name} 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(f"{output_path}.zip", flags, modes), "wb") as f, tqdm( + desc=f"{tar_name}", + 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(f"{output_path}.zip", 'r') as zfile: + zfile.extractall(path=f"{output_path}") + + +def get_download_url(task_name): + now_time = datetime.datetime.now().strftime('%Y%m%d%H%M%S') + last_hour = (datetime.datetime.now() + + 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(now_time) + post_result = requests.post(url, json=downnload_job) + post_data = json.loads(post_result.text) + sdk_url_suffix = '' + for ohos_sdk_list in post_data['data']['dailyBuildVos']: + try: + if get_remote_download_name(task_name) in ohos_sdk_list['obsPath']: + sdk_url_suffix = ohos_sdk_list['obsPath'] + break + except BaseException as err: + print(err) + download_url = 'http://download.ci.openharmony.cn/' + sdk_url_suffix + return download_url + + +def download(download_url, temp_file, temp_file_name, max_retries=3): + for i in range(max_retries): + try: + with httpx.stream('GET', download_url) as response: + with open(temp_file, "wb") as temp: + 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)) + return True + except Exception as e: + print(f"download failed! retrying... ({i + 1}/{max_retries})") + time.sleep(2) + return False + + +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) + + +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 get_remote_download_name(task_name): + if is_windows(): + if task_name == 'sdk': + return 'ohos-sdk-full.tar.gz' + if task_name == 'dayu200': + return 'dayu200.tar.gz' + elif is_mac(): + if task_name == 'sdk': + 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 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 parse_file_name(url): + parsed_url = urlparse(url) + path = unquote(parsed_url.path) + file_name = os.path.basename(path) + return file_name + + +def before_update_sdk(): + pass + + +def after_update_sdk(output_path): + pass + + +def after_update_sdk_to_deveco(): + pass \ No newline at end of file diff --git a/test/scripts/get_commit_log/__pycache__/result.cpython-310.pyc b/test/scripts/get_commit_log/__pycache__/result.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9664493649236f7a45ae66061780ede8179a6698 Binary files /dev/null and b/test/scripts/get_commit_log/__pycache__/result.cpython-310.pyc differ diff --git a/test/scripts/get_commit_log/config.yaml b/test/scripts/get_commit_log/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0ce2c53db3a9fa7fc7207087a32b7c4e75dec00e --- /dev/null +++ b/test/scripts/get_commit_log/config.yaml @@ -0,0 +1,20 @@ +# 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. + +crawl_max_page: 3 +# repo list +repo_list: + - 'arkcompiler_ets_frontend' + - 'developtools_ace_ets2bundle' + - 'third_party_typescript' + - 'arkcompiler_runtime_core' \ No newline at end of file diff --git a/test/scripts/get_commit_log/get_commit_log.py b/test/scripts/get_commit_log/get_commit_log.py new file mode 100644 index 0000000000000000000000000000000000000000..ff27bcb6b7f3bb6c23282be6133621d8b7cf05b7 --- /dev/null +++ b/test/scripts/get_commit_log/get_commit_log.py @@ -0,0 +1,133 @@ +import argparse +import os + +import yaml +import requests +from lxml import etree +from datetime import datetime, timedelta, time + +from result import get_result + + +configs = {} + + +def parse_config(): + 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: + global configs + configs = yaml.safe_load(config_file) + + +def get_url(name, page): + url_prefix = 'https://gitee.com/openharmony/' + url_suffix = f'/pulls?assignee_id=&author_id=&label_ids=&label_text=&milestone_id=&page={page}&priority=&project_type=&scope=&search=&single_label_id=&single_label_text=&sort=closed_at+desc&status=merged&target_project=&tester_id=' + url = url_prefix + name + url_suffix + + return url + + +def get_html(url): + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3' + } + try: + # response = requests.get(url, headers=headers, verify=False) + response = requests.get(url, headers=headers) + if response.status_code == 200: + return response.text + except Exception as e: + print(e) + return None + + +def get_three_newest_data(repo_name): + url = get_url(repo_name, 1) + html = get_html(url) + tree = etree.HTML(html) + commit_list = tree.xpath('/html/body/div[2]/div[2]/div[2]/div[2]/div') + + newest_commits = commit_list[:3] + for commit_task in newest_commits: + title = commit_task.xpath('.//div[1]/a/text()')[0] + committer = commit_task.xpath('.//div[3]/span[2]/a/span/text()')[0] + commit_time_str = commit_task.xpath('.//div[3]/span[4]/span/text()')[0].strip() + pr_link = commit_task.xpath('.//div[1]/a/@href')[0] + data_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data.txt') + with open(data_file, 'a', encoding='utf-8') as file: + file.write(f"{repo_name}, {title}, {committer}, {commit_time_str}, {pr_link}\n") + + +def crawl_committer(repo_list, start_time, end_time, max_retries=3): + crawl_max_page = configs.get('crawl_max_page') + data_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data.txt') + if os.path.exists(data_file): + os.remove(data_file) + for i in range(max_retries): + try: + data_count = 0 + for repo_name in repo_list: + has_commit_log = False + for j in range(1, crawl_max_page + 1): + url = get_url(repo_name, str(j)) + html = get_html(url) + tree = etree.HTML(html) + commit_list = tree.xpath('/html/body/div[2]/div[2]/div[2]/div[2]/div') + for commit_task in commit_list: + title = commit_task.xpath('.//div[1]/a/text()')[0] + committer = commit_task.xpath('.//div[3]/span[2]/a/span/text()')[0] + commit_time_str = commit_task.xpath('.//div[3]/span[4]/span/text()')[0].strip() + pr_link = commit_task.xpath('.//div[1]/a/@href')[0] + time = datetime.strptime(commit_time_str, '%Y-%m-%d %H:%M') + if start_time <= time <= end_time: + has_commit_log = True + data_count = data_count + 1 + with open(data_file, 'a', encoding='utf-8') as file: + file.write(f"{repo_name}, {title}, {committer}, {commit_time_str}, {pr_link}\n") + if not has_commit_log: + print(f"repo {repo_name} no commit records were found within the specified time range," + " retrieving the latest 3 records instead") + get_three_newest_data(repo_name) + data_count = data_count + 3 + print(f'The data was successfully obtained, a total of {data_count} commit records were retrieved') + print(f'Data statistics from {start_time} to {end_time} were successfully retrieved') + return True + except Exception as e: + print(f"get data failed! retrying... ({i + 1}/{max_retries})") + time.sleep(2) + return False + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--startTime', type=str, dest='start_time', default=None, + help='specify crawl start time') + parser.add_argument('--repoName', type=str, dest='repo_name', default=None, + nargs='+', + help='specify which repo you want to crawl') + return parser.parse_args() + + +if __name__ == '__main__': + parse_config() + end_time = datetime.now() + yesterday = end_time - timedelta(days=1) + start_time = datetime(yesterday.year, yesterday.month, yesterday.day, 0, 0, 0) + repo_list = configs.get('repo_list') + + arguments = parse_args() + if arguments.start_time is not None: + time_str = datetime.strptime(arguments.start_time, '%Y-%m-%d') + start_time = datetime.combine(time_str, time.min) + end_time = start_time + timedelta(days=1) + if arguments.repo_name is not None: + repo_list = arguments.repo_name + + success = crawl_committer(repo_list, start_time, end_time) + if not success: + print("Maximum retries reached, failed to crawl the data") + else: + get_result() + + + diff --git a/test/scripts/get_commit_log/result.py b/test/scripts/get_commit_log/result.py new file mode 100644 index 0000000000000000000000000000000000000000..68d8b742952463558203843559fbe6c9036979ad --- /dev/null +++ b/test/scripts/get_commit_log/result.py @@ -0,0 +1,40 @@ +import os + +from jinja2 import Environment, FileSystemLoader + + +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: + line = line.strip() + values = line.split(',') + + project = values[0] + item = { + 'description': values[1], + 'author': values[2], + 'time': values[3], + 'link': f'https://gitee.com/{values[4]}'.replace(' ', '') + } + + if project in data: + data[project].append(item) + else: + data[project] = [item] + + template_dir = os.path.dirname(__file__) + env = Environment(loader=FileSystemLoader(template_dir)) + template = env.get_template('template.html') + output = template.render(data=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(output) + + +if __name__ == '__main__': + get_result() diff --git a/test/scripts/get_commit_log/template.html b/test/scripts/get_commit_log/template.html new file mode 100644 index 0000000000000000000000000000000000000000..d029eb750e11ae572d8add47c3695d867cfd5004 --- /dev/null +++ b/test/scripts/get_commit_log/template.html @@ -0,0 +1,102 @@ + + + + + 提交记录 + + + +
+
+ + + + + + + + + + + + + {% for project, items in data.items() %} + {% for item in items %} + + {% if loop.index == 1 %} + + {% endif %} + + + + + + {% endfor %} + {% endfor %} + +
提交记录
仓库描述作者时间链接
{{ project }}{{ item.description }}{{ item.author }}{{ item.time }}点击查看
+
+
+ + diff --git a/test/scripts/readme.md b/test/scripts/readme.md index 4a8b71a3769700df8cb001c94fab946d87baa583..216394ff195b74663c67592d72ffdf82c2279668 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 timer.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..607469652e2acccad6fe6dbcaee4184778a6898f 100644 --- a/test/scripts/readme_zh.md +++ b/test/scripts/readme_zh.md @@ -5,11 +5,12 @@ 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 diff --git a/test/scripts/sdk_test/__pycache__/execution.cpython-310.pyc b/test/scripts/sdk_test/__pycache__/execution.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82bd4a84156b39e4994f6cb06dfacc889125306b Binary files /dev/null and b/test/scripts/sdk_test/__pycache__/execution.cpython-310.pyc differ diff --git a/test/scripts/sdk_test/__pycache__/options.cpython-310.pyc b/test/scripts/sdk_test/__pycache__/options.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bdd042193a2a23863076216a062deff9d7adf393 Binary files /dev/null and b/test/scripts/sdk_test/__pycache__/options.cpython-310.pyc differ diff --git a/test/scripts/sdk_test/__pycache__/preparation.cpython-310.pyc b/test/scripts/sdk_test/__pycache__/preparation.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a09a069173556504806501c9bc638d1c54255ea Binary files /dev/null and b/test/scripts/sdk_test/__pycache__/preparation.cpython-310.pyc differ diff --git a/test/scripts/sdk_test/__pycache__/result.cpython-310.pyc b/test/scripts/sdk_test/__pycache__/result.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6c5e4c0dccfcaa60d59803428b02987fba1b6d4 Binary files /dev/null and b/test/scripts/sdk_test/__pycache__/result.cpython-310.pyc differ diff --git a/test/scripts/sdk_test/__pycache__/utils.cpython-310.pyc b/test/scripts/sdk_test/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..750b8caa258bb6caab16c6b3664247e4433eb897 Binary files /dev/null and b/test/scripts/sdk_test/__pycache__/utils.cpython-310.pyc differ diff --git a/test/scripts/sdk_test/config.yaml b/test/scripts/sdk_test/config.yaml index ffd306bf0439f30ca75ddd1af3c3ebf2345de3e2..7e2adcd87950670e2115452df90afbb1ea917e13 100644 --- a/test/scripts/sdk_test/config.yaml +++ b/test/scripts/sdk_test/config.yaml @@ -12,11 +12,12 @@ # limitations under the License. # Description: configs for test suite +output_hap_path: [ entry, build, default, outputs, default, entry-default-signed.hap ] # environment settings -deveco_path: D:\Software\Deveco-0602\DevEco Studio -deveco_sdk_path: D:\deveco-sdk\deveco-sdk-0602 -node_js_path: D:\Software\nodejs # The nodejs which is used in Deveco +deveco_path: D:\complier\DevEco Studio +deveco_sdk_path: D:\enviorment\SDK\openHarmony_SDK +node_js_path: D:\enviorment\nodejs-huawei # The nodejs which is used in Deveco # output settings output_html_file: ./sdk_test_report.html @@ -43,7 +44,7 @@ haps: - calendar: name: Calendar path: D:\haps\calendar - type: [stage] + type: [ stage ] build_path: cache_path: output_hap_path: @@ -54,21 +55,24 @@ haps: - widgetdemo: name: WidgetDemo path: D:\haps\WidgetDemo - type: [stage, widget] + type: [ stage, widget ] build_path: cache_path: output_hap_path: output_app_path: inc_modify_file: description: - # IDE demo haps +# IDE demo haps - idedemo_00: name: IdeStageDemoEmptyAbility path: D:\sdk-test\DemoApplication_EmptyAbility type: [stage, ohosTest, exceed_length_error, error] - build_path: [entry, build, default] + 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 +81,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,8 +94,11 @@ 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: @@ -97,7 +107,10 @@ haps: 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] @@ -119,4 +132,4 @@ patch_content: tail: "\n console.log('This is a new line');\n" patch_lines_error: tail: "\n let a_duplicated_value_for_test_suite = 1; function a_duplicated_value_for_test_suite() {};" - expected_error: [Duplicate identifier 'a_duplicated_value_for_test_suite', Identifier 'a_duplicated_value_for_test_suite' has already been declared] \ No newline at end of file + expected_error: [ Duplicate identifier 'a_duplicated_value_for_test_suite', Identifier 'a_duplicated_value_for_test_suite' has already been declared ] \ No newline at end of file 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..64295d6d4583d42ab62d79d9edb5887ff238de84 100644 --- a/test/scripts/sdk_test/execution.py +++ b/test/scripts/sdk_test/execution.py @@ -24,13 +24,14 @@ import re import shutil import signal import subprocess +import time import zipfile - import json5 - import options import utils +from utils import get_running_screenshot, verify_runtime, out_file_backup + class IncrementalTest: @staticmethod @@ -47,8 +48,11 @@ class IncrementalTest: logging.debug(f"new module hap file: {new_module_name_output_file}") + picture_suffix = 'debug' + if not is_debug: + picture_suffix = 'release' passed = validate(inc_task, task, is_debug, stdout, - stderr, new_module_name_output_file) + stderr, f'incremental_compile_change_module_name_{picture_suffix}', new_module_name_output_file) logging.debug(f"validate new module hap file, passed {passed}") if not passed: return @@ -65,6 +69,7 @@ class IncrementalTest: modules_abc_path = os.path.join(abc_path, 'modules.abc') modules_pa = disasm_abc(task, modules_abc_path) if not modules_pa or not os.path.exists(modules_pa): + out_file_backup(task, 'changeModuleName') inc_info.result = options.TaskResult.failed inc_info.error_message = f'ark_disasm failed, module name change not verified' return @@ -172,10 +177,17 @@ 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) + picture_suffix = 'debug' + if not is_debug: + picture_suffix = 'release' + passed = validate(inc_task, task, is_debug, stdout, stderr, f'incremental_compile_no_change_{picture_suffix}') if passed: IncrementalTest.validate_compile_incremental_file( task, inc_task, is_debug, []) + # if is_debug: + # get_running_screenshot(task, 'incremental_compile_no_change_debug') + # else: + # get_running_screenshot(task, 'incremental_compile_no_change_release') @staticmethod def compile_incremental_add_oneline(task, is_debug): @@ -193,11 +205,18 @@ class IncrementalTest: 'patch_lines_2').get('tail')) [stdout, stderr] = compile_project(task, is_debug) - passed = validate(inc_task, task, is_debug, stdout, stderr) + picture_suffix = 'debug' + if not is_debug: + picture_suffix = 'release' + passed = validate(inc_task, task, is_debug, stdout, stderr, f'incremental_compile_add_oneline_{picture_suffix}') if passed: modified_files = [os.path.join(*modify_file_item)] IncrementalTest.validate_compile_incremental_file( task, inc_task, is_debug, modified_files) + # if is_debug: + # get_running_screenshot(task, 'incremental_compile_add_oneline_debug') + # else: + # get_running_screenshot(task, 'incremental_compile_add_oneline_release') shutil.move(modify_file_backup, modify_file) @@ -238,11 +257,18 @@ class IncrementalTest: file.write(patch_lines.get('tail')) [stdout, stderr] = compile_project(task, is_debug) - passed = validate(inc_task, task, is_debug, stdout, stderr) + picture_suffix = 'debug' + if not is_debug: + picture_suffix = 'release' + passed = validate(inc_task, task, is_debug, stdout, stderr, f'incremental_compile_add_file_{picture_suffix}') if passed: modified_files = [os.path.join(*modify_file_item)] IncrementalTest.validate_compile_incremental_file( task, inc_task, is_debug, modified_files) + # if is_debug: + # get_running_screenshot(task, 'incremental_compile_add_file_debug') + # else: + # get_running_screenshot(task, 'incremental_compile_add_file_release') shutil.move(modify_file_backup, modify_file) os.remove(new_file) @@ -256,12 +282,20 @@ 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) + picture_suffix = 'debug' + if not is_debug: + picture_suffix = 'release' + passed = validate(inc_task, task, is_debug, stdout, stderr, f'incremental_compile_delete_file_{picture_suffix}') if passed: modify_file_item = task.inc_modify_file modified_files = [os.path.join(*modify_file_item)] IncrementalTest.validate_compile_incremental_file( task, inc_task, is_debug, modified_files) + # if is_debug: + # get_running_screenshot(task, 'incremental_compile_delete_file_debug') + # else: + # get_running_screenshot(task, 'incremental_compile_delete_file_release') + @staticmethod def compile_incremental_reverse_hap_mode(task, is_debug): @@ -271,7 +305,16 @@ 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) + picture_suffix = 'debug' + if not is_debug: + picture_suffix = 'release' + validate(inc_task, task, hap_mode, stdout, stderr, f'incremental_compile_reverse_hap_mode_{picture_suffix}') + # passed = validate(inc_task, task, hap_mode, stdout, stderr) + # if passed: + # if is_debug: + # get_running_screenshot(task, 'incremental_compile_reverse_hap_mode_debug') + # else: + # get_running_screenshot(task, 'incremental_compile_reverse_hap_mode_release') @staticmethod def compile_incremental_modify_module_name(task, is_debug): @@ -310,8 +353,15 @@ class IncrementalTest: try: [stdout, stderr] = compile_project(task, is_debug) - IncrementalTest.validate_module_name_change( + # IncrementalTest.validate_module_name_change( + # task, inc_task, is_debug, stdout, stderr, new_module_name) + passed = IncrementalTest.validate_module_name_change( task, inc_task, is_debug, stdout, stderr, new_module_name) + # if passed: + # if is_debug: + # get_running_screenshot(task, 'incremental_compile_modify_module_name_debug') + # else: + # get_running_screenshot(task, 'incremental_compile_modify_module_name_release') except Exception as e: logging.exception(e) finally: @@ -383,6 +433,7 @@ class OtherTest: if debug_consistency and release_consistency: test_info.result = options.TaskResult.passed + # get_running_screenshot(task, 'other_tests_binary_consistency') else: test_info.result = options.TaskResult.failed @@ -426,6 +477,7 @@ class OtherTest: passed = validate_compile_output(test_info, task, is_debug) if passed: test_info.result = options.TaskResult.passed + # get_running_screenshot(task, 'other_tests_break_continue_compile_debug') @staticmethod def compile_full_with_error(task, is_debug): @@ -520,6 +572,7 @@ class OtherTest: '-p', 'module=entry@ohosTest', 'assembleHap'] [stdout, stderr] = compile_project(task, True, cmd) [is_success, time_string] = is_compile_success(stdout) + if not is_success: test_info.result = options.TaskResult.failed test_info.error_message = stderr @@ -549,6 +602,7 @@ class OtherTest: test_info, task, True, ohos_test_output_file) if passed: test_info.result = options.TaskResult.passed + # get_running_screenshot(task, 'other_tests_ohos_test_debug') def disasm_abc(task, abc_file): @@ -575,6 +629,7 @@ def disasm_abc(task, abc_file): def is_abc_debug_info_correct(task, abc_file, is_debug): pa_file = disasm_abc(task, abc_file) if not os.path.exists(pa_file): + out_file_backup(task, 'checkEsModuleOutPuts') logging.error(f"pa file not exist: {pa_file}") return False @@ -751,11 +806,14 @@ def validate_compile_output(info, task, is_debug, output_file=''): return passed -def run_compile_output(info, task_path): +# def run_compile_output(task, info, task_path): +def run_compile_output(task, picture_name): # TODO: - # 1)install hap - # 2)run hap and verify - return False + # 1)install hap && run hap + get_running_screenshot(task, picture_name) + time.sleep(2) + # 2) verify + return verify_runtime(task, picture_name) def is_compile_success(compile_stdout): @@ -763,11 +821,10 @@ def is_compile_success(compile_stdout): match_result = re.search(pattern, compile_stdout) if not match_result: return [False, ''] - 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 +841,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) + passed &= run_compile_output(task, picture_name) if passed: collect_compile_time(info, time_string) @@ -851,8 +908,11 @@ def compile_incremental(task, is_debug): return if options.arguments.compile_mode == 'incremental': + picture_suffix = 'debug' + if not is_debug: + picture_suffix = 'release' passed = validate(task.full_compilation_info, - task, is_debug, stdout, stderr) + task, is_debug, stdout, stderr, f'incremental_compile_first{picture_suffix}') if not passed: logging.error( "Incremental compile failed due to first compile failed!") @@ -939,15 +999,17 @@ 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_release') if passed: + # get_running_screenshot(task, 'full_compile_release') 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_debug') if passed: + # get_running_screenshot(task, 'full_compile_debug') 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..f557943fc07a6839083a8fc724de542a209d08ea 100644 --- a/test/scripts/sdk_test/options.py +++ b/test/scripts/sdk_test/options.py @@ -73,12 +73,14 @@ 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 = [] - self.full_compilation_info = FullCompilationInfo() self.incre_compilation_info = {} self.other_tests = {} @@ -132,7 +134,7 @@ def get_ark_disasm_path(task_path): 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']), + return os.path.join(sdk_path, str(profile_data['app']['compileSdkVersion']), 'toolchains', ark_disasm) @@ -156,10 +158,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..50a623f513242448093e61a9b6a9bf19ecd98317 100644 --- a/test/scripts/sdk_test/preparation.py +++ b/test/scripts/sdk_test/preparation.py @@ -18,17 +18,13 @@ limitations under the License. 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 def setup_env(): @@ -46,125 +42,21 @@ def setup_env(): os.environ['JAVA_HOME'] = java_home -def check_deveco_env(): - if is_linux(): - return False - - java_path = os.path.join(options.configs.get('deveco_path'), 'jbr') - if not os.path.exists(java_path): - logging.error("Java not found!") - return False - - if not os.path.exists(options.configs.get('node_js_path')): - logging.error("Node js not found!") - return False - - 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 - - return True - - def clean_log(): output_log_file = options.configs.get('log_file') daily_report_file = options.configs.get('output_html_file') + picture_dic = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'pictures') 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(picture_dic): + shutil.rmtree(picture_dic) def prepare_test_env(): clean_log() - prepared = check_deveco_env() setup_env() - prepared = prepared and prepare_sdk() and prepare_image() - return prepared + + + diff --git a/test/scripts/sdk_test/run.py b/test/scripts/sdk_test/run.py index 35077749eded766dde735b1255dc2b9d83721ba3..e45aca0bf9f3799695641787ba18537f01b3f280 100644 --- a/test/scripts/sdk_test/run.py +++ b/test/scripts/sdk_test/run.py @@ -25,8 +25,8 @@ import time from execution import execute from options import process_options -from preparation import prepare_test_env from result import process_test_result +from preparation import prepare_test_env def run(): @@ -34,14 +34,13 @@ def run(): try: start_time = time.time() test_tasks = process_options() + + prepare_test_env() + if not test_tasks: logging.error("No test task found, test suite exit!") sys.exit(1) - if not prepare_test_env(): - logging.error("Prepare test environment failed, test suite exit!") - sys.exit(1) - execute(test_tasks) process_test_result(test_tasks, start_time) except Exception as e: diff --git a/test/scripts/sdk_test/utils.py b/test/scripts/sdk_test/utils.py index fdf4298aa01049f47e3e7cd8277362d6f33c51e1..5a543f8665d5fb52615ddd7588216813ece6e366 100644 --- a/test/scripts/sdk_test/utils.py +++ b/test/scripts/sdk_test/utils.py @@ -26,11 +26,8 @@ import shutil import time import subprocess import sys - import gzip -import httpx -import requests -import tqdm +from PIL import Image def get_log_level(arg_log_level): @@ -84,41 +81,6 @@ def is_esmodule(hap_type): return 'stage' in hap_type -def get_sdk_url(): - now_time = datetime.datetime.now().strftime('%Y%m%d%H%M%S') - last_hour = (datetime.datetime.now() + - datetime.timedelta(hours=-24)).strftime('%Y%m%d%H%M%S') - url = 'http://ci.openharmony.cn/api/ci-backend/ci-portal/v1/dailybuilds' - 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(now_time) - post_result = requests.post(url, data=downnload_job) - post_data = json.loads(post_result.text) - sdk_url_suffix = '' - for ohos_sdk_list in post_data['result']['dailyBuildVos']: - try: - if get_remote_sdk_name() in ohos_sdk_list['obsPath']: - sdk_url_suffix = ohos_sdk_list['obsPath'] - break - except BaseException as err: - logging.error(err) - sdk_url = 'http://download.ci.openharmony.cn/' + sdk_url_suffix - return sdk_url - - def get_api_version(json_path): with open(json_path, 'r') as uni: uni_cont = uni.read() @@ -143,28 +105,6 @@ def is_file_timestamps_same(file_a, file_b): return file_a_mtime == file_b_mtime -def download(url, temp_file, temp_file_name): - with httpx.stream('GET', url) as response: - with open(temp_file, "wb") as temp: - 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)): - if str(percentage).startswith('100'): - logging.info(f'SDK Download Complete {percentage: .1f}%') - break - else: - logging.info(f'SDK Downloading... {percentage: .1f}%') - count += 1 - pbar.update(len(chunk)) - - def add_executable_permission(file_path): current_mode = os.stat(file_path).st_mode new_mode = current_mode | 0o111 @@ -179,3 +119,77 @@ def get_remote_sdk_name(): else: logging.error('Unsuport platform to get sdk from daily build') return '' + + +def get_running_screenshot(task, image_name): + subprocess.run('hdc shell power-shell wakeup;power-shell setmode 602') + subprocess.run('hdc shell uinput -T -m 420 1000 420 400;uinput -T -m 420 400 420 1000') + + build_path = os.path.join(task.path, *task.build_path) + out_path = os.path.join(build_path, *task.output_hap_path_signed) + + subprocess.run(f'hdc install {out_path}') + subprocess.run(f'hdc shell aa start -a {task.ability_name} -b {task.bundle_name}') + time.sleep(3) + + screen_path = f'/data/local/tmp/{image_name}.jpeg' + subprocess.run(f'hdc shell snapshot_display -f {screen_path}') + time.sleep(3) + + subprocess.run(f'hdc file recv {screen_path} {image_name}.jpeg') + subprocess.run(f'hdc shell aa force-stop {task.bundle_name}') + subprocess.run(f'hdc shell bm uninstall -n {task.bundle_name}') + + pic_save_dic = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'pictures') + if not os.path.exists(pic_save_dic): + os.mkdir(pic_save_dic) + + pic_save_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), f'pictures\{task.name}') + if not os.path.exists(pic_save_path): + os.mkdir(pic_save_path) + + shutil.move(f'{image_name}.jpeg', pic_save_path) + + +def compare_screenshot(runtime_picture_path, picture_reference_path, threshold=0.95): + runtime_picture = Image.open(runtime_picture_path).convert('RGB') + + picture_reference_path = Image.open(picture_reference_path).convert('RGB') + + runtime_picture.thumbnail((256, 256)) + picture_reference_path.thumbnail((256, 256)) + + pixel1 = runtime_picture.load() + pixel2 = picture_reference_path.load() + width, height = runtime_picture.size + + similar_pixels = 0 + total_pixels = width * height + + for x in range(width): + for y in range(height): + if pixel1[x, y] == pixel2[x, y]: + similar_pixels += 1 + + similarity = similar_pixels / total_pixels + + if similarity >= threshold: + return True + else: + return False + + +def verify_runtime(task, picture_name): + pic_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), f'pictures/{task.name}/{picture_name}.jpeg') + pic_path_reference = os.path.join(os.path.dirname(os.path.abspath(__file__)), f'pictures_reference/{task.name}/{picture_name}.jpeg') + passed = compare_screenshot(pic_path, pic_path_reference, threshold=0.95) + if not passed: + logging.error(f'{task.name} get error when runing') + return False + return True + + +def out_file_backup(task, test_name): + output_file_path = os.path.join(task.path, *task.build_path, 'outputs') + output_bak_path = f'{task.name}/{test_name}/{get_time_string()}' + shutil.copytree(output_file_path, output_bak_path) diff --git a/test/scripts/email_config.yaml b/test/scripts/send_email/email_config.yaml similarity index 96% rename from test/scripts/email_config.yaml rename to test/scripts/send_email/email_config.yaml index 329f3e79f2ef65b3a3f3b7f266e881620d976d14..feae15cad6cca399998804449bb9c5f5318153da 100644 --- a/test/scripts/email_config.yaml +++ b/test/scripts/send_email/email_config.yaml @@ -1,35 +1,36 @@ -# 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. + +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 diff --git a/test/scripts/send_email.py b/test/scripts/send_email/send_email.py old mode 100755 new mode 100644 similarity index 94% rename from test/scripts/send_email.py rename to test/scripts/send_email/send_email.py index 07f7030f065291aca271c3e2356f3264c14c48bd..4e837b9769d2bcd51d5fe1004e26057b8cea02d2 --- a/test/scripts/send_email.py +++ b/test/scripts/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(): + 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"] + 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 diff --git a/test/scripts/timer.py b/test/scripts/timer.py index 99b2630bf42789975027e5486b0ad15c88400648..d1cd3fd4cb068b2838474b393ad82d21623c9e72 100755 --- a/test/scripts/timer.py +++ b/test/scripts/timer.py @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - +import argparse import os import subprocess import time @@ -22,25 +22,95 @@ import time import schedule +arguments = {} + + +def download_is_successful(): + if not os.path.exists('download/download_url.txt'): + return False + with open('download/download_url.txt', 'r') as file: + content = file.read() + if 'successfully' not in content: + return False + + return True + + +def start_download_task(): + download_command = ['python', './download/download.py'] + if arguments.download_url is not None: + download_command.extend(['--downloadUrl', arguments.download_url]) + if arguments.output_path is not None: + download_command.extend(['--outputPath', arguments.output_path]) + job(download_command) + + +def start_crawl_task(): + crawl_command = ['python', './get_commit_log/get_commit_log.py'] + if arguments.start_time is not None: + crawl_command.extend(['--startTime', arguments.start_time]) + if arguments.repo_name is not None: + crawl_command.extend(['--repoName']) + for repo_name in arguments.repo_name: + crawl_command.extend([repo_name]) + job(crawl_command) + + def job(cmd): subprocess.run(cmd, shell=False) +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--testModel', type=str, dest='test_model', default=all, + help='specify which model you want to test') + parser.add_argument('--runTime', type=str, dest='run_time', default=None, + help='specify when to start the test') + parser.add_argument('--skipDownload', type=str, dest='skip_download', default=False, + help='specify whether to skip the download or not') + parser.add_argument('--downloadUrl', type=str, dest='download_url', default=None, + help='specify what you want to download') + parser.add_argument('--outputPath', type=str, dest='output_path', default=None, + nargs='+', + help='specify where you want to store the file') + parser.add_argument('--startTime', type=str, dest='start_time', default=None, + help='specify crawl start time') + parser.add_argument('--repoName', type=str, dest='repo_name', default=None, + nargs='+', + help='specify which repo you want to crawl') + + global arguments + arguments = parser.parse_args() + + def run(): + if not arguments.skip_download: + start_download_task() + if not download_is_successful(): + return + + start_crawl_task() + + os.chdir(os.path.dirname(os.path.realpath(__file__))) 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) +if __name__ == '__main__': + parse_args() + if arguments.run_time is not None: + run_time = arguments.run_time + os.chdir(os.path.dirname(os.path.realpath(__file__))) + schedule.every().day.at(run_time).do(run) + while True: + schedule.run_pending() + time.sleep(1) + else: + run() + +