67 lines
3.3 KiB
Go
67 lines
3.3 KiB
Go
package backup
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// R-1271 (brief 2026-10-25 Part 4) — a copy dated in the future is never „the newest". The measured case (catalog sweep
|
|
// 2026-10-24): the rehearsal box's off-site copy dated 2026-10-28 07:39 beat the family's own copy of 2026-10-24 19:17
|
|
// on a box whose clock said 2026-10-24.
|
|
// COMPANION RED-PROOF (REPORT.md): with the old KeptNewer (off-site when its date is after the local one's),
|
|
// TestR1271_AFutureOffsiteCopyNeverBeatsTheOwnCopy fails — the off-site copy is chosen.
|
|
|
|
var r1271Now = time.Date(2026, 10, 24, 19, 22, 0, 0, time.UTC)
|
|
|
|
func TestR1271_AFutureOffsiteCopyNeverBeatsTheOwnCopy(t *testing.T) {
|
|
local := KeptCopy{UnitDir: "/u", Tier: 1, Time: time.Date(2026, 10, 24, 19, 17, 0, 0, time.UTC)}
|
|
off := KeptCopy{Tier: KeptTierOffsite, Time: time.Date(2026, 10, 28, 6, 39, 0, 0, time.UTC), SnapshotID: "abba81ba"}
|
|
c, ok := KeptNewerAt(r1271Now, local, true, off, true)
|
|
if !ok || c.Tier != 1 || c.Future {
|
|
t.Fatalf("the household's own copy must win over a future-dated off-site one, got %+v", c)
|
|
}
|
|
}
|
|
|
|
func TestR1271_AFutureCopyAloneIsOfferedButMarked(t *testing.T) {
|
|
off := KeptCopy{Tier: KeptTierOffsite, Time: time.Date(2026, 10, 28, 6, 39, 0, 0, time.UTC), SnapshotID: "abba81ba"}
|
|
c, ok := KeptNewerAt(r1271Now, KeptCopy{}, false, off, true)
|
|
if !ok || c.Tier != KeptTierOffsite || !c.Future {
|
|
t.Fatalf("a future-dated copy alone is offered and marked Future (not recommended), got %+v ok=%v", c, ok)
|
|
}
|
|
}
|
|
|
|
func TestR1271_AnOlderOffsiteCopyAloneIsChosenAsBefore(t *testing.T) {
|
|
off := KeptCopy{Tier: KeptTierOffsite, Time: time.Date(2026, 10, 20, 4, 15, 0, 0, time.UTC), SnapshotID: "s1"}
|
|
c, ok := KeptNewerAt(r1271Now, KeptCopy{}, false, off, true)
|
|
if !ok || c.Tier != KeptTierOffsite || c.Future {
|
|
t.Fatalf("a normal older off-site copy alone is chosen as before, got %+v", c)
|
|
}
|
|
}
|
|
|
|
// The other direction of the old rule still holds: a NEWER off-site copy with a true date beats an older local one.
|
|
func TestR1271_ANewerTrueOffsiteCopyStillWins(t *testing.T) {
|
|
local := KeptCopy{UnitDir: "/u", Tier: 1, Time: time.Date(2026, 10, 20, 4, 0, 0, 0, time.UTC)}
|
|
off := KeptCopy{Tier: KeptTierOffsite, Time: time.Date(2026, 10, 24, 4, 0, 0, 0, time.UTC), SnapshotID: "s2"}
|
|
if c, _ := KeptNewerAt(r1271Now, local, true, off, true); c.Tier != KeptTierOffsite {
|
|
t.Fatalf("a newer off-site copy with a true date wins, got %+v", c)
|
|
}
|
|
// A tie goes local (no download).
|
|
off.Time = local.Time
|
|
if c, _ := KeptNewerAt(r1271Now, local, true, off, true); c.Tier != 1 {
|
|
t.Fatalf("a tie goes local, got %+v", c)
|
|
}
|
|
}
|
|
|
|
// The skew allowance: a few minutes ahead is a true date; beyond KeptClockSkew it is not.
|
|
func TestR1271_TheClockSkewAllowance(t *testing.T) {
|
|
local := KeptCopy{UnitDir: "/u", Tier: 1, Time: r1271Now.Add(-time.Hour)}
|
|
near := KeptCopy{Tier: KeptTierOffsite, Time: r1271Now.Add(KeptClockSkew - time.Minute), SnapshotID: "n"}
|
|
if c, _ := KeptNewerAt(r1271Now, local, true, near, true); c.Tier != KeptTierOffsite {
|
|
t.Fatalf("a copy within the skew is a true date and newer, got %+v", c)
|
|
}
|
|
far := KeptCopy{Tier: KeptTierOffsite, Time: r1271Now.Add(KeptClockSkew + time.Minute), SnapshotID: "f"}
|
|
if c, _ := KeptNewerAt(r1271Now, local, true, far, true); c.Tier != 1 {
|
|
t.Fatalf("a copy beyond the skew is future-dated and never the newest, got %+v", c)
|
|
}
|
|
}
|