From 8e3311cea291fefe6439c81992a231009164d6d5 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Wed, 7 Oct 2026 13:25:35 +0800 Subject: [PATCH] =?UTF-8?q?test(cyrene):=20=E8=A1=A5=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=85=A5=E5=BA=93=E9=97=B8=E7=9A=84=E6=8E=A5=E7=BA=BF=E6=96=AD?= =?UTF-8?q?=E8=A8=80=EF=BC=88=E5=88=87=E7=89=87=E8=BF=9E=E5=B8=A6=E7=9A=84?= =?UTF-8?q?=E6=BC=8F=E6=8F=90=E4=BA=A4=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 断言组合根真的接了闸的开关:a.memoryIngestGateOff() 与 DisableIngestGate: gateOff - 断言 store 侧唯一写路径先过闸(不是只投异步队列) (前一片 90f4302 提交时漏了这个测试文件,工作树因此挂着一处未提交改动;现补齐。) --- cmd/cyrene/wire_memory_review_test.go | 52 +++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/cmd/cyrene/wire_memory_review_test.go b/cmd/cyrene/wire_memory_review_test.go index 4c05f01..aca7659 100644 --- a/cmd/cyrene/wire_memory_review_test.go +++ b/cmd/cyrene/wire_memory_review_test.go @@ -3,10 +3,12 @@ package main import ( "context" "os" + "path/filepath" "strings" "testing" "time" + "git.yeij.top/AskaEth/Cyrene_v2/internal/config" "git.yeij.top/AskaEth/Cyrene_v2/internal/db" "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/embedding" "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/history" @@ -54,6 +56,10 @@ func TestMemoryReviewIsWired(t *testing.T) { "Audit: a.auditMemoryReview", // 接到 store 的唯一写入路径上。 "a.memStore.AttachIngestReviewer(reviewer)", + // 同步入库闸(2026-10-07)的开关来自 `$DATA_DIR/config/memory-tidy.json` + // 的 `{"ingestGate": false}`(**零新 env 键**,`.env` 已冻结)。 + "a.memoryIngestGateOff()", + "DisableIngestGate: gateOff", }, "main.go": { "a.memoryReview.Start(ctx)", @@ -75,13 +81,53 @@ func TestMemoryReviewIsWired(t *testing.T) { } } - // store 侧的唯一写入路径必须投递审查(否则新记忆永远不进队列)。 + // store 侧的唯一写入路径必须投递审查(否则新记忆永远不进队列), + // 且必须**先过同步入库闸**(2026-10-07:闸就摆在写路径上,重复当场落 merged)。 storeSrc, err := os.ReadFile("../../internal/runtime/memory/store.go") if err != nil { t.Fatalf("read memory/store.go: %v", err) } - if !strings.Contains(string(storeSrc), "s.enqueueReview(item)") { - t.Fatal("memory/store.go 的写入路径上没有投递审查(写路径唯一)") + for _, want := range []string{"s.enqueueReview(item)", "s.planIngest(ctx, item)", "s.finishIngest(ctx, item, plan)"} { + if !strings.Contains(string(storeSrc), want) { + t.Fatalf("memory/store.go 的写入路径上找不到 %q(唯一写路径上的闸/投递断了)", want) + } + } +} + +// TestMemoryIngestGate_ReadsDataDirConfig 钉住**同步入库闸**的开关确实来自 +// `$DATA_DIR/config/memory-tidy.json`(它没有 env 键:`.env` 已冻结)—— +// 若组合根没读那个文件,「一键回到只插不审」就是一句空话。 +// +// 口径与自动档同一条:没配 = 开;显式 false = 关;坏文件 = 回落代码默认(开) +// 并记 WARN,**绝不静默把一处防护关掉**。 +func TestMemoryIngestGate_ReadsDataDirConfig(t *testing.T) { + t.Parallel() + + empty := &app{cfg: &config.Config{DataDir: t.TempDir()}, log: tidyTestLog()} + if empty.memoryIngestGateOff() { + t.Fatal("没配过时入库闸应当保持代码默认(开)") + } + + dataDir := t.TempDir() + dir := filepath.Join(dataDir, "config") + if err := os.MkdirAll(dir, 0o700); err != nil { + t.Fatalf("mkdir: %v", err) + } + path := filepath.Join(dir, "memory-tidy.json") + if err := os.WriteFile(path, []byte(`{"ingestGate": false}`), 0o600); err != nil { + t.Fatalf("write: %v", err) + } + off := &app{cfg: &config.Config{DataDir: dataDir}, log: tidyTestLog()} + if !off.memoryIngestGateOff() { + t.Fatal("ingestGate: false 没被读到(闸没有一键关掉的路径)") + } + + if err := os.WriteFile(path, []byte(`{"ingestGate": "nope"}`), 0o600); err != nil { + t.Fatalf("write broken: %v", err) + } + broken := &app{cfg: &config.Config{DataDir: dataDir}, log: tidyTestLog()} + if broken.memoryIngestGateOff() { + t.Fatal("坏配置把入库闸静默关掉了:必须回落代码默认(开)") } }