news 2026/9/17 14:10:48

connectedhomeip YAML 测试的 Pseudo-cluster(伪集群)命令参考:Matter 测试驱动基础设施解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
connectedhomeip YAML 测试的 Pseudo-cluster(伪集群)命令参考:Matter 测试驱动基础设施解析

connectedhomeip YAML 测试的 Pseudo-cluster(伪集群)命令参考:Matter 测试驱动基础设施解析

【免费下载链接】connectedhomeipMatter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.项目地址: https://gitcode.com/GitHub_Trending/co/connectedhomeip

Pseudo-cluster(伪集群)是 connectedhomeip(Matter SDK)YAML 集成测试框架中的一类特殊"集群":它们不通过 Matter 协议在线路上传输,而是在测试运行器进程内直接执行,用于完成配网、等待、发现、日志、文件系统操作等测试步骤,是编写可运行 YAML 测试套件的事实标准设施。本文以官方生成的命令参考文档 yaml_pseudocluster.md 为主体骨架,结合 pseudo_clusters 目录下的完整实现源码与真实测试套件用法,系统讲解六大伪集群的全部命令、参数类型、可选标记,以及伪集群从定义、文档生成到运行时调度分发的完整机制,让读者既能照表编写 YAML 测试,也能深入理解其底层实现原理。

什么是 Pseudo-cluster,为什么 YAML 测试需要它

在 Matter 的 YAML 测试模型中,每个测试步骤通常是一个"命令":cluster指定集群名,command指定命令名,运行器会将其编码为 Matter 交互协议(IM)请求发送给被测设备(DUT)并校验响应。然而,真实的测试流程中有大量步骤并不属于任何标准 Matter 集群,例如:

  • 用配对码(QR code payload)执行配网流程;
  • 等待固定毫秒数、等待设备重新上线;
  • 在本地网络中搜索可配网的设备;
  • 在测试机本地创建、比较、删除文件;
  • 向测试日志输出信息或向测试人员发起交互式提问。

这些步骤无法被编码为设备侧命令,因此测试框架引入了Pseudo-cluster这一抽象层:它在语义上仍然以"集群 + 命令"的形式出现在 YAML 文件中,但实际执行时由测试运行器在进程内直接处理,不会发给任何设备。从源码结构看,这一层对应 pseudo_clusters 目录:每个伪集群是一个继承 PseudoCluster 的类,类名即集群名,类方法即命令名,通过 XML 定义声明命令签名。

当前仓库默认注册的伪集群共 7 个(见 pseudo_clusters.py 中的get_default_pseudo_clusters()),其中 6 个进入了官方命令参考文档:

伪集群名称集群 Code职责
CommissionerCommands0xFFF1FD04配网、取消配对、签发 NOC 链
DelayCommands0xFFF1FD02等待(设备上线、毫秒、消息、属性值)
DiscoveryCommands0xFFF1FD05mDNS 发现可配网设备/专员
EqualityCommands0xFFF1FD08布尔/有符号/无符号数值相等性断言
LogCommands0xFFF1FD01日志输出与人机交互提示
SystemCommands0xFFF1FD03启动/重启/复位测试装置、文件与 OTA 镜像操作

其余命令(如 WebRTC 相关的VerifyVideoStream等,见 webrtc.py)未进入文档表格。值得注意:伪集群的集群 Code 均落在0xFFF1FDxx厂商/测试保留区间内,与真实 Matter 集群 ID 隔离,避免命名与 ID 冲突。

命令参考文档是怎么生成的:定义即文档

文档 yaml_pseudocluster.md 的头部注释明确指出:该文件由脚本自动生成,禁止手工编辑。生成脚本为 generate_pseudo_cluster_doc_tables.py,其工作方式如下:

  1. 调用get_default_pseudo_clusters()拿到默认伪集群实例列表;
  2. 读取每个实例的definition属性——这是一段内嵌的 XML(格式与 ZAP 集群定义一致),用xml.etree.ElementTree解析;
  3. 遍历每个<command>及其<arg>子元素,提取nametypeoptional属性;
  4. 以 Markdown 表格形式写入docs/testing/yaml_pseudocluster.md

也就是说,伪集群的命令清单完全由源码中的 XML 定义驱动,文档只是这份定义的可读快照。因此,当你在仓库中看到文档与源码不一致时(例如文档中FindResponse只有supportsTcp一个布尔字段,而 discovery_commands.py 中实际已拆分为supportsTcpClientsupportsTcpServer),应以 XML 定义为事实依据——这正是本文件被设计为"自动生成、勿手工编辑"的原因。

