Files
HomeAgent/internal/log/test/manager_contract_test.go
JianFeeeee 3420ceca60 test: 按模块导出接口重写黑盒判据(批次 10:agent / lua / ollama / log)
4 个文件全部在 `<module>/test/`,源码目录仍零 `_test.go`。
共 20 条判据,只调导出接口,输入 → 可观察输出。

## internal/agent —— 人格文件

    TestSaveThenLoadPersonality            Save → Load 内容/路径
    TestLoadMissingPersonalityGivesEmpty   文件不存在 → 空人格
    TestInjectPromptContainsContentAndRules 注入含原文 + 内核说话规则
    TestInjectPromptEmptyPersonalityIsEmpty
    TestPersonaStaleHints                  陈旧措辞给提示;干净文本不报
    TestSavePersonalityCreatesParentDirs   自动建父目录

## internal/lua —— VM 适配器

    TestNewVMExposesAdapterDir             构造参数 → AdapterDir
    TestListAdaptersEmptyThenLoaded        LoadAdapterSource → ListAdapters
    TestLoadAdapterSourceRejectsBadScript
    TestCallTransformRequestUnknownAdapter
    TestGetAdapterEndpointUnknownIsEmpty

## providers/ollama —— httptest 真实 HTTP

    TestGenerateReturnsText                200 → Response.Text
    TestGenerateMarksTruncated             done_reason=length → Truncated
    TestGenerateHTTPError                  5xx → 报错
    TestGenerateRejectsInvalidJSONSchema
    TestNewFallsBackToDefaultModel         空 model 走默认值

**判据写错过一次**:第一版断言"空 model 构造失败",但 `optString`
对空值回退默认,构造成功才是真实契约,按此修正。

## internal/log —— Manager 生命周期

    TestManagerStartStopIsSafe             Start/cancel/Stop 不挂住
    TestManagerStopIsIdempotent            连停两次不 panic
    TestRetentionPoliciesAreDistinct       四个策略常量互异

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

    agent  SavePersonality 不建父目录  → ★ 文件没落盘
    lua    ListAdapters 恒空           → ★ ListAdapters = [],期望 1 个
    ollama 丢 Truncated               → ★ done_reason=length 未标记 Truncated
    log    Stop 重复 close             → panic: close of closed channel

lua / log 第一版变异分别是文本不匹配与"import 变未使用导致编译失败",
都不算干净的断言红;重做成只改行为后确认有效。

## 验证

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

55 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/log 的黑盒判据:NewManager → Start/Stop 不 panic;
// RetentionPolicy 常量是对外契约。不读日志文件内容、不碰 m.done。
import (
"context"
"testing"
"time"
"github.com/JianFeeeee/HologramAgent/internal/log"
)
type stubCfg struct{}
func (c *stubCfg) GetString(key, def string) string { return def }
func (c *stubCfg) GetInt(key string, def int) int { return def }
// TestManagerStartStopIsSafe:构造 + 启动 + 停止不得 panic/挂住。
func TestManagerStartStopIsSafe(t *testing.T) {
m := log.NewManager(t.TempDir(), &stubCfg{})
ctx, cancel := context.WithCancel(context.Background())
m.Start(ctx)
cancel()
done := make(chan struct{})
go func() { m.Stop(); close(done) }()
select {
case <-done:
case <-time.After(3 * time.Second):
t.Fatal("★ Stop 挂住")
}
}
// TestManagerStopIsIdempotent:连停两次不得 panic(close 纪律)。
func TestManagerStopIsIdempotent(t *testing.T) {
m := log.NewManager(t.TempDir(), &stubCfg{})
m.Stop()
m.Stop()
}
// TestRetentionPoliciesAreDistinct:四个策略常量互不相同且非空。
func TestRetentionPoliciesAreDistinct(t *testing.T) {
all := []log.RetentionPolicy{
log.RetentionThisWeek, log.RetentionThisMonth,
log.RetentionNMonths, log.RetentionForever,
}
seen := map[log.RetentionPolicy]bool{}
for _, p := range all {
if p == "" || seen[p] {
t.Fatalf("★ 策略常量为空或重复:%q", p)
}
seen[p] = true
}
}