diff --git a/auto-tc-gen/compile_rpm_package.py b/auto-tc-gen/compile_rpm_package.py new file mode 100644 index 0000000000000000000000000000000000000000..5617c863d9f0595c77da4aff46ddd676319ed070 --- /dev/null +++ b/auto-tc-gen/compile_rpm_package.py @@ -0,0 +1,139 @@ +# This program is licensed under Mulan PSL v2. +# You can use it according to the terms and conditions of the Mulan PSL v2. +# http://license.coscl.org.cn/MulanPSL2 +# THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +# See the Mulan PSL v2 for more details. +#################################### +# @Author : buchengjie +# @Contact : mf21320006@smail.nju.edu.cn +# @Date : 2023-4-28 12:00:00 +# @License : Mulan PSL v2 +# @Version : 1.0 +# @Desc : 软件包编译 +##################################### + + +import subprocess +import logging +import transform_rpm_package + + +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" +) + + +def get_rpm_name_path(sub_res_list): + """ + 获取包名与需要安装的rpm包路径 + + Args: + sub_res_list ([list]): [文件编译中的输出信息] + + Returns: + [string]: rpm包名 + [list]: rpm包路径 + """ + rpm_name = "" + rpm_list = [] + for d in sub_res_list: + if not d.startswith("Wrote:"): + continue + if d.startswith("Wrote: /root/rpmbuild/SRPMS/"): + rpm_name = d.split("Wrote: /root/rpmbuild/SRPMS/")[1] + rpm_name_list = rpm_name.split(".") + rpm_name = rpm_name_list[0] + for i in range(1, len(rpm_name_list) - 2): + rpm_name = rpm_name + "." + rpm_name_list[i] + if d.startswith("Wrote: /root/rpmbuild/RPMS/"): + d = d.split("Wrote:")[1].strip() + rpm_list.append(d) + return rpm_name, rpm_list + + +def automatic_install_dependency(sub_res_list): + """ + 依赖的自动导入 + + Args: + sub_res_list ([list]): [文件编译中的输出信息] + """ + dependency_list = [] + for d in sub_res_list: + if d.__contains__(" is needed by "): + dependency_list.append(d.split(" is needed by ")[0].strip().split(" ")[0]) + for d in dependency_list: + if d.startswith("perl(") and d.endswith(")"): + d = d[5:len(d) - 1] + sub_status, sub_res = subprocess.getstatusoutput("cpan " + d) + else: + sub_status, sub_res = subprocess.getstatusoutput("yum install -y " + d) + # 打印编译后十行 + sub_list = sub_res.split('\n') + for i in range(len(sub_list) - 10, len(sub_list)): + if i >= 0: + print(sub_list[i]) + if sub_status != 0: + logging.error("依赖 " + d + " 导入失败(yum install -y)") + +def compile_rpm_package(source_list): + """ + 软件包编译 + + Args: + source_list ([list]): [SPEC文件列表] + """ + if __name__ == '__main__': + print('PyCharm') + + """ 使用spec文件,编译出rpm包 """ + print(" ") + print("-----------------------------------------") + print("第二步:编译rpm包") + print("-----------------------------------------") + print(" ") + print("已检测到的spec文件为:") + spec_address = "/root/rpmbuild/SPECS" + status, res = subprocess.getstatusoutput("ls " + spec_address) + for d in res.split('\n'): + print(d) + print(" ") + print("开始编译rpm包(仅打印每个文件编译过程中输出信息的最后十行)") + # 记录需要安装的rpm包路径 + rpm_multiple_list = [] + for d in res.split('\n'): + sub_status, sub_res = subprocess.getstatusoutput("rpmbuild -ba" + " " + spec_address + "/" + d) + print(" ") + print("开始编译:" + d) + sub_res_list = sub_res.split('\n') + # 打印编译最后 20 行 + for i in range(len(sub_res_list) - 20, len(sub_res_list)): + if i >= 0: + print(sub_res_list[i]) + pass + if len(sub_res_list) > 0 and sub_res_list[len(sub_res_list) - 1].__contains__(" is needed by "): + print("------自动导入依赖------") + # 依赖的自动导入,( is needed by ) + automatic_install_dependency(sub_res_list) + sub_status, sub_res = subprocess.getstatusoutput("rpmbuild -ba" + " " + spec_address + "/" + d) + sub_res_list = sub_res.split('\n') + # 打印编译后十行 + for i in range(len(sub_res_list) - 10, len(sub_res_list)): + if i >= 0: + print(sub_res_list[i]) + if sub_status != 0: + logging.error("软件包 " + d + " 自动导入依赖失败(yum install -y)") + # 获取包名与需要安装的rpm包路径 + rpm_name, rpm_list = get_rpm_name_path(sub_res_list) + if rpm_name != "" and len(rpm_list) != 0: + # 将包名插入第一个位置,与rpm需要安装的包路径放在一起 + rpm_list.insert(0, rpm_name) + rpm_multiple_list.append(rpm_list) + # 打印编译失败的情况 + if not sub_res_list[len(sub_res_list)-1].__contains__("exit 0"): + for l in sub_res_list: + print(l) + logging.error("软件包 " + d + " 编译失败(rpmbuild -ba)") + transform_rpm_package.transform_rpm_package(source_list, rpm_multiple_list) diff --git a/auto-tc-gen/input_directory.py b/auto-tc-gen/input_directory.py new file mode 100644 index 0000000000000000000000000000000000000000..8c9ba8a20e597493afd17849f155b8f25d63b896 --- /dev/null +++ b/auto-tc-gen/input_directory.py @@ -0,0 +1,34 @@ +# This program is licensed under Mulan PSL v2. +# You can use it according to the terms and conditions of the Mulan PSL v2. +# http://license.coscl.org.cn/MulanPSL2 +# THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +# See the Mulan PSL v2 for more details. +#################################### +# @Author : buchengjie +# @Contact : mf21320006@smail.nju.edu.cn +# @Date : 2023-4-28 12:00:00 +# @License : Mulan PSL v2 +# @Version : 1.0 +# @Desc : 本地源码目录获取 +##################################### + + +import install_source_package +from help_parse import parameter_classify + + +def input_directory(): + """ + 获取本地源码包路径 + """ + print("请输入本地源码包路径, 例如:/root/test (默认为 /root/test)") + address = input() + if address == '': + address = "/root/test" + + # 初始化参数映射 + parameter_classify.initialize_parameters() + # 安装源码包 + install_source_package.install_source_package(address) diff --git a/auto-tc-gen/install_source_package.py b/auto-tc-gen/install_source_package.py new file mode 100644 index 0000000000000000000000000000000000000000..a23cc1aba92c5bb8c564809af6c0182e3f69b16d --- /dev/null +++ b/auto-tc-gen/install_source_package.py @@ -0,0 +1,75 @@ +# This program is licensed under Mulan PSL v2. +# You can use it according to the terms and conditions of the Mulan PSL v2. +# http://license.coscl.org.cn/MulanPSL2 +# THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +# See the Mulan PSL v2 for more details. +#################################### +# @Author : buchengjie +# @Contact : mf21320006@smail.nju.edu.cn +# @Date : 2023-4-28 12:00:00 +# @License : Mulan PSL v2 +# @Version : 1.0 +# @Desc : 源码包安装 +##################################### + +import logging +import subprocess +import compile_rpm_package + + +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" +) + + +def install_source_package(address): + """ + 安装源码包 + + Args: + address ([string]): [源码包本地目录] + """ + print(" ") + print("-----------------------------------------") + print("第一步:安装源码包(XXX.src.rpm)") + print("-----------------------------------------") + print(" ") + source_list = [] + status, res = subprocess.getstatusoutput("ls" + " " + address) + print("已检测到的源码包为: ") + for d in res.split('\n'): + print(d) + source_list.append(d) + + # 使用 dnf install 的方式安装软件包,便于后续使用预设值自动生成测试用例时测试 + print("使用 dnf install 的方式安装源码包(仅打印每个文件安装过程中输出信息的最后十行)") + for d in res.split('\n'): + d = d.lstrip() + name_list = d.split("-") + name = name_list[0] + for i in range(1, len(name_list)): + if name_list[i].isspace(): + continue + if 0 <= ord(name_list[i][0]) - ord('0') <= 9: + break + name = name + "-" + name_list[i] + + sub_status, sub_res = subprocess.getstatusoutput("dnf install" + " " + name) + sub_res_list = sub_res.split('\n') + for i in range(len(sub_res_list) - 10, len(sub_res_list)): + if i >= 0: + print(sub_res_list[i]) + pass + if sub_status != 0: + logging.error("软件包 " + name + " 安装失败(dnf install)") + + print("开始安装源码包:") + for d in res.split('\n'): + sub_status, sub_res = subprocess.getstatusoutput("rpm -ivh" + " " + str(address) + "/" + d) + print(sub_res) + if sub_status != 0: + logging.error("SRPM包 " + d + " 安装失败(rpm -ivh)") + + compile_rpm_package.compile_rpm_package(source_list) diff --git a/auto-tc-gen/main.py b/auto-tc-gen/main.py new file mode 100644 index 0000000000000000000000000000000000000000..3833c750103d7634d613d4bfa7d64514554e80ca --- /dev/null +++ b/auto-tc-gen/main.py @@ -0,0 +1,25 @@ +# This program is licensed under Mulan PSL v2. +# You can use it according to the terms and conditions of the Mulan PSL v2. +# http://license.coscl.org.cn/MulanPSL2 +# THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +# See the Mulan PSL v2 for more details. +#################################### +# @Author : buchengjie +# @Contact : mf21320006@smail.nju.edu.cn +# @Date : 2023-4-28 12:00:00 +# @License : Mulan PSL v2 +# @Version : 1.0 +# @Desc : 工具入口 +##################################### + + +import input_directory + + +if __name__ == '__main__': + """ + 工具入口 + """ + input_directory.input_directory() diff --git a/auto-tc-gen/transform_rpm_package.py b/auto-tc-gen/transform_rpm_package.py new file mode 100644 index 0000000000000000000000000000000000000000..7ce1a536f8ac96a4bd1ada79fae723875b8de599 --- /dev/null +++ b/auto-tc-gen/transform_rpm_package.py @@ -0,0 +1,130 @@ +# This program is licensed under Mulan PSL v2. +# You can use it according to the terms and conditions of the Mulan PSL v2. +# http://license.coscl.org.cn/MulanPSL2 +# THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +# See the Mulan PSL v2 for more details. +#################################### +# @Author : buchengjie +# @Contact : mf21320006@smail.nju.edu.cn +# @Date : 2023-4-28 12:00:00 +# @License : Mulan PSL v2 +# @Version : 1.0 +# @Desc : RPM 包解压 +##################################### + +import subprocess +import logging +from help_parse import extract_source_code as help_parse_extract_source_code + +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" +) + +def get_possible_rpm_name(suffix, rpm_possible_name_list, source_list): + """ + 由源码包名称,拼接出 noarch 与 x86_64 两个目录下的可能存在的 rpm 包名称 + + Args: + suffix ([string]): [前缀] + rpm_possible_name_list ([list]): [可能需要解压的rpm包名称] + source_list ([list]): [rpm包路径] + """ + for d in source_list: + source_name_list = d.split('.') + source_name = "" + for i in range(0, len(source_name_list) - 2): + source_name = source_name + "" + source_name_list[i] + "." + source_name = source_name + "" + suffix + ".rpm" + rpm_possible_name_list.append(source_name) + +def get_rpm_name(suffix, rpm_possible_name_list, rpm_name_list): + """ + # 获取需要解压的 rpm 包名称 + + Args: + suffix ([string]): [前缀] + rpm_possible_name_list ([list]): [可能需要解压的rpm包名称] + rpm_name_list ([list]): [需要解压的rpm包名称] + """ + rpm_address = "/root/rpmbuild/RPMS/" + suffix + status, res = subprocess.getstatusoutput("ls" + " " + rpm_address) + for d in res.split('\n'): + if rpm_possible_name_list.__contains__(d): + rpm_name_list.append(d) + +def converted_package(rpm_multiple_list, pre_name_list): + """ + 根据 rpm_multiple_list 中包含的包名与路径,解压rpm包 + + Args: + rpm_multiple_list ([list]): [需要解压的rpm包名称] + pre_name_list ([list]): [rpm包存放目录前缀] + """ + for rpm_list in rpm_multiple_list: + if rpm_list is None or len(rpm_list) == 0: + continue + else: + rpm_name = rpm_list[0] + pre_name = "/root/rpmbuild/CPIO/" + rpm_name + "/" + pre_name_list.append(pre_name) + subprocess.getstatusoutput("mkdir -p " + pre_name) + for i in range(1, len(rpm_list)): + subprocess.getstatusoutput("rm -rf ./usr/") + sub_status, sub_res = subprocess.getstatusoutput("rpm2cpio " + rpm_list[i] + " | cpio -div") + # rpm2cpio后默认在当前目录(也就是python程序存放的目录,测试环境中为/home/tmp/pythonProject),将安装产生的文件剪切到指定位置 + subprocess.getstatusoutput("cp -r ./usr/ " + pre_name) + subprocess.getstatusoutput("rm -rf ./usr/") + sub_res_info_list = sub_res.split('\n') + for j in range(len(sub_res_info_list) - 10, len(sub_res_info_list)): + if j >= 0: + print(sub_res_info_list[j]) + pass + if sub_status != 0: + logging.error("RPM包 " + rpm_list[i] + " 解压失败(rpm2cpio)") + pass + +def transform_rpm_package(source_list, rpm_multiple_list): + """ + 解压 rpm 包 + + Args: + source_list ([list]): [rpm包路径] + rpm_multiple_list ([list]): [需要解压的rpm包名称] + """ + print(" ") + print("-----------------------------------------") + print("第三步: 解压rpm包") + print("-----------------------------------------") + print(" ") + print("已检测到的rpm包为:") + + for rpm_list in rpm_multiple_list: + if rpm_list is not None and len(rpm_list) != 0: + for i in range(1, len(rpm_list)): + print(rpm_list[i]) + + # 记录所有可能存在的,需要转换的 rpm 包名称 + rpm_possible_name_list = [] + get_possible_rpm_name("noarch", rpm_possible_name_list, source_list) + get_possible_rpm_name("x86_64", rpm_possible_name_list, source_list) + + # 记录两种需要解压的 rpm 包名称 + rpm_name_noarch_list = [] + rpm_name_x86_list = [] + get_rpm_name("noarch", rpm_possible_name_list, rpm_name_noarch_list) + get_rpm_name("x86_64", rpm_possible_name_list, rpm_name_x86_list) + + print(" ") + print("开始解压rpm包(仅打印每个文件编译过程中输出信息的最后十行)") + + # 记录解压后的包路径 + pre_name_list = [] + converted_package(rpm_multiple_list, pre_name_list) + + print(" ") + print("rpm文件解压完成后存放的位置为: ") + for d in pre_name_list: + print(d) + help_parse_extract_source_code.extract_source_code(pre_name_list, 1)