mirror of
https://gitcode.com/JianFeeeee/homeagent-sdk.git
synced 2026-10-31 22:37:25 +00:00
refactor(sdk)!: 废除自定协议号,版本身份只由版本号本身承载
兼容性判据原有三处自造版本号,全部删除:
- procProtocolVersion(模板侧握手常量)
- shmVersion / shmOffVersion(共享段 header)
- unifiedVersion(SuperBlock)
为什么废除:语义版本变动频繁(修 bug、加字段),再要求人去升一个额外的号,
那个号必然漏升而腐烂。实证:ProtocolVersion 常量在多次布局变更里只升过一次,
而对应的守卫测试(TestProcTemplate_ShmLayoutMatchesKernel)长期处于失败状态
无人察觉 —— 它当时期望 shmStageFieldCount=18/shmVersion=1,实际已是 19/2。
取而代之的两个判据都是**结构的派生事实**,不需要谁记得去同步:
1. 主版本号:内核 meta.Version ↔ 插件 sdk.SDKVersion 的主版本段比对。
主版本跃迁正是破坏性变更的定义(1.0.0 从 C ABI 改子进程即属此列),
所以它天然是正确分界。
2. field_count:StageContext 描述符个数,决定标志位基址。
顺带修正了 shmFlagsOff:原实现用本插件的编译期常量推算标志位基址,
内核加字段时会静默错位。现改为从 header 读取内核下发的描述符个数。
SuperBlock 的 version 槽位保留(不动其余偏移),值不再写入也不再校验。
判据:TestProcTemplate_RejectsIncompatiblePeer(含 banned 列表,
防这些号被重新引入)。
This commit is contained in:
@ -26,6 +26,21 @@ func loadProcTemplate(t *testing.T) string {
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// extractShmFlagsOff 取出模板里 shmFlagsOff 函数的函数体,供断言其取值来源。
|
||||
func extractShmFlagsOff(t *testing.T, src string) string {
|
||||
t.Helper()
|
||||
const sig = "func shmFlagsOff() uint32 {"
|
||||
i := strings.Index(src, sig)
|
||||
if i < 0 {
|
||||
t.Fatal("模板缺少 shmFlagsOff()")
|
||||
}
|
||||
rest := src[i+len(sig):]
|
||||
if j := strings.Index(rest, "\n}"); j >= 0 {
|
||||
return rest[:j]
|
||||
}
|
||||
return rest
|
||||
}
|
||||
|
||||
// stripComments 去掉源码中的注释(用空白填充以保持偏移),只留可执行代码。
|
||||
func stripComments(t *testing.T, src string) string {
|
||||
t.Helper()
|
||||
@ -218,17 +233,18 @@ func TestProcTemplate_ShmLayoutMatchesKernel(t *testing.T) {
|
||||
|
||||
// 与内核 shm.go 的 offXxx 常量对齐(值比较,不依赖 gofmt 的对齐空白)
|
||||
layout := map[string]string{
|
||||
"shmOffMagic": "0",
|
||||
"shmOffVersion": "4",
|
||||
"shmOffArenaBase": "8",
|
||||
"shmOffArenaCap": "12",
|
||||
"shmOffArenaUsed": "16",
|
||||
"shmOffCtxBase": "20",
|
||||
"shmOffSeq": "24",
|
||||
// 与内核 stageFieldCount / sliceSize 对齐
|
||||
"shmStageFieldCount": "18",
|
||||
"shmOffMagic": "0",
|
||||
"shmOffFieldCount": "4",
|
||||
"shmOffArenaBase": "8",
|
||||
"shmOffArenaCap": "12",
|
||||
"shmOffArenaUsed": "16",
|
||||
"shmOffCtxBase": "20",
|
||||
"shmOffSeq": "24",
|
||||
// 与内核 stageFieldCount / sliceSize 对齐。
|
||||
// 注意:这里不校验人工版本号 —— 它已被删除,布局一致性
|
||||
// 改由描述符个数这种派生事实校验(见下方全局规约断言)。
|
||||
"shmStageFieldCount": "19",
|
||||
"shmSliceSize": "8",
|
||||
"shmVersion": "1",
|
||||
}
|
||||
constRe := func(name, want string) bool {
|
||||
// gofmt 会对齐常量块,故容许 name 与 = 之间有任意空白
|
||||
@ -241,6 +257,26 @@ func TestProcTemplate_ShmLayoutMatchesKernel(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 布局必须自描述:标志位基址由内核下发的描述符个数推出,
|
||||
// 不能用本插件的编译期常量。否则内核加字段时会静默错位。
|
||||
if !strings.Contains(src, "func shmFieldCount()") {
|
||||
t.Error("模板缺少 shmFieldCount():标志位基址必须从 header 读取,不能自行推算")
|
||||
}
|
||||
flagsOff := extractShmFlagsOff(t, src)
|
||||
if strings.Contains(flagsOff, "shmStageFieldCount") {
|
||||
t.Errorf("shmFlagsOff 不得使用编译期常量 shmStageFieldCount(应经 shmFieldCount() 从 header 读取):\n%s", flagsOff)
|
||||
}
|
||||
if !strings.Contains(flagsOff, "shmFieldCount()") {
|
||||
t.Errorf("shmFlagsOff 应基于 shmFieldCount():\n%s", flagsOff)
|
||||
}
|
||||
|
||||
// 不得再出现人工版本号(内核与模板都不应有)。
|
||||
for _, banned := range []string{"shmVersion", "shmOffVersion"} {
|
||||
if strings.Contains(src, banned) {
|
||||
t.Errorf("模板不得再有 %s:布局一致性由描述符个数校验,不靠人工版本号", banned)
|
||||
}
|
||||
}
|
||||
|
||||
// 字段枚举顺序:内核 stageField 的前若干项
|
||||
fieldOrder := []string{
|
||||
"fRawMessage = iota", "fUserID", "fGroupID", "fLLMText",
|
||||
@ -343,15 +379,24 @@ func TestProcTemplate_DispatchesRequestsConcurrently(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 协议与共享内存区域版本/魔数不匹配必须拒绝,不得半兼容运行。
|
||||
func TestProcTemplate_RejectsVersionMismatch(t *testing.T) {
|
||||
// 主版本与共享内存区域结构不匹配必须拒绝,不得半兼容运行。
|
||||
//
|
||||
// 注意:这里不再检查任何「协议版本」/「共享段版本」自定号 ——
|
||||
// 它们已废除。兼容性只认双方版本号的**主版本段**(跨主版本即破坏性变更),
|
||||
// 布局一致性由描述符个数把关。
|
||||
func TestProcTemplate_RejectsIncompatiblePeer(t *testing.T) {
|
||||
src := loadProcTemplate(t)
|
||||
// §13.1 起共享段合并为单一「统一区域」,魔数校验文案随之更新。
|
||||
for _, want := range []string{"协议版本不匹配", "共享段版本不匹配", "统一区域魔数不匹配"} {
|
||||
for _, want := range []string{"主版本不匹配", "字段数不匹配", "统一区域魔数不匹配"} {
|
||||
if !strings.Contains(src, want) {
|
||||
t.Errorf("握手应校验并拒绝 %q", want)
|
||||
}
|
||||
}
|
||||
// 自定版本号必须已彻底移除,否则会出现「谁负责升这个号」的腐烂面。
|
||||
for _, banned := range []string{"procProtocolVersion", "shmVersion", "unifiedVersion"} {
|
||||
if strings.Contains(src, banned) {
|
||||
t.Errorf("模板不得再有自定版本号 %s", banned)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 全平台统一产出 plugin.bin。
|
||||
|
||||
Reference in New Issue
Block a user