package inventory import ( "context" "errors" "testing" "time" ) // **A heal is begun under the lease and kept with its epoch** (novox/hq to-be 45 ยง7): refused, and // nothing written, by a process that may not act; finished whatever the lease says by then; read back // in the order they were taken. func TestAHealIsBegunUnderTheLeaseAndFinishedAfter(t *testing.T) { inv := ForTest(t) ctx := t.Context() inv.ActsUnder(func(context.Context) (uint64, error) { return 0, errors.New("the lease is not held") }) if _, err := inv.BeginHeal(ctx, Heal{Healer: "H1", ConditionKey: "machine.anchor.sent-not-reported", Act: "asked"}); err == nil { t.Fatal("a heal was begun by a process that may not act") } inv.ActsUnder(func(context.Context) (uint64, error) { return 57, nil }) at := time.Now().Add(-time.Minute).UTC().Truncate(time.Microsecond) first, err := inv.BeginHeal(ctx, Heal{Healer: "H1", ConditionKey: "machine.anchor.sent-not-reported", Kind: "sent-not-reported", Act: "asked", At: at}) if err != nil || first.ID == 0 || first.Epoch != 57 || first.BudgetKey != first.ConditionKey || first.Outcome != HealActing || !first.At.Equal(at) { t.Fatalf("begun: %+v %v", first, err) } if _, err := inv.BeginHeal(ctx, Heal{Healer: "H3"}); err == nil { t.Fatal("a heal naming no condition and no act was begun") } inv.ActsUnder(func(context.Context) (uint64, error) { return 0, errors.New("lost meanwhile") }) if err := inv.FinishHeal(ctx, first.ID, HealActed, "it reported"); err != nil { t.Fatalf("what was done could not be recorded once the lease was gone: %v", err) } if err := inv.FinishHeal(ctx, first.ID+1000, HealActed, ""); err == nil { t.Fatal("a heal that was never begun was finished") } heals, err := inv.HealsSince(ctx, time.Now().Add(-time.Hour)) if err != nil || len(heals) != 1 || heals[0].Outcome != HealActed || heals[0].Said != "it reported" || heals[0].Finished == nil || heals[0].Epoch != 57 { t.Fatalf("read back: %+v %v", heals, err) } }