1
00:00:03,767 --> 00:00:05,718
这是 testbed-qemu

2
00:00:05,718 --> 00:00:09,619
它在 QEMU 中启动一台
真实的 prplOS 路由器

3
00:00:10,120 --> 00:00:14,300
我们称这台路由器
为被测设备，即 DUT

4
00:00:14,800 --> 00:00:19,373
它运行 prplOS 的 cram 测试，
与 CI 运行的测试相同

5
00:00:19,873 --> 00:00:24,837
它在你的电脑上启动 DUT，
使用你选择的 prplOS 镜像

6
00:00:29,197 --> 00:00:33,692
testbed-qemu 由 Docker Compose
或 rootless Podman 作为容器运行

7
00:00:33,692 --> 00:00:38,740
在容器内，测试主机运行
cram、SSH 和串口控制台

8
00:00:38,740 --> 00:00:43,235
在它旁边，QEMU 启动 DUT，
主机支持 KVM 时会使用 KVM

9
00:00:43,235 --> 00:00:45,586
三条线路连接两边

10
00:00:45,586 --> 00:00:47,937
LAN 承载测试流量

11
00:00:47,937 --> 00:00:52,086
WAN 从容器内的
DHCP 服务器获取地址

12
00:00:52,086 --> 00:00:54,922
并通过它访问外部网络

13
00:00:54,922 --> 00:00:57,480
第三条线路是串口控制台

14
00:00:57,480 --> 00:01:02,805
主机向容器提供 prplOS 源码树，
以及只读的 prplOS 镜像

15
00:01:02,805 --> 00:01:07,092
还提供一个日志和结果目录

16
00:01:07,092 --> 00:01:09,374
以及 shell 的持久磁盘目录

17
00:01:13,734 --> 00:01:19,603
需要 Linux 主机、Docker Compose
或 rootless Podman、git 和 make

18
00:01:19,603 --> 00:01:23,020
有 KVM 时，DUT
大约半分钟就能启动

19
00:01:23,020 --> 00:01:26,065
没有 KVM，
QEMU 也能运行，只是很慢

20
00:01:26,565 --> 00:01:29,388
克隆 testbed-qemu 仓库

21
00:01:32,900 --> 00:01:34,361
然后运行 make fetch

22
00:01:34,361 --> 00:01:38,892
它下载固定版本的
prplOS 镜像并验证校验和

23
00:01:38,892 --> 00:01:43,716
它还会把精简的 prplOS
测试树写入 qa-cache 目录

24
00:01:44,216 --> 00:01:46,580
然后运行 make test-qemu-shell

25
00:01:46,580 --> 00:01:49,575
首次使用时，它会构建容器

26
00:01:49,575 --> 00:01:53,595
它启动 DUT，
并在容器中打开一个 shell

27
00:01:57,955 --> 00:02:01,838
smoke 等测试 bucket
需要完整克隆的 prplOS 仓库

28
00:02:01,838 --> 00:02:04,655
而不是 make fetch 生成的精简树

29
00:02:04,655 --> 00:02:08,614
所以请在 testbed-qemu
固定的提交上克隆 prplOS

30
00:02:09,114 --> 00:02:10,802
然后运行 make test-qemu

31
00:02:10,802 --> 00:02:14,318
让它指向该克隆，
并选择 smoke bucket

32
00:02:14,318 --> 00:02:18,256
它启动一个全新的 DUT，
并等待 SSH 和数据模型就绪

33
00:02:18,256 --> 00:02:23,038
然后运行该克隆为此板卡
列出的六个 smoke 测试

34
00:02:25,502 --> 00:02:30,410
在 prplOS CI 中，合并请求
可以手动启动同一个 smoke bucket

35
00:02:30,410 --> 00:02:33,967
作为 QEMU 作业，
运行在同一个 testbed-qemu 容器中

36
00:02:33,967 --> 00:02:37,453
它运行六个 smoke 测试，
并跳过其中一个

37
00:02:37,453 --> 00:02:39,444
然后运行两个后置测试

38
00:02:39,444 --> 00:02:44,708
运行通过了，作业仍从
DUT 收集了调试信息

39
00:02:44,708 --> 00:02:47,838
该作业运行在带有 KVM 的
GitLab runner 上

40
00:02:52,198 --> 00:02:55,002
shell 模式就是
make test-qemu-shell

41
00:02:55,002 --> 00:02:59,409
会立即得到一个 shell，
而此时 DUT 仍在启动

42
00:02:59,967 --> 00:03:01,655
按上箭头键

43
00:03:01,655 --> 00:03:07,875
shell 历史已有 testbed-qemu wait
和 testbed-qemu ssh

44
00:03:07,875 --> 00:03:12,673
wait 命令会一直阻塞，
直到 DUT 通过 SSH 响应

45
00:03:12,673 --> 00:03:16,138
然后 ssh 在 DUT 上
打开 root shell