下表汇总了各集群在官方文档中的命令、参数、参数类型与可选性标记("arg optional" 列中false表示必填,true表示可选)。

CommissionerCommands

commandargsarg typearg optional
PairWithCodenodeId
payload
discoverOnce
node_id
char_string
boolean
false
false
true
UnpairnodeIdnode_idfalse
GetCommissionerNodeId
GetCommissionerNodeIdResponsenodeIdnode_idfalse
GetCommissionerRootCertificate
GetCommissionerRootCertificateResponseRCACOCTET_STRINGfalse
IssueNocChainElements
nodeId
octet_string
node_id
false
false
IssueNocChainResponseNOC
ICAC
RCAC
IPK
octet_string
octet_string
octet_string
octet_string
false
false
false
false

DelayCommands

commandargsarg typearg optional
WaitForCommissioning
WaitForCommissioneenodeId
expireExistingSession
node_id
bool
false
true
WaitForMsmsint16ufalse
WaitForMessageregisterKey
message
char_string
char_string
false
false

DiscoveryCommands

commandargsarg typearg optional
FindCommissionable
FindCommissionableByShortDiscriminatorvalueint16ufalse
FindCommissionableByLongDiscriminatorvalueint16ufalse
FindCommissionableByCommissioningMode
FindCommissionableByVendorIdvaluevendor_idfalse
FindCommissionableByDeviceTypevaluedevtype_idfalse
FindCommissioner
FindCommissionerByVendorIdvaluevendor_idfalse
FindCommissionerByDeviceTypevaluedevtype_idfalse
FindResponsehostName
instanceName
longDiscriminator
shortDiscriminator
vendorId
productId
commissioningMode
deviceType
deviceName
rotatingId
rotatingIdLen
pairingHint
pairingInstruction
supportsTcp
numIPs
port
mrpRetryIntervalIdle
mrpRetryIntervalActive
mrpRetryActiveThreshold
isICDOperatingAsLIT
char_string
char_string
int16u
int16u
vendor_id
int16u
int8u
devtype_id
char_string
octet_string
int64u
int16u
char_string
boolean
int8u
int16u
int32u
int32u
int16u
boolean
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
true
true
true
true

EqualityCommands

commandargsarg typearg optional
BooleanEqualsValue1
Value2
boolean
boolean
false
false
SignedNumberEqualsValue1
Value2
int64s
int64s
false
false
UnsignedNumberEqualsValue1
Value2
int64u
int64u
false
false
EqualityResponseEqualsboolfalse

LogCommands

commandargsarg typearg optional
Logmessagechar_stringfalse
UserPromptmessage
expectedValue
char_string
char_string
false
true

SystemCommands

commandargsarg typearg optional
StartregisterKey
discriminator
port
minCommissioningTimeout
kvs
filepath
otaDownloadPath
endUserSupportLogPath
networkDiagnosticsLogPath
crashLogPath
char_string
int16u
int16u
int16u
char_string
char_string
char_string
char_string
char_string
char_string
true
true
true
true
true
true
true
true
true
true
StopregisterKeychar_stringtrue
RebootregisterKeychar_stringtrue
FactoryResetregisterKeychar_stringtrue
CreateOtaImageotaImageFilePath
rawImageFilePath
rawImageContent
char_string
char_string
char_string
false
false
false
CompareFilesfile1
file2
char_string
char_string
false
false
CreateFilefilePath
fileContent
char_string
char_string
false
false
DeleteFilefilePathchar_stringfalse

CommissionerCommands:在 YAML 里完成配网与证书签发

配网是绝大多数集成测试的前置步骤,CommissionerCommands 把"用配对码配网"这一操作抽象成了 YAML 命令。其核心命令语义如下:

  • PairWithCode:携带目标节点nodeId、配对码payload(Setup QR/Manual Pairing Code 字符串),可选的discoverOnce控制是否只发现一次后即开始配网。真实用法可参考 TestCommissionerNodeId.yaml,其中先用Administrator Commissioning集群的OpenBasicCommissioningWindow打开配网窗口,再由指定身份(identity: "beta")执行PairWithCode
  • Unpair:按nodeId取消配对、移除该节点所在的 fabric。
  • GetCommissionerNodeId / GetCommissionerNodeIdResponse:读取当前专员自身的节点 ID,响应以nodeId返回。典型用法见 TestCommissionerNodeId.yaml:GetCommissionerNodeId的响应值被saveAs: commissionerNodeIdAlpha保存,供后续步骤引用。
  • GetCommissionerRootCertificate / GetCommissionerRootCertificateResponse:获取专员根证书(RCAC,OCTET_STRING)。
  • IssueNocChain / IssueNocChainResponse:按给定的Elements(NOC 链元素,octet_string)与nodeId签发新的 NOC 链,响应返回NOCICACRCACIPK四个 OCTET_STRING。

