问题
目前 ostool 只支持一组顶层 shell 初始化配置:
shell_prefix = "root@starry:/root #"
shell_init_cmd = "echo pass"
success_regex = ["(?m)^pass\\s*$"]
这种配置要求 runner 启动后已经位于目标 shell。
Axvisor 引入 guest console 隔离后,物理终端默认停留在 Axvisor shell,guest 串口日志由 Axvisor 缓存。测试需要按下面的顺序操作:
Axvisor shell
-> vm console 1
-> guest shell
-> guest test command
现有的单组 shell_prefix 和 shell_init_cmd 无法表达这个过程。
实际失败日志中,Axvisor 已经成功启动 guest,但 ostool 一直停留在 Axvisor shell,最终等待 guest 成功标记超时:
axvisor:/$
kernel boot timed out after 300s
手动输入 vm console 1 后,可以看到 guest 日志并继续测试。
建议方案
为 QEMU、U-Boot 和 board 配置增加显式有序数组 shell_init_steps:
shell_check_steps = [
{
name = "attach guest",
shell_prefix = "axvisor:/$",
shell_cmd = "vm console 1"
},
{
name = "run guest test",
shell_prefix = "root@starry:/root #",
shell_cmd = "pwd && echo 'starry guest test pass'",
success_regex = ["(?m)^starry guest test pass\\s*$"],
fail_regex = ["(?i)failed", "(?i)panic"],
timeout = 30
},
]
数组下标就是执行顺序。
每一步支持:
pub struct ShellCheckStep {
pub name: Option<String>,
pub shell_prefix: Option<String>,
pub shell_cmd: String,
pub success_regex: Option<Vec<String>>,
pub fail_regex: Option<Vec<String>>,
pub timeout: Option<u64>,
}
配置语义
shell prefix
- 第一步必须配置非空的
shell_prefix。
- 后续步骤省略
shell_prefix 时,继承前一步。
- 显式配置空字符串时报错。
shell_prefix 使用普通字符串匹配,不作为正则处理。
例如:
shell_check_steps = [
{ shell_prefix = "root#", shell_cmd = "cd /tmp" },
{ shell_cmd = "./test", success_regex = ["PASS"] },
]
第二步继承 root#。
success 和 fail
shell_check_steps 之间严格按数组顺序执行。只有当前步骤完成后,才会进入下一步;不能跨步骤匹配,也不能跳过中间步骤。
- 单个步骤内部可以配置多个
success_regex。当前步骤的任意一个 success 匹配后,该步骤完成并进入下一步。
- 单个步骤内部也可以配置多个
fail_regex。当前步骤的任意一个 fail 匹配后,该步骤立即失败,整个测试结束。
- 当前步骤的同一批输出同时匹配 success 和 fail 时,fail 优先。
- 不允许只配置
fail_regex 而没有 success_regex,因为这种步骤没有明确的成功条件。
可以概括为:步骤之间是顺序 AND;单个步骤内部的 success_regex 是 OR,fail_regex 也是 OR。
没有结果表达式的步骤
如果某一步没有配置 success_regex 和 fail_regex,命令完成 write/flush 后直接进入下一步:
{ shell_prefix = "axvisor:/$", shell_cmd = "vm console 1" }
这只能证明命令已经送入终端,不能单独证明命令执行成功。通常由下一步 guest prefix 证明 console 切换已经生效。
timeout
- 步骤
timeout 从命令完成 write/flush 后开始。
- 它只覆盖该步骤等待结果的阶段。
- 顶层
timeout 继续作为整个运行过程的总超时。
- timeout 和成功匹配必须是互斥的状态转换,不能在截止时间附近同时把测试标记为成功和失败。
只读取 guest 启动结果
有些测试不需要在 guest shell 执行命令,但成功标记只存在于 guest console。只有当前 Axvisor 输出流确实看不到该标记时,才需要 attach。
这种情况只需要一个步骤:
success_regex = []
fail_regex = [
"(?i)kernel panic",
"(?m)^AXVISOR_X86_ACPI_FAILED\\s*$",
]
shell_check_steps = [
{
shell_prefix = "axvisor:/$",
shell_cmd = "vm console 1",
success_regex = ["(?m)^AXVISOR_GUEST_PASSED\\s*$"],
fail_regex = ["(?i)kernel panic"]
},
]
ostool 发送 vm console 1 后,由当前步骤从 Axvisor 回放的 guest 日志中匹配结果。若 ACPI、timer 等测例的成功标记本来就在当前流中,则应保持原配置,不添加步骤。
问题
目前 ostool 只支持一组顶层 shell 初始化配置:
这种配置要求 runner 启动后已经位于目标 shell。
Axvisor 引入 guest console 隔离后,物理终端默认停留在 Axvisor shell,guest 串口日志由 Axvisor 缓存。测试需要按下面的顺序操作:
现有的单组
shell_prefix和shell_init_cmd无法表达这个过程。实际失败日志中,Axvisor 已经成功启动 guest,但 ostool 一直停留在 Axvisor shell,最终等待 guest 成功标记超时:
手动输入
vm console 1后,可以看到 guest 日志并继续测试。建议方案
为 QEMU、U-Boot 和 board 配置增加显式有序数组
shell_init_steps:数组下标就是执行顺序。
每一步支持:
配置语义
shell prefix
shell_prefix。shell_prefix时,继承前一步。shell_prefix使用普通字符串匹配,不作为正则处理。例如:
第二步继承
root#。success 和 fail
shell_check_steps之间严格按数组顺序执行。只有当前步骤完成后,才会进入下一步;不能跨步骤匹配,也不能跳过中间步骤。success_regex。当前步骤的任意一个 success 匹配后,该步骤完成并进入下一步。fail_regex。当前步骤的任意一个 fail 匹配后,该步骤立即失败,整个测试结束。fail_regex而没有success_regex,因为这种步骤没有明确的成功条件。可以概括为:步骤之间是顺序 AND;单个步骤内部的
success_regex是 OR,fail_regex也是 OR。没有结果表达式的步骤
如果某一步没有配置
success_regex和fail_regex,命令完成 write/flush 后直接进入下一步:这只能证明命令已经送入终端,不能单独证明命令执行成功。通常由下一步 guest prefix 证明 console 切换已经生效。
timeout
timeout从命令完成 write/flush 后开始。timeout继续作为整个运行过程的总超时。只读取 guest 启动结果
有些测试不需要在 guest shell 执行命令,但成功标记只存在于 guest console。只有当前 Axvisor 输出流确实看不到该标记时,才需要 attach。
这种情况只需要一个步骤:
ostool 发送
vm console 1后,由当前步骤从 Axvisor 回放的 guest 日志中匹配结果。若 ACPI、timer 等测例的成功标记本来就在当前流中,则应保持原配置,不添加步骤。