FreeBSD 中文社区 2025 第二季度问卷调查
FreeBSD 中文社区(CFC)
VitePress 镜像站QQ 群 787969044视频教程Ⅰ视频教程Ⅱ
  • FreeBSD 从入门到追忆
  • 中文期刊
  • 状态报告
  • 发行说明
  • 手册
  • 网络文章集锦
  • 笔记本支持报告
  • Port 开发者手册
  • 架构手册
  • 开发者手册
  • 中文 man 手册
  • 文章
  • 书籍
  • FreeBSD 中文期刊
  • 编辑日志
  • 2025-123 下游项目
    • FreeBSD 发布工程:新主管上任
    • GhostBSD:从易用到挣扎与重生
    • BSD Now 与将来
    • 字符设备驱动教程(第三部分)
    • 学会走路——连接 GPIO 系统
    • FreeBSD 中对 SYN 段的处理
    • FreeBSD 2024 年秋季峰会
  • 2024-1112 虚拟化
    • 字符设备驱动程序教程(第二部分)
    • 面向 Linux 和 Windows 用户的 bhyve
    • Xen 与 FreeBSD
    • Wifibox:一种嵌入式虚拟化无线路由器
    • 嵌入式 FreeBSD:Fabric——起步阶段
    • DGP:一种新的数据包控制方法
    • 会议报告:我在都柏林的 EuroBSDCon 体验
  • 2024-0910 内核开发
    • 字符设备驱动程序教程
    • VPP 移植到了 FreeBSD:基础用法
    • 利用 Kyua 的 Jail 功能提升 FreeBSD 测试套件的并行效率
    • FreeBSD 上的 Valgrind
    • 嵌入式 FreeBSD:探索 bhyve
    • TCP/IP 历险记:FreeBSD TCP 协议栈中的 Pacing
    • 实用软件:实现无纸化(Paperless)
  • 2024-0708 存储与文件系统
    • FreeBSD 中的 NVMe-oF
    • FreeBSD iSCSI 入门
    • 使用 ZFS 原生加密保护数据
    • 嵌入式 FreeBSD:打造自己的镜像
    • TCP LRO 简介
    • 基于 Samba 的时间机器备份
  • 2024-0506 配置管理对决
    • 基本系统中的 mfsBSD
    • rdist
    • Hashicorp Vault
    • 在 GitHub 上向 FreeBSD 提交 PR
    • 悼念 Mike Karels
    • 2024 年 5-6 月来信
    • 嵌入式 FreeBSD 面包板
    • TCP/IP 历险记:TCP BBLog
    • 实用软件:开发定制 Ansible 模块
  • 2024-0304 开发工作流与集成
    • FreeBSD 内核开发工作流程
    • FreeBSD 与 KDE 持续集成(CI)
    • 更现代的内核调试工具
    • 从零开始的 ZFS 镜像及 makefs -t zfs
    • 提升 Git 使用体验
  • 2024-0102 网络(十周年)
    • FreeBSD 中的 RACK 栈和替代 TCP 栈
    • FreeBSD 14 中有关 TCP 的更新
    • if_ovpn 还是 OpenVPN
    • SR-IOV 已成为 FreeBSD 的重要功能
    • FreeBSD 接口 API(IfAPI)
    • BATMAN:更优的可移动热点网络方式
    • 配置自己的 VPN——基于 FreeBSD、Wireguard、IPv6 和广告拦截
    • 实用软件:使用 Zabbix 监控主机
  • 2023-1112 FreeBSD 14.0
    • LinuxBoot:从 Linux 启动 FreeBSD
    • FreeBSD 容器镜像
    • 现在用 Webhook 触发我
    • 新的 Ports 提交者:oel Bodenmann (jbo@freebsd.org)
  • 2023-0910 Port 与软件包
    • 回忆录:与 Warner Losh(@imp)的访谈
    • 在你自己的仓库中定制 Poudriere 源
    • Wazuh 和 MITRE Caldera 在 FreeBSD Jail 中的使用
    • PEP 517
    • CCCamp 2023 旅行报告
  • 2023-0708 容器与云
    • 在 Firecracker 上的 FreeBSD
    • 使用 pot 和 nomad 管理 Jail
    • 会议报告:C 与 BSD 正如拉丁语与我们——一位神学家的旅程
    • 抒怀之旅:与 Doug Rabson 的访谈
    • 基于 Jail 的广告拦截教程
    • 我们收到的来信
  • 2023-0506 FreeBSD 三十周年纪念特刊
    • CheriBSD 近十多年的历程
    • AArch64:成为 FreeBSD 新的一级架构
    • 岁月如梭:我个人的时间线
    • 安装 FreeBSD 1.0:回顾 30 年前
    • ZFS 是如何进入 FreeBSD 的呢?
    • 我不是来自约克郡的,我保证!
    • 回忆录:采访 David Greenman Lawrence
    • FreeBSD 和早期的 Unix 社区
    • 早期的 FreeBSD 移植
    • FreeBSD 30 周年:成功的秘诀
    • FreeBSD 在日本:回忆之旅与今日之实
  • 2023-0304 嵌入式
    • CheriBSD port 和软件包
    • 让我们来试试 ChatGPT
    • GPU 直通
  • 2023-0102 构建 FreEBSD Web 服务器
    • ZFS 的原子 I/O 与 PostgreSQL
    • 虚拟实验室——BSD 编程研讨会
    • ZFS 简介
    • 会议报告:落基山庆祝女性计算机科学家
    • 进行中的工作/征求反馈:数据包批处理
    • 基金会与 FreeBSD 桌面
  • 2022-1112 可观测性和衡量标准
    • 在 FreeBSD 的 DDB 内核调试器中编写自定义命令
    • DTrace:老式跟踪系统的新扩展
    • 基于证书的 Icinga 监控
    • 活动监控脚本(activitymonitor.sh)
    • 实用 IPv6(第四部分)
    • EuroBSDCon 会议报道
    • 实用 Port:Prometheus 的安装与配置
    • 书评:《用火解决问题:管理老化的计算机系统(并为现代系统保驾护航)》Kill It with Fire: Manage Aging Computer Systems (and Future Proof Modern Ones)
  • 2022-0910 安全性
    • CARP 简介
    • 重构内核加密服务框架
    • PAM 小窍门
    • SSH 小窍门
    • 实用 IPv6(第三部分)
    • 书评:Understanding Software Dynamics(深入理解软件性能——一种动态视角)—— Richard L. Sites 著
    • 访谈:保障 FreeBSD 安全性
    • MCH 2022 会议报告
  • 2022-0708 科研、系统与 FreeBSD
    • 在 FreeBSD 上构建 Loom 框架
    • 教授本科生 Unix 课程
    • FreeBSD 入门研讨会
    • 实用 IPv6(第二部分)
    • 在 2022 年及以后推广 FreeBSD
    • 进行中的工作/征求反馈:Socket 缓冲区
    • FreeBSD 开发者峰会报告
    • 支持 Electromagnetic Field 2022
  • 2022-0506 灾难恢复
    • 使用 FreeBSD 构建高弹性的私有云
    • LLDB 14 —— FreeBSD 新调试器
    • 实用 IPv6(第一部分)
    • 利用 netdump(4) 进行事后内核调试
    • 进行中的工作/征求反馈:FreeBSD 启动性能
    • 实用 Port:在 OpenZFS 上设置 NFSv4 文件服务器
  • 2022-0304 ARM64 是一级架构
    • FreeBSD/ARM64 上的数据科学
    • Pinebook Pro 上的 FreeBSD
    • 嵌入式控制器的 ACPI 支持
    • 进行中的工作/征求反馈:Lumina 桌面征集开发人员
    • 实用 Port:如何设置 Apple 时间机器
  • 2022-0102 软件与系统管理
    • 为 FreeBSD Ports 做贡献
    • 使用 Git 贡献到 FreeBSD Ports
    • CBSD:第一部分——生产环境
    • 将 OpenBSD 的 pf syncookie 代码移植到 FreeBSD 的 pf
    • 进行中的工作/征求反馈:mkjail
    • 《编程智慧:编程鬼才的经验和思考》(The Kollected Kode Vicious)书评
    • 会议报告:EuroBSDCon 2021 我的第一次 EuroBSDCon:一位新组织者的视角
  • 2021-1112 存储
    • 开放通道 SSD
    • 构建 FreeBSD 社区
    • 与完美操作系统同行 27 年
    • 进行中的工作/征求反馈:OccamBSD
    • 通过 iSCSI 导入 ZFS ZIL——不要在工作中这样做——就像我做的那样
  • 2021-0910 FreeBSD 开发
    • FreeBSD 代码审查与 git-arc
    • 如何为 FreeBSD 实现简单的 USB 驱动程序
    • 内核开发技巧
    • 程序员编程杂谈
  • 2021-0708 桌面/无线网
    • 通往 FreeBSD 桌面的直线路径
    • FreeBSD 13 中的人机接口设备 (HID) 支持
    • Panfrost 驱动程序
    • 用 Git 更新 FreeBSD
    • FreeBSD 的新面孔
    • 想给你的桌面加点佐料?
  • 2021-0506 安全
    • 七种提升新安装 FreeBSD 安全性的方法
    • copyinout 框架
    • 使用 TLS 改善 NFS 安全性
    • Capsicum 案例研究:Got
    • 对 Jail 进行安全扫描
  • 2021-0304 FreeBSD 13.0
    • 展望未来
    • FreeBSD 13.0 工具链
    • FreeBSD 13.0 中有新加载器吗?
    • TCP Cubic 准备起飞
    • OpenZFS 中的 Zstandard 压缩
    • 会议报告:FreeBSD 供应商峰会
    • Git 不够吗?
  • 2021-0102 案例研究
    • Tarsnap 的 FreeBSD 集群
    • BALLY WULFF
    • Netflix Open Connect
    • FreeBSD 的新面孔
    • 写作学者的 FreeBSD
    • 在世界之巅
  • 2020-1112 工作流/持续集成(CI)
    • FreeBSD Git 快速入门
    • 使用 syzkaller 进行内核 Fuzzing
    • Mastering Vim Quickly 书评
    • 线上会议实用技巧
    • 在控制台上进行网络监控
  • 2020-0910 贡献与入门
    • 采访:Warner Losh,第 2 部分
    • 代码审查
    • 撰写良好的提交消息
    • 如何在不是程序员的情况下做出贡献——成为 FreeBSD 译者
    • 如何成为文档提交者
    • 谷歌编程之夏
    • 为 FreeBSD 期刊撰写文章
    • 你为什么使用 FreeBSD
    • FreeBSD 的新面孔
  • 2020-0708 基准测试/调优
    • FreeBSD Friday
    • 采访:Warner Losh,第 1 部分
    • 构建和运行开源社区
    • 在 FreeBSD 上轻松搭建我的世界(Minecraft)服务器
    • FreeBSD 的新面孔
  • 2020-0506 网络性能
    • 内核中的 TLS 卸载
    • 访谈:Michael W Lucas
    • FreeBSD 桌面发行版
    • 使用 Poudriere 进行 Port 批量管理
    • FreeBSD 的新面孔
