Files
Agent-System/internal/ctxmgr/summarizer_persist_test.go
weichenandCursor 848a0457a0 fix(chat): stop treating failed summary writes as durable
新增 chat_summaries 迁移。数据库写失败会返回错误并标明仅本进程可见。test_manager 血缘改用文档版本,不再写死 1。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-20 04:02:41 +00:00

80 lines
2.6 KiB
Go

package ctxmgr
import (
"context"
"strings"
"testing"
"time"
"github.com/jackc/pgx/v5/pgxpool"
)
func TestSaveChatSummary_MemoryStoreCountsAsPersisted(t *testing.T) {
mgr := NewContextManager(nil, nil, DefaultTimeDecayConfig())
sum := &ChatSummary{SessionID: "sess_mem", Narrative: "仅内存", Facts: map[string]string{}, OpenQuestions: []string{}}
if err := mgr.SaveChatSummary(context.Background(), sum); err != nil {
t.Fatal(err)
}
if !sum.Persisted {
t.Fatal("nil pool is the configured store and must report persisted")
}
}
func TestSaveChatSummary_DatabaseFailureIsNotSuccess(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
pool, err := pgxpool.New(ctx, "postgres://summary:summary@127.0.0.1:1/none?sslmode=disable&connect_timeout=1")
if err != nil {
t.Fatal(err)
}
t.Cleanup(pool.Close)
mgr := NewContextManager(pool, nil, DefaultTimeDecayConfig())
sum := &ChatSummary{
SessionID: "sess_db_down", Narrative: "不应伪装成功",
Facts: map[string]string{}, OpenQuestions: []string{},
}
err = mgr.SaveChatSummary(ctx, sum)
if err == nil {
t.Fatal("database write failure must be returned")
}
if sum.Persisted {
t.Fatal("failed write must not be marked persisted")
}
if !strings.Contains(sum.FreshnessNote, summaryNotDurableNote) {
t.Fatalf("freshness note = %q", sum.FreshnessNote)
}
got, getErr := mgr.GetChatSummary(context.Background(), sum.SessionID)
if getErr != nil || got == nil {
t.Fatalf("current process should still serve the summary, err=%v", getErr)
}
if got.Persisted || !strings.Contains(got.FreshnessNote, summaryNotDurableNote) {
t.Fatalf("served fallback must stay non-durable: %+v", got)
}
}
func TestGenerateRollingSummary_RecordsRevisionAndMessageSpan(t *testing.T) {
mgr := NewContextManager(nil, nil, DefaultTimeDecayConfig())
ctx := context.Background()
first := []ChatMessageRecord{{
ID: 10, Role: "user", Content: "临床评价路径该怎么走?", CreatedAt: time.Now(),
}}
sum, err := mgr.GenerateRollingSummary(ctx, "sess_rev", nil, first)
if err != nil {
t.Fatal(err)
}
if !sum.Persisted || sum.Revision != 1 || sum.FromMessageID != 10 || sum.ToMessageID != 10 || sum.ProtocolVersion != "deterministic-v1" {
t.Fatalf("first summary = %+v", sum)
}
second := []ChatMessageRecord{{
ID: 11, Role: "user", Content: "预算大约在200万左右", CreatedAt: time.Now(),
}}
next, err := mgr.GenerateRollingSummary(ctx, "sess_rev", sum, second)
if err != nil {
t.Fatal(err)
}
if next.Revision != 2 || next.PreviousRevision != 1 || next.FromMessageID != 11 || next.Facts["budget"] != "200万元" {
t.Fatalf("rolled summary = %+v", next)
}
}