storage(sml 插件)测试

概述

仓是 openubmc/plugins/storage,现网 require 名是 hwproxy.plugins.sml(不是 storage)。快照为 init.lua + cmds.lua + cmd_work.lua。

这是模式 C:Worker 线程 + sml.core 厂商库。本目录证明 能 require + has_cmd 分发、生产 bootstrap 没有 m.new 时会失败,以及 UT 注入 new 之后 init_register 写 self.wr_id 会被 mc.class seal 拦住。不假装 RAID 命令能跑通。

共享宿主见 ../README.md。应用 Lua 见 app/README.md。

C 对照:init.lua 是 mc.class();cmds.lua 导出 CMD 函数表;cmd_work.lua 是 Worker 循环,不是 Chip has_cmd 入口。

目录结构

storage/
├── README.md
├── test_sml_plugin.cpp
├── app/                                  # → app/README.md
│   └── test_sml.lua
├── stubs/                         # 非 libmcpp:仅 sml.core(C 扩展桩)
│   └── sml/core.lua
└── hwproxy/plugins/sml/
    ├── init.lua
    ├── cmds.lua
    └── cmd_work.lua
本目录文件 生产来源
hwproxy/plugins/sml/init.lua plugins/storage/include/hwproxy/plugins/sml/init.lua
hwproxy/plugins/sml/cmds.lua plugins/storage/include/hwproxy/plugins/sml/cmds.lua
hwproxy/plugins/sml/cmd_work.lua plugins/storage/include/hwproxy/plugins/sml/cmd_work.lua

禁止改测试拷贝。生产更新后三份一起拷。

测试文件说明

cmds.lua 共 75 个 CMD.* 入口(RAID 注册、PD/LD/电池、升级、SMART 等)。本目录不逐条跑厂商库。

用例 测什么
unknown_command_returns_false require('hwproxy.plugins.sml') 成功 + has_cmd 为假 → 宿主 HAS_ERR
known_command_without_new_hits_host_gap get_ctrl_info 为真命令;生产 _load_chip_plugin 未 m.new,ctor 未跑 → HAS_ERR
known_commands_without_new_all_hit_host_gap get_ctrl_pd_list / get_pd_info / get_ld_info / get_battery_info / register_controller 命令名存在且同样缺 m.new
known_command_after_new_hits_seal_gap UT 注入 Class.new 后 ctor 已跑;init_register 写 self.wr_id 被 seal 拦住 → HAS_ERR
应用 Lua app_lua_ctrl_info

未点到:cmd_work.lua 循环 / sml.core 真实结构体 / MCTP writeread / 任何 CMD.* 成功路径。

测试统计

测试文件 用例数
test_sml_plugin.cpp 5(分发 + 缺 m.new + 高频命令 ABI + 注入 new 后被 seal 拦住 + 1 个应用 Lua 文件)

被测模块功能说明

存储 RAID 卡 OOB 管理(I2C / MCTP)。业务 PluginRequest(..., 'sml', cmd, ctrl_id, ...)。现网 run_cmd 会 init_register 拉 Worker,把命令 send 到 cmd_work.lua,再 skynet.wait 等回调。storage 仓其余 src/lualib/** 不是 Chip 插件,不在本 UT。

构建和运行

meson test -C builddir test_sml_plugin --verbose
./builddir/tests/plugins/test_sml_plugin --gtest_filter='sml_plugin_test.*'

注意事项

  • meson / gtest 目标名是 test_sml_plugin,目录名是 storage,plugin_name() 必须是 sml。
  • 加载 cmds.lua 需要:sml.core 在 storage/stubs/sml/core.lua(必须保留——生产是 storage C 扩展 sml/core.so,UT 不能拷 Lua 也不能轻量链 .so,见 ../README.md「sml.core 为何必须保留」);mctp_lib 在 SetUp 时从 plugins/mctpd 拷入;sd_bus 在 libmcpp_stubs/;worker.core 走正式 mcskynet。
  • 独有缺口(bootstrap / libmcpp):生产 _load_chip_plugin 没有 plugin = m.new(work_objects)。sml_plugin_instantiated_test 只在测试拷贝的 bootstrap 末尾包一层 Class.new({bus_object_name=...})。
  • C 对照:Class.new(app) ≈ malloc + ctor。mc.class 在 ctor 结束后 seal 实例,之后不能给 self 加新字段(cannot add private field)。sml 的 init_register 要写 wr_id / work 等,:init() 要写 cbs,在当前 mc.class 下都会失败。生产侧需要在 ctor 里预声明这些字段,或不用 seal。本 UT 不改 plugins 仓。
  • skynet.wait 仍被注入成立刻 error,防止以后走到 Worker 循环时空转。
  • 独有缺口(产品路径):整段 BusLock 下 Worker 另线程再 I2C 会死锁;真 worker.core 与 sml.core.so 本 UT 不链。
  • 不要为凑覆盖率给 75 个 CMD.* 加空测试。