由 GitBook 提供支持
LogoLogo

FreeBSD 中文社区(CFC) 2025

在本页
  • 使用 Kyua 组织测试
  • 并行性和 Jail
  • 执行环境概念
  • 隐式参数与分层 Jail
  • kldload 问题
  • execenvs 和 WITHOUT_JAIL
  • 入门示例
  • 进一步阅读
在GitHub上编辑
导出为 PDF
  1. 2024-0910 内核开发

利用 Kyua 的 Jail 功能提升 FreeBSD 测试套件的并行效率

上一页VPP 移植到了 FreeBSD:基础用法下一页FreeBSD 上的 Valgrind

最后更新于24天前

  • 原文地址:

  • 作者:Igor Ostapenko

测试是一个广泛的概念 如今,无论采用何种方法、学术观点或特定情境,很难抗拒这样一个简单愿望:不要让最终用户代替我们进行测试。即使是一个简单的错误,也可能在多个方面对业务造成重大损害:声誉、上市时间、转化率、业务扩展等。行业已经从依赖复杂的手动检查发布演变为尽可能拥抱自动化。自动化测试提供了许多优势:缩短测试周期、更频繁的反馈、对结果的额外信心、减少对变更的恐惧等。尽管自动化测试是开发流程中的重要组成部分,但它仅是改善软件交付的众多实践之一。

