package host import ( "context" "net/http" "net/http/httptest" "testing" "time" ) func TestWrappedClaimRootStartsAndServes(t *testing.T) { ctx, cancel := context.WithCancel(t.Context()) defer cancel() var handler http.Handler = ClaimRootWithLaunch{Root: ClaimRootHTTP{}} lifecycle, ok := handler.(interface{ Start(context.Context) }) if !ok { t.Fatal("wrapped handler lost lifecycle") } lifecycle.Start(ctx) r := httptest.NewRecorder() handler.ServeHTTP(r, httptest.NewRequest(http.MethodGet, "/claim/retire", nil)) if r.Code != http.StatusServiceUnavailable { t.Fatal(r.Code) } } type recoveryPages struct { servingParkAuthority calls []string } func (p *recoveryPages) recoverServingParks(_ context.Context, after string, limit int) (servingParkRecoveryPage, error) { p.calls = append(p.calls, after) page := servingParkRecoveryPage{} count := 128 if after != "" { count = 72 } for i := 0; i < count; i++ { page.Results = append(page.Results, servingParkRecoveryResult{Host: "kept", ID: "park", Err: errServingParkRetagPending}) } if after == "" { page.More = true page.Next = "128" } return page, nil } func TestServingParkRecoveryPagesRetainedRecords(t *testing.T) { a := &recoveryPages{} ctx, cancel := context.WithCancel(t.Context()) defer cancel() p := &servingParkRuntime{authority: a, ctx: ctx, cancel: cancel, idle: make(chan struct{})} for i := 0; i < 2; i++ { if err := p.recoverPending(ctx); err != nil { t.Fatal("retained parks blocked recovery", err) } } if len(a.calls) != 2 || a.calls[0] != "" || a.calls[1] != "128" { t.Fatal(a.calls) } } func TestServingParkPressurePrecedesSlowRecovery(t *testing.T) { cleaned := false ctx, cancel := context.WithTimeout(t.Context(), time.Second) defer cancel() _, err := maintainServingParkPass(ctx, "", func(call context.Context) error { if call.Err() != nil { t.Fatal(call.Err()) } cleaned = true return nil }, func(call context.Context, _ string, _ int) (servingParkRecoveryPage, error) { if !cleaned { t.Fatal("recovery starved pressure cleanup") } <-call.Done() return servingParkRecoveryPage{}, call.Err() }, 10*time.Millisecond) if !cleaned || err == nil { t.Fatal(cleaned, err) } }