Files
knowledge-governance/internal/platform/postgres/backup_schedule_integration_test.go
T
姚章浩 343a005db1 test(backup): 迁移计数更新到 45 并补 44/45 内容断言;新增 backup_schedule 真实库往返集成测试
- migrations_test.go 之前硬编码 44:新增 000045 后该包测试失败(全量套件里才暴露)
- 现在断言 migration 44 = production_kb_bindings、45 = backup_schedule
- 新增 TestBackupScheduleRoundTripIntegration:默认值 → 保存(upsert 单行) → 读回(含 updated_by/at)
  → 记录下发结果(不改计划);实测在 governance 库隔离 schema 上 PASS(0.95s)
2026-10-09 13:55:35 +08:00

91 lines
2.7 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 postgres
import (
"context"
"os"
"testing"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"knowledge-governance/internal/governance"
)
// 备份定时计划的真实库往返:默认值 → 保存 → 读回 → 记录下发结果。
// 页面靠这几步判定"库里设置"与"主机上生效计划"是否一致(待下发/已一致)。
func TestBackupScheduleRoundTripIntegration(t *testing.T) {
databaseURL := isolatedIntegrationDatabaseURL(t, os.Getenv("TEST_DATABASE_URL"))
if databaseURL == "" {
t.Skip("TEST_DATABASE_URL is not set")
}
ctx := context.Background()
pool, err := pgxpool.New(ctx, databaseURL)
if err != nil {
t.Fatal(err)
}
defer pool.Close()
if err := ApplyMigrations(ctx, pool); err != nil {
t.Fatal(err)
}
store := NewStore(pool)
initial, err := store.LoadBackupSchedule(ctx)
if err != nil {
t.Fatal(err)
}
if initial.Enabled || initial.ScheduleTime != governance.BackupScheduleDefaultTime ||
initial.RetentionDays != 7 || initial.RetentionMonths != 3 {
t.Fatalf("迁移后的默认计划不对: %#v", initial)
}
now := time.Date(2026, 10, 9, 12, 0, 0, 0, time.UTC)
next := governance.BackupSchedule{
Enabled: true, ScheduleTime: "04:15", RetentionDays: 14, RetentionMonths: 6,
}
if err := store.SaveBackupSchedule(ctx, next, "admin", now); err != nil {
t.Fatal(err)
}
saved, err := store.LoadBackupSchedule(ctx)
if err != nil {
t.Fatal(err)
}
if !saved.Enabled || saved.ScheduleTime != "04:15" || saved.RetentionDays != 14 || saved.RetentionMonths != 6 {
t.Fatalf("保存后读回不对: %#v", saved)
}
if saved.UpdatedBy != "admin" || !saved.UpdatedAt.Equal(now) {
t.Fatalf("应记录操作人与时间: %#v", saved)
}
if !next.SameHostPlan(saved) {
t.Fatal("保存的计划应与主机下发字段一致(SameHostPlan)")
}
// 重复保存走 upsert,不应产生第二行。
if err := store.SaveBackupSchedule(ctx, next, "admin2", now.Add(time.Minute)); err != nil {
t.Fatal(err)
}
var rows int
if err := pool.QueryRow(ctx, `SELECT count(*) FROM backup_schedule`).Scan(&rows); err != nil {
t.Fatal(err)
}
if rows != 1 {
t.Fatalf("单行表出现 %d 行", rows)
}
appliedAt := now.Add(2 * time.Minute)
if err := store.MarkBackupScheduleApplied(ctx, "每天 04:15 · 保留 14 天 · 每月归档 6 份", appliedAt); err != nil {
t.Fatal(err)
}
afterApply, err := store.LoadBackupSchedule(ctx)
if err != nil {
t.Fatal(err)
}
if afterApply.LastAppliedAt == nil || !afterApply.LastAppliedAt.Equal(appliedAt) ||
afterApply.LastAppliedSummary == "" {
t.Fatalf("下发结果未落库: %#v", afterApply)
}
// 记录下发不得改动计划本身。
if !afterApply.SameHostPlan(saved) {
t.Fatal("记录下发不应改变计划")
}
}