46
00:03:16,638 --> 00:03:21,446
现在以 root 身份操作 DUT，
例如列出它的路由

47
00:03:25,638 --> 00:03:31,755
如果需要串口控制台而不是 SSH，
运行 testbed-qemu console

48
00:03:31,755 --> 00:03:33,909
按回车键显示提示符

49
00:03:33,909 --> 00:03:36,924
按 Ctrl 加右方括号返回 shell

50
00:03:41,284 --> 00:03:42,410
现在添加一个测试

51
00:03:42,410 --> 00:03:47,967
保存到你电脑上的 prplOS 源码树：
shell 看到同样的文件

52
00:03:47,967 --> 00:03:52,848
cram 测试是一个文本文件：
一条命令，然后是预期输出

53
00:03:52,848 --> 00:03:56,828
这个测试检查 SSH
能否通过 LAN 连到 DUT

54
00:03:57,328 --> 00:03:59,474
用 testbed-qemu cram 运行它

55
00:03:59,474 --> 00:04:02,480
它在已启动的 DUT 上运行

56
00:04:02,480 --> 00:04:05,270
所以可以反复运行，无需重新启动

57
00:04:05,770 --> 00:04:09,455
现在把它改坏：
修改文件中的预期输出

58
00:04:12,270 --> 00:04:13,194
再运行一次

59
00:04:13,194 --> 00:04:18,593
cram 输出一个 diff：
测试期望的行，以及实际得到的行

60
00:04:20,770 --> 00:04:26,064
如果新输出正确，就接受它：
把测试运行器打印的 cp 命令

61
00:04:26,064 --> 00:04:26,858
在主机上运行

62
00:04:32,630 --> 00:04:34,940
CI 中的 QEMU 作业失败时

63
00:04:34,940 --> 00:04:41,043
先在你的电脑上复现：
用 make test-qemu 运行同一个测试

64
00:04:41,543 --> 00:04:45,620
这里运行 testbed-qemu
自带的重启测试

65
00:04:45,620 --> 00:04:50,770
它写入一个标记文件，
重启 DUT，并等待 SSH 恢复

66
00:04:50,770 --> 00:04:55,706
然后检查标记是否还在，
以及系统运行时间是否已重置

67
00:04:55,706 --> 00:04:59,568
testbed-qemu 自己的 CI
在每条流水线中都运行此测试

68
00:05:00,068 --> 00:05:03,827
make test-qemu
批量运行时，总会启动

69
00:05:03,827 --> 00:05:06,054
一份私有的出厂状态镜像副本

70
00:05:06,054 --> 00:05:10,092
shell 首次使用时
会用镜像刷写自己的磁盘

71
00:05:10,092 --> 00:05:14,755
并在会话之间保留该磁盘，
位于 qemu-disk-state 目录

72
00:05:14,755 --> 00:05:17,748
要从头开始，运行
testbed-qemu disk reset

73
00:05:17,748 --> 00:05:21,438
之后，下一次受控启动就是出厂状态

74
00:05:21,938 --> 00:05:23,150
运行失败时

75
00:05:23,150 --> 00:05:26,786
testbed-qemu 会从
DUT 收集调试信息

76
00:05:26,786 --> 00:05:28,925
之后才关闭 DUT

77
00:05:28,925 --> 00:05:34,914
你之前看到的 prplOS CI 作业
每次运行都会收集，即使运行通过

78
00:05:34,914 --> 00:05:38,265
在交互式 shell 中，
可以随时获取

79
00:05:42,625 --> 00:05:45,473
testbed-qemu 还为
智能体提供一个 skill

80
00:05:45,473 --> 00:05:49,880
skill 文件列出了确切的
命令、退出码和操作手册

81
00:05:49,880 --> 00:05:53,067
这里 Claude Code 使用 Sonnet，
以自动模式工作

82
00:05:53,067 --> 00:05:56,729
它加载 skill，
并用 doctor 检查主机

83
00:05:56,729 --> 00:05:59,373
doctor 会先构建容器镜像

84
00:05:59,373 --> 00:06:03,984
然后测试在 QEMU 中启动 DUT，
等待 SSH 和数据模型

85
00:06:03,984 --> 00:06:06,086
并运行连通性测试

86
00:06:06,086 --> 00:06:09,679
它报告测试已通过，附带后置检查

87
00:06:09,679 --> 00:06:11,917
启动时间和产物

88
00:06:11,917 --> 00:06:16,324
状态栏显示本次运行
花费的 token、时间和费用

89
00:06:18,985 --> 00:06:24,049
testbed-qemu 启动你获取的
prplOS 镜像，带有完整的用户空间

90
00:06:24,049 --> 00:06:27,739
它为 DUT 提供真实的
LAN、WAN 和串口控制台

91
00:06:27,739 --> 00:06:30,198
它不能替代真实硬件

92
00:06:30,198 --> 00:06:34,033
也不模拟交换机或蜂窝网关