使用 Kyua 组织测试

FreeBSD 测试套件通常位于 /usr/tests,其基础设施基于 Julio Merino 创建的测试框架 Kyua。Kyua 提供了一种富有表现力的测试套件定义语言、安全的运行时引擎以及强大的报告生成能力。测试可以使用任意工具编写,也可以不依赖特定的库。测试套件中的单元和集成测试通常使用诸如 、、 或 等库。

Kyua 的核心概念层次结构如下:测试套件 > 测试程序 > 测试用例。

一个测试套件将多个二进制文件(测试程序)分组为一个具有单一名称的集合。测试套件通过 Lua 脚本描述,通常保存为特殊的 。让我们来看以下已存在的文件示例:

# cat -n /usr/tests/sys/kern/Kyuafile
       1  -- Automatically generated by bsd.test.mk.
       2
       3  syntax(2)
       4
       5  test_suite(“FreeBSD”)
       6
       7  atf_test_program{name=”basic_signal”, }
[skipped]
       34  atf_test_program{name=”sonewconn_overflow”, required_programs=”python”, required_user=”root”, is_exclusive=”true”}
       35  atf_test_program{name=”subr_physmem_test”, }
       36  plain_test_program{name=”subr_unit_test”, }
[skipped]
       45  atf_test_program{name=”unix_seqpacket_test”, timeout=”15”}
       46  atf_test_program{name=”unix_stream”, }
       47  atf_test_program{name=”waitpid_nohang”, }
       48  include(“acct/Kyuafile”)
       49  include(“execve/Kyuafile”)
       50  include(“pipe/Kyuafile”)

