Record a backup that cannot start as the module's last night (issue 1067)
This commit is contained in:
@@ -26,8 +26,16 @@ import (
|
||||
const HandTag = "hand"
|
||||
|
||||
// BackUpNow is a backup asked for now, of every module or one: as a night, each restore point tagged HandTag.
|
||||
//
|
||||
// One that cannot start (the lock cannot be taken, the repository cannot be opened, the module declares nothing)
|
||||
// is recorded as that module's last night, failed and with the reason: the mesh asking before a delivery reads
|
||||
// it from backed-up, and would otherwise read silence (novox/hq issue 1067).
|
||||
func (b *Backups) BackUpNow(ctx context.Context, only string) (map[string]Night, error) {
|
||||
return b.backUp(ctx, only, true)
|
||||
out, err := b.backUp(ctx, only, true)
|
||||
if err != nil && only != "" {
|
||||
b.record(only, Night{OK: false, At: b.Now().UTC(), Error: err.Error()})
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
|
||||
// isHand is whether a restore point was taken by hand.
|
||||
|
||||
@@ -324,3 +324,30 @@ func TestAThinningThatFailsAfterLettingGoSaysWhatItLetGo(t *testing.T) {
|
||||
t.Errorf("said %q, want it to say aaaaaaaa was let go", why)
|
||||
}
|
||||
}
|
||||
|
||||
// A backup asked for now that cannot start leaves its failure as the module's last night, so the mesh asking
|
||||
// for it before a delivery reads the backup's own words from backed-up, not silence (novox/hq issue 1067).
|
||||
func TestABackupAskedForNowThatCannotStartIsRecordedAsThatModulesLastNight(t *testing.T) {
|
||||
h := &handRestic{}
|
||||
asked := time.Date(2026, 10, 17, 22, 50, 0, 0, time.UTC)
|
||||
b := &Backups{Where: placed(t, "# pg\npath /\n"), Run: h.run, Now: func() time.Time { return asked }, Say: quiet}
|
||||
must(t, os.Mkdir(filepath.Join(b.Where.State, nightLock), 0o700)) // a directory cannot be opened read-write: the lock cannot be taken
|
||||
if _, err := b.BackUpNow(context.Background(), "pg"); err == nil {
|
||||
t.Fatal("a backup started without its lock")
|
||||
}
|
||||
night, ok := b.Nights()["pg"]
|
||||
if !ok || night.OK || night.Error == "" || !night.At.Equal(asked) {
|
||||
t.Fatalf("pg's last night is %+v, want a failure at %s with the reason", night, asked)
|
||||
}
|
||||
if !strings.Contains(night.Error, nightLock) {
|
||||
t.Errorf("the reason is %q, want it to name the lock", night.Error)
|
||||
}
|
||||
// Asked of a module that declares nothing here, once the lock can be taken: recorded too, with the reason.
|
||||
must(t, os.Remove(filepath.Join(b.Where.State, nightLock)))
|
||||
if _, err := b.BackUpNow(context.Background(), "mail"); err == nil {
|
||||
t.Fatal("a backup of a module that declares nothing started")
|
||||
}
|
||||
if n := b.Nights()["mail"]; n.OK || !strings.Contains(n.Error, "declares nothing") {
|
||||
t.Errorf("mail's last night is %+v, want a failure saying it declares nothing", n)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user