需要注意,源码定义 commissioner_commands.py 中还包含文档未收录的EstablishPASESession(参数nodeId+payload),用于显式建立 PASE 会话,说明 XML 定义是此类命令最权威的清单来源。

DelayCommands:测试流程中的"时间控制"

集成测试常常需要等待异步事件(如设备重启后重新上线),DelayCommands 提供四个等待原语:

  • WaitForCommissioning:无参数,等待配网流程完成。
  • WaitForCommissionee:等待指定nodeId的节点作为已配网设备出现;可选的expireExistingSession为 true 时使既有会话过期。真实用法见 TestArmFailSafe.yaml:设备执行SystemCommands.Reboot之后,紧接着用WaitForCommissionee等待其重新被检索到。
  • WaitForMs:休眠ms(int16u)毫秒。其实现(delay_commands.py 中的WaitForMs)先刷新 stdout,再执行await asyncio.sleep(int(duration_in_ms) / 1000)
  • WaitForMessage:通过registerKeymessage两个 char_string 参数等待一条注册消息(由 AccessoryServerBridge 机制实现跨进程消息同步)。

源码定义中还包含文档未收录的WaitForAttributeValue(参数attributeexpectedValueexpectedDurationMsclusterendpoint)。该命令的实现在 delay_commands.py 中值得单独一提:它以 100ms 为间隔轮询读取属性,直到值等于期望值或超过expectedDurationMs + valueWaitExtraDurationMs(默认 250ms)的超时窗口;轮询过程中会忽略中间态网络/设备错误(设备可能临时不可达后自愈),并将最近 10 次尝试的历史记录进超时异常信息,便于排障。

DiscoveryCommands:在测试内驱动 mDNS 发现

发现类命令用于在测试中触发 mDNS 发现并校验发现响应,其命令族可划分为两组:

搜索可配网设备(Commissionable)FindCommissionable(无过滤)、按短/长 discriminator(int16u)、按配网模式(FindCommissionableByCommissioningMode)、按 Vendor ID(vendor_id)、按设备类型(devtype_id)过滤的五个变体。

搜索专员(Commissioner)FindCommissionerFindCommissionerByVendorIdFindCommissionerByDeviceType

统一响应FindResponse携带极其丰富的字段,覆盖 Matter 配网发现的全部 TXT 记录:主机名、实例名、长短 discriminator、Vendor/Product ID、配网模式(int8u)、设备类型、设备名、rotatingId 及其长度、pairingHint/pairingInstruction、TCP 支持标志、IP 数量、端口,以及仅 ICD/LIT 场景需要的mrpRetryIntervalIdlemrpRetryIntervalActivemrpRetryActiveThresholdisICDOperatingAsLIT(后四个可选)。

该伪集群被发现测试套件大量使用:TestDiscovery.yaml 从第 94 行起连续二十余个步骤调用DiscoveryCommands,例如:

- label: "Check Instance Name" cluster: "DiscoveryCommands" command: "FindCommissionable" response: values: - name: "instanceName" saveAs: deviceInstanceNameBeforeReboot constraints: minLength: 16 maxLength: 16 isUpperCase: true isHexString: true

该示例展示了伪集群命令与 YAML 测试框架的完整交互:调用FindCommissionable后,响应值可被saveAs保存为运行时变量,并可用constraints(如长度、大小写、十六进制校验)对发现结果做强校验;后续步骤还可以用FindCommissionableByLongDiscriminator(value 引用变量discriminator)、FindCommissionableByShortDiscriminatorFindCommissionableByCommissioningMode等分别校验_L_S_CM等 mDNS 服务子类型,实现对 TXT 记录逐字段的断言(见 TestDiscovery.yaml)。

EqualityCommands:纯本地数值比较断言

当测试需要"比较两个值是否相等"且结果要参与后续断言时,可以使用 EqualityCommands——它是一个完全在本地执行的比较器,不涉及任何网络交互:

  • BooleanEquals(Value1/Value2,boolean)→ 返回EqualityResponse.Equals(bool);
  • SignedNumberEquals(Value1/Value2,int64s)→ 有符号 64 位整数比较;
  • UnsignedNumberEquals(Value1/Value2,int64u)→ 无符号 64 位整数比较。