每个 Kyuafile 只描述其所在目录中的测试二进制文件。然而,/usr/tests 的结构设计方式使得每个测试目录都会显式包含其子目录中的测试文件,如第 48、49 和 50 行所示。因此,在该目录运行测试时,将会执行 sys/kern 子树中的所有测试,包括 sys/kern/acct、sys/kern/execve 和 sys/kern/pipe 中的测试:

# kyua test -k /usr/tests/sys/kern/Kyuafile

第 1 行表明,FreeBSD 测试套件中的 Kyuafile 并不是手动创建的。相反,与 FreeBSD 构建系统的大多数组件一样,该过程通过 Makefile 自动处理,Makefile 构建测试程序并生成相应的 Kyuafile。要详细了解该过程,可以将生成的 /usr/tests/sys/kern/Kyuafile 与其源文件 /usr/src/tests/sys/kern/Makefile 进行比较——这是一种直观的方法。

未在 Kyuafile 中注册的测试程序将不会被 Kyua 识别,因此也不会被执行。

Kyuafile 中未显式提及测试用例(test cases),因为测试用例是在更低的层级(即测试程序内部)定义的,并需要所使用的库的支持。通常,将多个相似的测试(即测试用例)分组到一个测试程序的二进制文件中会比创建多个独立的测试程序更为方便。对于普通测试程序,通常仅提供一个测试用例,通常根据 main() 函数命名为“main”。相比之下,基于 ATF 库的测试可以报告多个测试用例。在 Kyua 中,我们通常称为“测试”的内容被称为“测试用例”,并被视为执行的基本单元。因此,尽管 Kyuafile 中描述的测试套件可能看起来只引用了一个测试程序,但它可能包含数十个或更多的测试用例。kyua list 命令会以 <测试程序>:<测试用例> 的格式列出测试用例,这种格式也可以用于其他命令,例如单独运行特定的测试用例:

# cd /usr/tests/sys/kern
# kyua test unix_dgram:basic

每个测试用例都可以包含可选的元数据属性,以键/值对的形式存在,用于修改 Kyua 针对该特定测试用例的行为。上面的 Kyuafile 示例展示了如何将相同的元数据应用于测试程序中的所有测试用例。示例中包含的属性如下:

  • timeout:允许更改默认超时时间(默认值为 300 秒)。

  • required_programs:如果所指定的二进制文件无论是通过完整路径还是在 PATH 环境变量中未找到,该测试用例将被标记为跳过,并显示相应的消息。

  • required_user="root":如果 Kyua 未以 root 权限运行,则跳过该测试;而 required_user="unprivileged" 则确保测试在无 root 访问权限的情况下运行。

  • is_exclusive="true":指定该测试不能与其他测试同时运行。

