mirror of
https://github.com/Awuqing/BackupX.git
synced 2026-08-07 05:23:28 +08:00
文件备份新增差异模式:仅打包自上次全量以来的变更并记录删除,恢复自动按全量+差异链还原。含基线解析、链式恢复、保留链保护与本机文件任务校验;清单/比对/删除/往返/保留保护单测全覆盖。
56 lines
2.0 KiB
Go
56 lines
2.0 KiB
Go
package retention
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"backupx/server/internal/model"
|
|
)
|
|
|
|
func retentionRecIDs(records []model.BackupRecord) []uint {
|
|
ids := make([]uint, 0, len(records))
|
|
for _, r := range records {
|
|
ids = append(ids, r.ID)
|
|
}
|
|
return ids
|
|
}
|
|
|
|
// 基线全量仍被「不在删除集合中的差异」依赖 → 必须保留,否则差异无法恢复。
|
|
func TestProtectDifferentialBasesKeepsBaseWithSurvivingDiff(t *testing.T) {
|
|
all := []model.BackupRecord{
|
|
{ID: 1, BackupKind: model.BackupKindFull},
|
|
{ID: 2, BackupKind: model.BackupKindDifferential, BaseRecordID: 1},
|
|
}
|
|
candidates := []model.BackupRecord{{ID: 1, BackupKind: model.BackupKindFull}}
|
|
if got := protectDifferentialBases(all, candidates); len(got) != 0 {
|
|
t.Fatalf("base with surviving diff must be protected, got %v", retentionRecIDs(got))
|
|
}
|
|
}
|
|
|
|
// 基线全量与其全部差异都在删除集合中 → 可一并删除(无残留差异失去基线)。
|
|
func TestProtectDifferentialBasesDeletesBaseWhenDiffAlsoDeleted(t *testing.T) {
|
|
all := []model.BackupRecord{
|
|
{ID: 1, BackupKind: model.BackupKindFull},
|
|
{ID: 2, BackupKind: model.BackupKindDifferential, BaseRecordID: 1},
|
|
}
|
|
candidates := []model.BackupRecord{
|
|
{ID: 1, BackupKind: model.BackupKindFull},
|
|
{ID: 2, BackupKind: model.BackupKindDifferential, BaseRecordID: 1},
|
|
}
|
|
if got := protectDifferentialBases(all, candidates); len(got) != 2 {
|
|
t.Fatalf("base+diff both expired should both be deleted, got %v", retentionRecIDs(got))
|
|
}
|
|
}
|
|
|
|
// 无差异备份时原样透传(不影响既有全量保留逻辑)。
|
|
func TestProtectDifferentialBasesNoDiffsPassThrough(t *testing.T) {
|
|
all := []model.BackupRecord{
|
|
{ID: 1, BackupKind: model.BackupKindFull},
|
|
{ID: 2, BackupKind: model.BackupKindFull},
|
|
}
|
|
candidates := []model.BackupRecord{{ID: 1, BackupKind: model.BackupKindFull}}
|
|
got := protectDifferentialBases(all, candidates)
|
|
if len(got) != 1 || got[0].ID != 1 {
|
|
t.Fatalf("no diffs should pass through unchanged, got %v", retentionRecIDs(got))
|
|
}
|
|
}
|