package spindle
import (
"context"
"testing"
"time"
)
func TestAKickedRepoStillWaitsOutItsBackoff(t *testing.T) {
env := newEnsureEnv(t)
env.serve("repo")
env.ensure(t)
if err := env.s.markRepo(testRepoDid); err != nil {
t.Fatal(err)
}
env.knot.failing = true
env.s.runRepoJob(context.Background(), testRepoDid)
if attempts, marked, err := env.s.db.RepoRetryRow(testRepoDid); err != nil || !marked || attempts != 1 {
t.Fatalf("setup: attempts %d, exists %v, %v, want one failed refresh", attempts, marked, err)
}
before := env.knot.count()
env.s.runRepoJob(context.Background(), testRepoDid)
if got := env.knot.count(); got != before {
t.Fatalf("a repo that is backing off made %d knot requests when it was kicked", got-before)
}
if attempts, _, err := env.s.db.RepoRetryRow(testRepoDid); err != nil || attempts != 1 {
t.Fatalf("attempts = %d, %v, want the backoff left at one failure", attempts, err)
}
// a new event doesn't skip the backoff, it only pulls the due time to a few seconds out
if err := env.s.markRepo(testRepoDid); err != nil {
t.Fatal(err)
}
env.s.runRepoJob(context.Background(), testRepoDid)
if got := env.knot.count(); got != before {
t.Fatalf("a fresh mark on a repo backing off made %d knot requests", got-before)
}
// once those few seconds pass the mark gets answered, long before the backoff ends
env.knot.failing = false
env.s.retries.now = func() time.Time { return time.Now().Add(6 * time.Second) }
env.s.runRepoJob(context.Background(), testRepoDid)
if env.knot.count() == before {
t.Fatal("a mark that waited out the backoff didn't make the repo refresh")
}
}