Files
HomeAgent/internal/agent/io/test/channel_contract_test.go
JianFeeeee 379300d89c test: 按模块导出接口重写黑盒判据(批次 7:agent-io / system / ipc / supervisor)
4 个文件全部在 `<module>/test/`,源码目录仍零 `_test.go`。
共 15 条判据,只调导出接口,输入 → 可观察输出。

## internal/agent/io —— OutputCapability

    TestSupportsSingleAndCombinedFlags  位标志的「任一位命中」语义
    TestCapabilityStringListsFlags      String 列出已置位能力名
    TestZeroCapabilityString            零能力不 panic

**判据写错过一次**:第一版按「全部命中」写 Supports,实测红。
查实现(`c&cap != 0`)确认是任一位命中,按真实契约修正。

## internal/system —— 路径判定 / 写前留档

    TestIsProtectedPathExplicit         显式前缀集内/外的判定
    TestArchiveBeforeWrite              受保护路径覆盖前留档(走导出的
                                        SetProtectedPaths 配置入口)
    TestNetworkBaselinePathIsStable     路径输出稳定
    TestLoadBaselineMissingReportsError 读不存在的基线报错

## internal/ipc —— 真实 unix socket 往返

    TestPingReturnsServerStatus         Server 状态原样到达 Client
    TestPingWithoutServerReportsError   无服务端时报错

用临时目录下真 socket,不 mock 传输层。

## internal/supervisor —— Daemon 登记

    TestFreshDaemonHasNoAgents          新 daemon 无 agent
    TestRegisterThenList                RegisterAgent → List/Get 反映该 agent
    TestGetUnknownAgentReportsError     未注册 agent 报错
    TestSDKAdapterSeesSameAgents        适配层看到同一份登记

## 变异验证(改回旧实现必须红)

    agent/io   Supports 恒 false      → ★ 已置位的能力报告不支持
    system     路径判定恒 false       → ★ 前缀集内的路径没判受保护
    ipc        Ping 丢 Tools 字段     → ★ Ping 拿到的状态不符
    supervisor ListAgents 恒空        → ★ ListAgents = [],期望 1 个

system / ipc 第一版变异改错了位置(空变异),重做后确认判据有效。

## 验证

    go build ./...                            PASS
    go vet ./...                              PASS
    gofmt -l                                  干净
    python3 .github/scripts/check-ci-gates.py PASS
    go test ./... -count=1                    28 个测试包 / 100 包无测试 / 0 FAIL
    4 个新包 -race                            全绿
    源码目录 _test.go                         0
2026-11-09 13:38:31 +08:00

47 lines
1.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package test
// internal/agent/io 的黑盒判据:OutputCapability 的导出方法,输入 → 输出。
// 不构造设备、不碰内部注册表。
import (
"strings"
"testing"
"github.com/JianFeeeee/HologramAgent/internal/agent/io"
)
// TestSupportsSingleAndCombinedFlags:位标志的 Supports 语义。
func TestSupportsSingleAndCombinedFlags(t *testing.T) {
c := io.CapText | io.CapAudio
if !c.Supports(io.CapText) || !c.Supports(io.CapAudio) {
t.Fatal("★ 已置位的能力报告不支持")
}
if c.Supports(io.CapImage) {
t.Fatal("★ 未置位的能力报告支持")
}
// Supports 的语义是「任一位命中」,不是「全部命中」。
if !io.CapText.Supports(io.CapText | io.CapImage) {
t.Fatal("★ 任一位命中应报告支持")
}
if io.CapText.Supports(io.CapImage) {
t.Fatal("★ 完全不相交却报告支持")
}
}
// TestCapabilityStringListsFlags:String 输出列出已置位的能力名。
func TestCapabilityStringListsFlags(t *testing.T) {
c := io.CapText | io.CapImage
s := c.String()
if !strings.Contains(s, "text") || !strings.Contains(s, "image") {
t.Fatalf("★ String() = %q,缺已置位能力名", s)
}
if strings.Contains(s, "audio") {
t.Fatalf("★ String() = %q,含未置位能力", s)
}
}
// TestZeroCapabilityString:零能力字符串可用(不 panic)。
func TestZeroCapabilityString(t *testing.T) {
_ = io.OutputCapability(0).String()
}