其实现(equality_commands.py)非常直接:Compare(request)从参数列表中提取Value1/Value2并返回value1 == value2,三个命令都把它包装进{'value': {'Equals': ...}}响应中。命令名称的选择(区分布尔、有符号、无符号)是为了让解析器能按正确的类型语义解释传入的字面量。

LogCommands:日志输出与人工交互

  • Log:向测试日志输出message(char_string),实现为空操作(日志由运行器统一记录)。
  • UserPrompt:向测试人员展示message并等待输入;可选的expectedValue提供预期答案。其实现(log_commands.py)在提供了expectedValue时会调用input()阻塞读取用户输入,并把输入值作为expectedValue返回,供 YAML 步骤继续断言。

源码中还有文档未收录的PromptWithResponse(参数message、可选placeHolderparseStr)及其响应PromptResponsePromptWithResponse在运行器中走专门分支处理(见下节),并支持parseStr=true时用ast.literal_eval将用户输入解析为字面量(数字、布尔等),实现"输入即数据"。另外,运行器通过PseudoClusters.is_manual_step()(pseudo_clusters.py)将LogCommands.UserPrompt识别为"人工步骤",触发step_manual钩子,确保人工交互步骤在自动化与人工两种运行模式下都有明确的处理路径。

SystemCommands:测试装置的生命周期与文件操作

SystemCommands 是支撑"多设备/重启/OTA/文件对比"类测试的关键伪集群,几乎所有复杂测试套件都会用到它。其命令分四类:

装置生命周期(配合 AccessoryServerBridge,见 accessory_server_bridge.py):

  • Start:启动一个测试装置实例。全部 10 个参数均可选:registerKey(实例注册名)、discriminator(int16u)、port(int16u)、minCommissioningTimeout(int16u)、kvs(KVS 存储路径)、filepathotaDownloadPath(OTA 下载目录)、endUserSupportLogPathnetworkDiagnosticsLogPathcrashLogPath(各类日志落盘路径)。源码定义中还有文档未收录的traceDecode(int8u)。
  • Stop / Reboot / FactoryReset:均以可选的registerKey指定目标实例,分别执行停止、重启与恢复出厂设置。

文件与镜像操作

  • CreateOtaImage:由rawImageFilePath+rawImageContent生成 OTA 镜像并写入otaImageFilePath(三者均为必填 char_string),用于构造测试用 OTA 镜像。
  • CompareFiles:对比file1file2两个文件内容。
  • CreateFile / DeleteFile:在测试机本地创建(filePath+fileContent)或删除文件,常用于准备/清理诊断日志等测试产物。

真实用例遍布多个套件:OTA 传输测试 OTA_SuccessfulTransfer.yaml 中用SystemCommands控制装置并准备镜像;TestDiagnosticLogs.yaml 中用Start配置networkDiagnosticsLogPath/crashLogPath并用CompareFiles/CreateFile校验日志输出;TestArmFailSafe.yaml 中一个典型的重启流程步骤是:

- label: "Reboot target device" cluster: "SystemCommands" command: "Reboot"

紧随其后的DelayCommands.WaitForCommissionee则确保设备重启后重新上线,两个伪集群协同完成了"重启并等待恢复"这一常见测试模式。

参数类型约定速查

伪集群命令参数使用的类型与 Matter IDL/ZAP 类型体系一致,整理如下(可在各集群 XML 定义中逐一核对):