并行性和 Jail

# kyua -v parallelism=8 test

测试用例需要独占访问共享资源时,应标记为 is_exclusive="true",以便 Kyua 知道不与其他测试并行运行。Kyua 的操作分为两个阶段。第一阶段运行所有非独占的测试用例,如果配置了并行性设置,这些测试可以并行执行。第二阶段顺序运行所有独占的测试用例。为了保持测试套件的高效性,最好避免添加新的独占测试,并尽量创建非独占的替代版本,否则测试套件可能会耗费过多时间来执行。

执行环境概念

在 15-CURRENT 版本中,Kyua 引入了一个新的概念——“执行环境”。该功能将在 14.2-RELEASE 中提供。

默认情况下,测试仍然按照之前的方式运行,即通过生成子进程——这种方式被称为主机执行环境。测试用例可以通过指定一个新的元数据属性 execenv,选择使用不同的执行环境。针对每个测试用例的一般步骤顺序已扩展,包括以下内容:

  1. 初始化执行环境

  2. 执行测试

  3. (可选)测试清理

  4. 清理执行环境

目前,Kyua 仅支持一种额外的执行环境——jail 环境。虽然可以为单个测试用例配置该环境,但以下示例展示了如何将 execenv 元数据属性应用于测试程序中的所有测试用例:

atf_test_program{name=”test_program”, execenv=”jail”}
atf_test_program{name=”test_program”, execenv=”jail”, execenv_jail_params=”vnet allow.raw_sockets”}

只要不同父 jail 中的子 jail 名称不冲突,并且每个 jail 都能拥有自己的 VNET 堆栈,我们就可以轻松地将测试(例如前面提到的网络测试)隔离到独立的 jail 中运行,并通过移除 is_exclusive 标志实现并行运行。具体效果取决于环境和配置,但有报告显示,在相同环境下,netpfil/pf 测试套件的运行速度提高了 4 至 5 倍,仅需几分钟就能完成,而非原来的半小时。

隐式参数与分层 Jail

由于测试用例及其可选清理例程分别在独立的子进程中运行,Kyua 会隐式地添加 persist 参数以保持临时 jail 存在,确保两个子进程都在同一个 jail 中运行。Kyua 会在“执行环境清理”步骤中删除临时 jail。

网络测试中常见的做法是生成 jail。这就引出了一个问题:是否允许已经运行在 jail 内的测试用例创建子 jail。从原则上讲,只要不超过系统限制,这是允许的。每个 jail 都有一个关于可创建子 jail 数量的限制。在 15-CURRENT 中引入了以下新的只读 sysctl 变量,用于提供这些信息:

# sysctl security.jail.children
security.jail.children.cur: 0
security.jail.children.max: 999999
# jail -c command=sysctl security.jail.children
security.jail.children.cur: 0
security.jail.children.max: 0

这表示不允许创建子 jail。显然,在这种条件下,尝试创建新 jail 的测试用例将会失败。为了解决这个问题,Kyua 通过添加另一个隐式参数来提供帮助,该参数允许最大数量的子 jail,这个数量是父 jail 最大限制减去 1。虽然可以通过测试用例中的 execenv_jail_params 元数据属性来配置这一点,但这似乎是一项繁琐且重复的工作。

以下公式阐明了 Kyua 如何创建临时 jails 以及如何通过元数据属性修改这一过程:

jail -qc name=<name> children.max=<parent_max-1> <test case defined params> persist

临时 jail 的名称来源于测试程序路径和测试用例名称。例如,测试用例 /usr/tests/sys/kern/unix_dgram:basic 将使用名为 kyua_usr_tests_sys_kern_unix_dgram_basic 的临时 jail。

kldload 问题

由于除了 prison0 外的所有 jail 都没有加载内核模块的权限,这会导致如果测试用例依赖于 jail 执行环境时的不便。

