diff --git a/src/oebuild/app/conf/plugins.yaml b/src/oebuild/app/conf/plugins.yaml index d81d6dfb3294d52356c6c978cced76adb8fa47db..94556347d1e1f4afcbcdef6dec0486501d904849 100644 --- a/src/oebuild/app/conf/plugins.yaml +++ b/src/oebuild/app/conf/plugins.yaml @@ -41,3 +41,6 @@ plugins: - name: samples class: Samples path: plugins/samples/samples.py +- name: mugentest + class: MugenTest + path: plugins/mugentest/mugentest.py diff --git a/src/oebuild/app/plugins/mugentest/README.md b/src/oebuild/app/plugins/mugentest/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b6ebeaa468c5eef8ec4ec36e155b3108a20d0e39 --- /dev/null +++ b/src/oebuild/app/plugins/mugentest/README.md @@ -0,0 +1,62 @@ +# 总体介绍: + +`oebuild`作为openEuler Embedded项目的开发工具,一直以来承担着openEuler Embedded入门的导引角色,目前oebuild已经集成了相当多的功能,例如OS构建,交叉编译链构建,oebuild插件管理,软件包在线部署等等功能,然后对于一个嵌入式系统的发布,测试这一环节必不可少,openEuler Embedded对于系统版本的发布有着严格测试要求,因此对于OS系统开发者来说,本地化测试就显得尤为重要,而对于openEuler生态的系统来说,mugen是openEuler社区开放的测试框架,提供公共配置和方法以便社区开发者进行测试代码的编写和执行,其中就包括了openEuler Embedded,此次设计的插件可以使oebuild能够通过mugen来实现嵌入式OS的本地化测试。 + +## 功能概述 + +该插件主要用于通过`oebuild`工具实现以下功能: + +- 自动化本地化Mugen测试集成。 +- 支持`qemu`与BSP等嵌入式环境的选择。 +- 配置远程环境以便使用`qemu`进行测试。 +- 提供多种测试套件选择,包括: + 1. Tiny镜像测试 + 2. OS基础测试 + 3. 嵌入式安全配置测试 + 4. 嵌入式基础开发测试 + +## 使用方法 + +该插件提供了通过`oebuild`命令行工具来运行`mugen`测试的能力。以下是一个典型的使用示例: + +### 1. 运行测试 + +```bash +bash oebuild mugen-test --env bsp --mugen-path /path/to/mugen +``` + +--env 参数用于指定测试环境,可以是qemu或者bsp。 +--mugen-path 指定mugen工具的安装路径。 + +### 2. 选择测试套件 + +执行上述命令后,您将能够选择需要运行的测试套件: + +- Tiny镜像测试 +- OS基础测试 +- 嵌入式安全配置测试 +- 嵌入式基础开发测试 + +根据测试需求,选择对应的测试套件。 + +### 3. QEMU远程测试配置 + +如果选择了`qemu`环境,则需要提供远程测试的详细信息,例如IP地址、用户名、密码等: + +```bash +bash oebuild mugen-test --env qemu --mugen-path /path/to/mugen --ip 192.168.0.100 --user root --password your_password --port 22 +``` +--ip 指定远程测试机器的IP地址 +--user 指定远程测试机器的用户名 +--password 指定远程测试机器的密码 + + +停止QEMU +在OS基础测试、嵌入式安全配置测试或嵌入式基础开发测试完成后,可以使用以下命令停止QEMU: + +```bash + +bash bash qemu_ctl.sh stop +``` + + diff --git a/src/oebuild/app/plugins/mugentest/mugentest.py b/src/oebuild/app/plugins/mugentest/mugentest.py new file mode 100644 index 0000000000000000000000000000000000000000..21c5fe5177399ef406b2fdf33eeb5e11fddfc70f --- /dev/null +++ b/src/oebuild/app/plugins/mugentest/mugentest.py @@ -0,0 +1,157 @@ +import argparse +import os +import subprocess +import logging +import textwrap +import sys + +from oebuild.command import OebuildCommand + +logger = logging.getLogger() + +class MugenTest(OebuildCommand): + name = 'mugentest' + help_msg = 'This command allows you to run Mugen test cases for openEuler Embedded OS.' + description = textwrap.dedent('''\ + Run Mugen test cases for openEuler Embedded systems. + Select the environment (qemu or BSP) and specify the test case from a predefined list. + ''') + + def __init__(self): + super().__init__( + name=self.name, + help_msg=self.help_msg, + description=self.description + ) + + def do_add_parser(self, parser_adder) -> argparse.ArgumentParser: + parser = self._parser( + parser_adder, + usage=textwrap.dedent('''\ + %(prog)s --env --mugen-path [other options] + Then select the test suite from the following options: + 1 -- Tiny Image Test + 2 -- OS Basic Test + 3 -- Embedded Security Config Test + 4 -- Embedded Application Development Test + ''') + ) + + # Add arguments for environment, Mugen path, and remote details for qemu + parser.add_argument('--env', choices=['qemu', 'bsp'], required=True, help='Specify the test environment: qemu or bsp') + parser.add_argument('--mugen-path', required=False, help='Specify the path to the Mugen installation') + + # For QEMU environment: add options for kernel and initrd paths + parser.add_argument('--kernal_img_path', required=False, help='Path to the QEMU kernel image (required for certain tests)') + parser.add_argument('--initrd_path', required=False, help='Path to the QEMU initrd image (required for certain tests)') + + # For QEMU environment remote login details + parser.add_argument('--ip', required=False, help='IP address for remote testing (required for qemu)') + parser.add_argument('--user', required=False, help='Username for remote login (required for qemu)') + parser.add_argument('--password', required=False, help='Password for remote login (required for qemu)') + parser.add_argument('--port', required=False, default=22, help='SSH port (default is 22, required for qemu)') + + return parser + + def do_run(self, args: argparse.Namespace, unknown=None): + # Handle help option + if '-h' in unknown or '--help' in unknown: + self.print_help_msg() + sys.exit(0) + + # Parse additional arguments + args = args.parse_args(unknown) + + # Check Mugen path + mugen_path = self.get_mugen_path(args.mugen_path) + + if not self.is_mugen_installed(mugen_path): + print(f"Mugen not found at {mugen_path}. Please install Mugen first or specify the correct path.") + sys.exit(1) + + # Environment check for qemu + if args.env == "qemu": + if not args.ip or not args.user or not args.password: + logger.error("For qemu environment, --ip, --user, and --password are required.") + return + + # Let user choose test suite + self.select_test_suite(mugen_path, args) + + def get_mugen_path(self, custom_path=None): + if custom_path: + return custom_path + return os.getenv('MUGEN_HOME', os.path.expanduser("~/.local/mugen")) + + def is_mugen_installed(self, mugen_path): + return os.path.exists(mugen_path) + + def select_test_suite(self, mugen_path, args): + # Define test suite options + test_suites = { + 1: "embedded_tiny_image_test", + 2: "embedded_os_basic_test", + 3: "embedded_security_config_test", + 4: "embedded_application_develop_tests" + } + + # Present options to the user + print("Select a test suite to run:") + for i, suite in test_suites.items(): + print(f"{i} -- {suite.replace('_', ' ').capitalize()}") + + # Capture user choice + choice = int(input(f"Enter the number of the test suite to run (1-{len(test_suites)}): ")) + + # Ensure valid input + if choice not in test_suites: + print("Invalid choice. Exiting.") + return + + selected_suite = test_suites[choice] + self.run_mugen_test(mugen_path, selected_suite, args) + + def run_mugen_test(self, mugen_path, suite, args): + try: + print(f"Running {suite} with Mugen...") + # For qemu environment + if args.env == "qemu": + if suite == "embedded_tiny_image_test": + # Tiny image test logic + cmd = f"bash {mugen_path}/mugen.sh -c --ip {args.ip} --password {args.password} --user {args.user} --port {args.port} --put_all --run_remote" + else: + # Other qemu-based tests require starting QEMU with kernel and initrd paths + if not args.kernal_img_path or not args.initrd_path: + logger.error("For this test, --kernal_img_path and --initrd_path are required.") + return + # Start QEMU for OS basic or security or application develop tests + qemu_start_cmd = f"sh qemu_ctl.sh start --put_all --kernal_img_path {args.kernal_img_path} --initrd_path {args.initrd_path}" + if suite == "embedded_os_basic_test" or suite == "embedded_security_config_test" or suite == "embedded_application_develop_tests": + qemu_start_cmd += " --qemu_type arm" # Add this flag if ARM architecture is needed + subprocess.run(qemu_start_cmd, shell=True, check=True) + + # Run the actual test suite + if suite == "embedded_application_develop_tests": + # Compile before running the develop tests + compile_cmd = f"bash {mugen_path}/mugen.sh -b {suite}" + subprocess.run(compile_cmd, shell=True, check=True) + + # Run the selected test suite + cmd = f"bash {mugen_path}/mugen.sh -f {suite} -s" + + elif args.env == "bsp": + # For BSP environment + cmd = f"bash {mugen_path}/mugen.sh -f {suite} -s" + + # Execute the test suite command + subprocess.run(cmd, shell=True, check=True) + print(f"Test suite {suite} completed successfully.") + + # Stop QEMU after the tests for qemu environment + if args.env == "qemu" and suite != "embedded_tiny_image_test": + subprocess.run("sh qemu_ctl.sh stop", shell=True, check=True) + + except subprocess.CalledProcessError as e: + logger.error(f"Failed to run test suite {suite}: {e}") + sys.exit(1) +