类型含义
node_id64 位节点 ID
char_string字符串
boolean / bool布尔值
octet_string / OCTET_STRING字节串(十六进制表示)
int8u / int16u / int32u / int64u无符号 8/16/32/64 位整数
int64s有符号 64 位整数
vendor_id厂商 ID(16 位)
devtype_id设备类型 ID
any任意类型(如WaitForAttributeValue.expectedValue

arg optional列标记参数是否为可选:false为必填,true为可选。若命令有响应(response),响应命令与参数会以独立条目(如FindResponseEqualityResponse)出现在同一表格中。

运行时调度:Pseudo-cluster 如何被分派执行

理解伪集群的关键在于运行时的分派逻辑,它位于 runner.py 的run_step主循环中,对每个测试步骤依次判断:

  1. 若步骤被PseudoClusters.is_manual_step()判定为人工步骤(UserPromptVerifyVideoStream),走hooks.step_manual()分支;
  2. 否则若config.pseudo_clusters.supports(request)返回 true(即按request.cluster+request.command能在已注册伪集群中找到对应方法),则直接调用config.pseudo_clusters.execute(request, ...)在进程内执行;其中PromptWithResponse还有专门分支:先通过hooks.show_prompt()弹出交互界面,再按parseStr决定是否用ast.literal_eval解析输入;
  3. 只有上述都不命中时,步骤才会交给config.adapter.encode()编码为真实的 Matter 请求发送给设备。

PseudoClusters.execute()(pseudo_clusters.py)用inspect.signature检查目标命令方法签名,只注入方法声明接受的 kwargs(如WaitForAttributeValue需要的runnerconfig),并保证definitions这类正式参数被单独注入;命令返回的None会被规范化为空成功状态,返回 dict 则作为响应值进入后续的post_process_response断言流程。因此,伪集群命令的响应与真实设备响应在 YAML 断言层面完全等价,saveAsconstraintsvalue校验等能力对两者一视同仁。

如何扩展:自定义 Pseudo-cluster

伪集群机制是开放可扩展的。PseudoCluster 是一个抽象基类,其文档字符串给出了完整的自定义示例:继承PseudoCluster,声明name类属性(即 YAML 中的 cluster 名),把命令实现为async def方法(方法名即 command 名),可选地提供definitionXML 以获得自动的命令名/参数名校验:

class CustomCommand(PseudoCluster): name = 'CustomCommands' async def MyCustomMethod(self, request): pass

对应的 YAML 步骤为:

- label: "Call a custom method" cluster: "CustomCommands" command: "MyCustomMethod" arguments: values: - name: "MyCustomParameter" value: "this_is_a_custom_value"

若提供definitionXML(<cluster><code>0xFFF1FD00</code>...格式),运行器还能自动校验命令名与参数名是否与定义一致。自定义伪集群通过PseudoClusters.add()注册进集合,即可与内置伪集群一起参与supports()/execute()分派。

总结与实战建议

Pseudo-cluster 是 connectedhomeip YAML 测试框架"测试步骤即命令"抽象的关键支撑:它以标准集群的语法形态,在进程内完成配网、等待、发现、断言、日志、文件系统与装置生命周期等测试基础设施操作,使 YAML 测试套件能够表达完整的多设备、多身份、OTA、诊断日志等复杂场景。编写测试时:

  • 命令清单以官方参考文档 yaml_pseudocluster.md 为速查入口,以 pseudo_clusters/clusters 下的 XML 定义为最终依据(文档为脚本快照,可能与最新源码存在细微差异);
  • 直接参考 TestDiscovery.yaml、TestCommissionerNodeId.yaml、TestArmFailSafe.yaml、TestDiagnosticLogs.yaml、OTA_SuccessfulTransfer.yaml 等套件,可以看到伪集群命令与真实集群命令在同一 YAML 文件中无缝混排的实际范式;
  • 需要扩展测试能力时,遵循PseudoCluster基类契约实现自定义伪集群并注册即可,响应处理与断言机制无需任何改动。

【免费下载链接】connectedhomeipMatter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.项目地址: https://gitcode.com/GitHub_Trending/co/connectedhomeip

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 14:10:32

大华MLCDF7-T车载7寸触摸屏说明书:接线、协议与Linux适配

简介&#xff1a;《Dahua大华车载7寸触摸屏MLCDF7-T使用说明书》面向车载影音改装人员、车队设备维护者及车载录像机配套安装用户&#xff0c;用于解决触摸屏接线、安装与日常操作中的规范问题。资源包内仅1个PDF文件&#xff0c;约616KB&#xff0c;内容围绕前面板按键布局、1…

作者头像 李华
网站建设 2026/9/17 14:08:29

问卷设计避坑指南 —— 你的问卷可能从一开始就错了

问卷是实证研究中最常用的数据收集工具&#xff0c;但也是最容易出问题的环节。问卷设计得不好&#xff0c;收上来的数据就是垃圾&#xff0c;后面再怎么分析都没用。汇写&#xff08;https://www.huixielunwen.com/tool/graduationThesis&#xff09;提供了问卷设计功能帮你快…

作者头像 李华
网站建设 2026/9/17 14:05:20

Hydra配置管理:Python机器学习实验的可复现治理方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 14:01:33

Linux vi编辑器实战入门:模式切换与终端编辑核心技能

简介&#xff1a;本资源是一份面向Linux初学者与计算机专业学生的Vi编辑器实践教学材料&#xff0c;聚焦命令行文本编辑核心技能训练&#xff0c;解决新手在系统配置、代码编写及日常文件处理中因不熟悉Vi操作而效率低下的问题。资源为单文件PDF文档&#xff08;422KB&#xff…

作者头像 李华