Kyua 的初衷是供开发人员和用户使用。这意味着系统管理员应能够在操作系统升级后运行测试套件,以确保一切正常工作。显然,这样的主机不是一个测试实验室,开发人员不能随意实验、破坏系统或引发故障。因此,测试应设计为避免干扰主机的正常操作,除非明确指示。这也是为什么 FreeBSD 测试套件有类似 allow_sysctl_side_effects 的配置变量来遵循这一方法。尽管该套件主要被视为开发工具,但许多现有的测试仍然遵循这一原则,通过检查所需的模块是否已加载,而不是隐式加载它。例如,如果防火墙的测试未被主机使用,却意外地影响了主机流量甚至使其无法访问,系统管理员会不满。

因此,推荐的策略是在测试用例中使用 kldstat -q -m <module-name> 来检查所需模块是否存在,如果模块未找到,则跳过测试。FreeBSD CI 的配置确保在运行测试套件之前,所有必要的模块已加载,所需的软件包已安装。

execenvs 和 WITHOUT_JAIL

提供了一个新的引擎配置变量——execenvs。默认情况下,它设置为一个包含所有支持的执行环境的列表:

# kyua config
architecture = aarch64
execenvs = host jail
parallelism = 1
platform = arm64
unprivileged_user = tests
# kyua -v execenvs=host test

如果系统在构建时没有启用 jail 支持,则仅会提供默认的主机执行环境。因此,任何需要 jail 执行环境的测试都将被跳过。

入门示例

# cat /usr/src/tests/sys/kern/test_program.sh
atf_test_case “case1” “cleanup”
case1_head()
{
atf_set descr 'Test that X does Y'
       atf_set require.user root
       atf_set execenv jail
       atf_set execenv.jail.params vnet allow.raw_sockets
}
case1_body()
{
       if ! kldstat -q -m tesseract; then
               atf_skip “This test requires tesseract”
       fi

       # 测试代码……
}
case1_cleanup()
{
       # 清除代码……
}

atf_init_test_cases()
{
       atf_add_test_case “case1”
}

在 Makefile 中添加一行即可完成该测试程序的配置:

# grep test_program /usr/src/tests/sys/kern/Makefile
ATF_TESTS_SH+= test_program

构建系统将会在脚本前添加 #!/usr/libexec/atf-sh 的 shebang 行,将脚本安装到 /usr/tests/sys/kern/test_program 并去掉 .sh 后缀,同时在 Kyuafile 中进行相应的注册:

# grep test_program /usr/tests/sys/kern/Kyuafile
atf_test_program{name=”test_program”, }

在单个测试程序中包含多个测试用例可能会导致“不要重复你自己”(Don’t Repeat Yourself, DRY)的情况。为了解决这个问题,可以将通用的元数据提升到 Kyuafile 中的测试套件级别,从而使其适用于整个测试程序,而无需为每个测试用例重复设置。然而,个别测试用例仍然可以在必要时覆盖这些属性:

# cat /usr/src/tests/sys/kern/test_program2.sh
atf_test_case “case2”
case2_head()
{
       atf_set descr 'Test that A does B'
}
case2_body()
{...}

atf_test_case “case3”
case3_head()
{
       atf_set descr 'Test that Foo does Bar'
       atf_set execenv.jail.params vnet allow.raw_sockets
}
case3_body()
{...}

atf_init_test_cases()
{
       atf_add_test_case “case2”
       atf_add_test_case “case3”
}

现在,主要的配置是在测试程序级别提供的:

# grep test_program2 /usr/src/tests/sys/kern/Makefile
ATF_TESTS_SH+= test_program2
TEST_METADATA.test_program2+= execenv=”jail”,execenv_jail_params=”vnet”

因此,Kyua 将在不同级别定义的元数据合并为以下内容:

# kyua list -k /usr/tests/sys/kern/Kyuafile -v test_program2
test_program2:case2 (FreeBSD)
    description = Test that A does B
    execenv = jail
    execenv_jail_params = vnet
test_program2:case3 (FreeBSD)
    description = Test that Foo does Bar
    execenv = jail
    execenv_jail_params = vnet allow.raw_sockets

