Browse Source

feat(test): 增加系统启动后执行syscall集成测试的make命令并将其加入流水线中 (#1306)

* feat(test): 增加系统启动后执行syscall集成测试的make命令并将其加入流水线中
黄铭涛 3 weeks ago
parent
commit
b74420f48e

+ 30 - 0
.github/workflows/test-x86.yml

@@ -0,0 +1,30 @@
+name: Test x86_64
+
+on:
+  workflow_dispatch:
+  push:
+    branches: ["master", "feat-*", "fix-*"]
+  pull_request:
+    branches: ["master", "feat-*", "fix-*"]
+
+env:
+  ARCH: x86_64
+  HOME: /root
+  RUSTUP_DIST_SERVER: "https://rsproxy.cn"
+  RUSTUP_UPDATE_ROOT: "https://rsproxy.cn/rustup"
+
+jobs:
+  integration-test:
+    name: Integration Test
+    runs-on: ubuntu-latest
+    container: 
+      image: dragonos/dragonos-dev:v1.14
+      options: --privileged -v /dev:/dev
+    steps:
+      - name: Checkout DragonOS code
+        uses: actions/checkout@v4
+
+      - name: Run syscall test
+        shell: bash -ileo pipefail {0}
+        run: |
+          make test-syscall

+ 11 - 0
Makefile

@@ -153,6 +153,16 @@ run-docker: check_arch
 	$(MAKE) write_diskimage || exit 1
 	$(MAKE) qemu
 
+test-syscall: check_arch
+	@echo "构建运行并执行syscall测试"
+	bash user/apps/tests/syscall/gvisor/enable_compile_gvisor.sh
+	$(MAKE) all -j $(NPROCS)
+	$(MAKE) write_diskimage || exit 1
+	$(MAKE) qemu-nographic AUTO_TEST=syscall SYSCALL_TEST_DIR=/opt/tests/gvisor &
+	QEMU_PID=$$!
+	bash user/apps/tests/syscall/gvisor/monitor_test_results.sh || { bash user/apps/tests/syscall/gvisor/disable_compile_gvisor.sh; exit 1; }
+	bash user/apps/tests/syscall/gvisor/disable_compile_gvisor.sh
+
 fmt: check_arch
 	@echo "格式化代码" 
 	FMT_CHECK=$(FMT_CHECK) $(MAKE) fmt -C kernel
@@ -199,6 +209,7 @@ help:
 	@echo "  make log-monitor      - 启动日志监控"
 	@echo "  make docs             - 生成文档"
 	@echo "  make clean-docs       - 清理文档"
+	@echo "  make test-syscall     - 构建运行并执行syscall测试"
 	@echo ""
 	@echo "  make update-submodules - 更新子模块"
 	@echo "  make update-submodules-by-mirror - 从镜像更新子模块"

+ 1 - 0
docs/introduction/build_system.md

@@ -250,6 +250,7 @@ make run-docker
 - 编译文档: `make docs` (需要手动安装sphinx以及docs下的`requirements.txt`中的依赖)
 - 清理文档: `make clean-docs`
 - 格式化代码: `make fmt`
+- 运行并执行syscall测试: `make test-syscall`
 
 :::{note}
 如果您需要在vnc中运行DragonOS,请在上述命令后加上`-vnc`后缀。如:`make run-vnc`

+ 8 - 0
docs/kernel/device/index.rst

@@ -0,0 +1,8 @@
+====================================
+Device
+====================================
+   
+.. toctree::
+   :maxdepth: 1
+
+   tty

+ 15 - 1
docs/kernel/ktest/gvisor_syscall_test.rst

@@ -16,7 +16,21 @@ gVisor 是 Google 开发的容器运行时沙箱,包含了大量的系统调
 - **黑名单过滤**:可针对每个测试程序屏蔽特定的测试用例
 - **自动化运行**:提供 Makefile 和脚本简化测试流程
 
-快速开始
+自动测试
+==========
+
+执行`make test-syscall`命令。该命令将启动DragonOS并自动执行gvisor syscall测试套件,测试完成后会退出qemu。同时根据测试用例成功率选择是成功返回还是失败返回,成功率不等于100%则失败返回。该命令的执行流程如下:
+
+1. 执行`enable_compile_gvisor.sh`注释`app-blocklist.toml`中有关于屏蔽gvisor测试套的配置
+2. 编译DragonOS
+3. 写入镜像
+4. 后台qemu无图形模式启动DragonOS,同时设置环境变量`AUTO_TEST`(自动测试选项,目前仅支持syscall测试)和`SYSCALL_TEST_DIR`(测试套所在目录),这两个环境变量会通过命令行参数传递到DragonOS。然后当busybox init进程执行rcS脚本时,该脚本会通过`AUTO_TEST`选项执行对应的测试
+5. 执行`monitor_test_results.sh`定时查看qemu串口输出内容,并根据测试结果选择成功返回还是失败返回
+6. 执行`disable_compile_gvisor.sh`取消`app-blocklist.toml`中有关于屏蔽gvisor测试套的配置注释
+
+对应的workflow配置文件为`test-x86.yml`
+
+手动测试
 ==========
 
 1. 进入测试目录:

+ 8 - 1
tools/run-qemu.sh

@@ -114,6 +114,13 @@ QEMU_NOGRAPHIC=false
 
 KERNEL_CMDLINE=" "
 
+# 自动测试选项,支持的选项:
+# - none: 不进行自动测试
+# - syscall: 进行gvisor系统调用测试
+AUTO_TEST=${AUTO_TEST:=none}
+# gvisor测试目录
+SYSCALL_TEST_DIR=${SYSCALL_TEST_DIR:=/opt/tests/gvisor}
+
 BIOS_TYPE=""
 #这个变量为true则使用virtio磁盘
 VIRTIO_BLK_DEVICE=true
@@ -187,7 +194,7 @@ while true;do
 
 setup_kernel_init_program() {
     if [ ${ARCH} == "x86_64" ]; then
-        KERNEL_CMDLINE+=" init=/bin/busybox init "
+        KERNEL_CMDLINE+=" init=/bin/busybox init AUTO_TEST=${AUTO_TEST} SYSCALL_TEST_DIR=${SYSCALL_TEST_DIR} "
         # KERNEL_CMDLINE+=" init=/bin/dragonreach "
     elif [ ${ARCH} == "riscv64" ]; then
         KERNEL_CMDLINE+=" init=/bin/riscv_rust_init "

+ 1 - 0
user/apps/tests/syscall/gvisor/Makefile

@@ -70,6 +70,7 @@ install: build download whitelist.txt $(BLOCKLIST_FILES)
 	@cp -f whitelist.txt $(INSTALL_DIR)/
 	@cp -rf blocklists $(INSTALL_DIR)/
 	@cp -rf tests $(INSTALL_DIR)/
+	@cp -f run_tests.sh $(INSTALL_DIR)/
 	@echo "安装完成"
 
 # 运行测试

+ 9 - 0
user/apps/tests/syscall/gvisor/disable_compile_gvisor.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+CONFIG_FILE=config/app-blocklist.toml
+
+sed -i \
+  -e '/^\s*#\s*\[\[blocked_apps\]\]\s*$/ s/^\s*#\s*//' \
+  -e '/^\s*#\s*name\s*=\s*"gvisor syscall tests"\s*$/ s/^\s*#\s*//' \
+  -e '/^\s*#\s*reason\s*=\s*"由于文件较大,因此屏蔽。如果要允许系统调用测试,则把这几行取消注释即可"\s*$/ s/^\s*#\s*//' \
+  $CONFIG_FILE

+ 9 - 0
user/apps/tests/syscall/gvisor/enable_compile_gvisor.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+CONFIG_FILE=config/app-blocklist.toml
+
+sed -i -E \
+  -e 's/^[[:space:]]*#*[[:space:]]*(\[\[blocked_apps\]\])[[:space:]]*$/# \1/' \
+  -e 's/^[[:space:]]*#*[[:space:]]*(name[[:space:]]*=[[:space:]]*"gvisor syscall tests")[[:space:]]*$/# \1/' \
+  -e 's/^[[:space:]]*#*[[:space:]]*(reason[[:space:]]*=[[:space:]]*"由于文件较大,因此屏蔽。如果要允许系统调用测试,则把这几行取消注释即可")[[:space:]]*$/# \1/' \
+  $CONFIG_FILE  

+ 34 - 0
user/apps/tests/syscall/gvisor/monitor_test_results.sh

@@ -0,0 +1,34 @@
+#!/bin/busybox sh
+
+# 串口文件路径
+SERIAL_FILE="serial_opt.txt"
+# qemu进程PID
+QEMU_PID=${QEMU_PID}
+# 清空串口输出日志文件
+> "$SERIAL_FILE"
+# 资源清理函数
+clean_up() {
+    kill -9 $QEMU_PID
+    stty sane 2>/dev/null
+}
+
+# 每隔10s查看qemu串口输出日志文件serial_opt.txt后100行是否包含“测试完成”
+while true; do
+    sleep 10
+    tail -n 100 "$SERIAL_FILE" | grep -a "测试完成" && break
+done
+
+# 提取成功率
+success_rate=$(grep -a "成功率" "$SERIAL_FILE" | awk -F'[:%]' '{gsub(/ /,""); print $2}')
+
+# 比较是否等于100
+if [ "$success_rate" = "100.00" ]; then
+    echo "syscall测试通过, 成功率为 ${success_rate}%"
+    clean_up
+    stty sane 2>/dev/null
+    exit 0
+else
+    echo "syscall测试失败, 成功率为 ${success_rate}%"
+    clean_up
+    exit 1
+fi

+ 4 - 0
user/apps/tests/syscall/gvisor/run_tests.sh

@@ -0,0 +1,4 @@
+#!/bin/busybox sh
+
+cd $SYSCALL_TEST_DIR
+./gvisor-test-runner

+ 6 - 1
user/sysconfig/etc/init.d/rcS

@@ -1,3 +1,8 @@
 #!/bin/sh
 echo "[rcS] Running system init script..."
-/bin/about.elf
+/bin/about.elf
+
+# 根据环境变量AUTO_TEST决定是否进行自动测试
+if [ "$AUTO_TEST" = "syscall" ]; then
+    /bin/busybox sh $SYSCALL_TEST_DIR/run_tests.sh
+fi