diff options
| author | Fuwn <[email protected]> | 2026-02-26 15:07:03 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-26 15:07:03 -0800 |
| commit | f1b26a68534e4299de7b5fe6b15d2b248fac40e1 (patch) | |
| tree | 4003d041bc46866b7d4b7f0bfb6c6924d991cbb6 /internal/ingest/client_retry_test.go | |
| parent | feat: initial Plutia release — verifiable high-performance PLC mirror (mirr... (diff) | |
| download | plutia-test-f1b26a68534e4299de7b5fe6b15d2b248fac40e1.tar.xz plutia-test-f1b26a68534e4299de7b5fe6b15d2b248fac40e1.zip | |
feat: harden launch readiness with versioning, metrics, and resilience
Diffstat (limited to 'internal/ingest/client_retry_test.go')
| -rw-r--r-- | internal/ingest/client_retry_test.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/internal/ingest/client_retry_test.go b/internal/ingest/client_retry_test.go new file mode 100644 index 0000000..a23fceb --- /dev/null +++ b/internal/ingest/client_retry_test.go @@ -0,0 +1,63 @@ +package ingest + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "sync/atomic" + "testing" + "time" +) + +func TestFetchExportLimitedRetries429ThenSucceeds(t *testing.T) { + var attempts atomic.Int32 + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + n := attempts.Add(1) + if n <= 2 { + w.Header().Set("Retry-After", "0") + http.Error(w, "rate limited", http.StatusTooManyRequests) + return + } + _, _ = fmt.Fprintln(w, `{"seq":1,"did":"did:plc:alice","cid":"cid1","operation":{"x":1}}`) + })) + defer ts.Close() + + client := NewClient(ts.URL, ClientOptions{ + MaxAttempts: 5, + BaseDelay: time.Millisecond, + MaxDelay: 2 * time.Millisecond, + }) + records, err := client.FetchExportLimited(context.Background(), 0, 0) + if err != nil { + t.Fatalf("fetch export: %v", err) + } + if len(records) != 1 { + t.Fatalf("record count mismatch: got %d want 1", len(records)) + } + if got := attempts.Load(); got != 3 { + t.Fatalf("attempt count mismatch: got %d want 3", got) + } +} + +func TestFetchExportLimitedDoesNotRetry400(t *testing.T) { + var attempts atomic.Int32 + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + attempts.Add(1) + http.Error(w, "bad request", http.StatusBadRequest) + })) + defer ts.Close() + + client := NewClient(ts.URL, ClientOptions{ + MaxAttempts: 5, + BaseDelay: time.Millisecond, + MaxDelay: 2 * time.Millisecond, + }) + _, err := client.FetchExportLimited(context.Background(), 0, 0) + if err == nil { + t.Fatalf("expected error for 400 response") + } + if got := attempts.Load(); got != 1 { + t.Fatalf("unexpected retries on 400: got attempts=%d want 1", got) + } +} |