要将现有的测试切换到 jail 执行环境,应该取反或移除 is_exclusive="true" 元数据属性。否则,该测试将无法从并行执行中受益。

进一步阅读

此外,审查现有基于 jail 的测试是如何编写和组织的也至关重要,以避免重复造轮子。位于 /usr/src/tests/sys/netpfil/pf 的 PF 测试套件是了解既定实践的一个重要来源。

虽然在现有代码中回溯性地添加测试可能是一项庞大的工作,但结合解决 bug 修复的测试,是提升 FreeBSD 测试套件以及整个项目的一个值得做的机会。


Igor Ostapenko 是一位 FreeBSD 贡献者,拥有广泛的软件开发经验,涉及的领域包括操作导航设备的系统、企业优化业务流程的解决方案、逆向工程、以及 B2B/B2C 创业公司等多个领域。

第 3 行指定了所使用语法的必要版本。第 5 行为测试套件设置了名称。通常,所有位于 /usr/tests/**/Kyuafile 的描述都会被收集到一个名为 FreeBSD 的测试套件中。如果某个二进制文件基于 ATF 库,它会通过 atf_test_program 进行注册,从而使 Kyua 能够利用 ATF 提供的功能和特性。如果测试程序不基于 Kyua 支持的库,而仅通过退出码传递结果,则会使用 plain_test_program 构造。此外,还有 tap_test_program,用于那些通过经典的 (TAP)协议传递结果的测试程序。

Kyua 可以通过配置实现测试用例的并行运行。默认情况下,parallelism 设置为 1,这意味着测试是按顺序运行的。该设置可以在 文件中调整,或作为选项指定:

然而,有些测试利用了 功能来处理其他方式难以复现的场景。例如,网络模块测试通常通过创建临时 jail,利用主机通过 对模块行为进行验证。这类测试必须标记为独占有以下几个原因:为了方便通常会重用相同的 jail 名称(但系统中的每个 jail 必须有唯一名称),主机端使用为演示用途分配的相同 IP 地址配置接口,可能导致共享路由表的冲突,以及其他相关问题。虽然这些问题可以由测试用例自身解决,但这样会显著增加测试编写者和维护者的复杂性,并且某些问题可能在没有外部干预的情况下无法解决。这时,最新版本的 Kyua 发挥了作用。

此配置使 Kyua 为 test_program 中的每个测试用例提供一个临时的 jail 来执行。如果某个测试用例声明了清理例程,该例程也将在相同的 jail 中执行。Kyua 使用 创建这些 jail,测试用例可以通过一个名为 execenv_jail_params 的新元数据属性传递额外的参数:

显然,上述内容指的是层级中的最高 jail,称为 prison0。根据当前值和最大值,系统最多可以创建近百万个 jail。当使用 创建新 jail 时,会应用以下默认配置:

这个变量可以通过 进行操作,也可以作为 命令行工具的选项来指定。例如,以下命令将仅执行基于主机的测试,并跳过所有其他测试:

以下示例基于 ,演示了如何在测试用例级别配置 jail 环境。它还提醒了 root 用户权限的重要性。

需要注意的是,ATF 和 Kyua 之间元数据属性命名约定的关键区别——点(execenv.jail.params)与下划线(execenv_jail_params)。此外,名称本身可能会略有不同,可以对比 和 的手册页面。

FreeBSD 测试套件的入口点在 中有描述。对于测试作者,以下 wiki 页面是一个有价值的起点:。

官方的 是了解历史背景、设计理念和功能概述的极好资源。有关执行环境的详细信息可以在 和 的手册页面中找到。

Enhancing FreeBSD Test Suite Parallelism with Kyua’s Jail Feature
atf-c(3)
atf-c++(3)
atf-sh(3)
pytest
kyuafile(5)
Test Anything Protocol
kyua.conf(5)
jail(8)
epair(4)
jail(8)
jail(8)
kyua.conf(5)
kyua(1)
atf-sh(3)
kyuafile(5)
atf-test-case(4)
tests(7)
https://wiki.freebsd.org/TestSuite/DeveloperHowTo
Kyua wiki
kyua.conf(5)
kyuafile(5)