78 lines · 2.6 KB · Go
RawDownload
package executor import (	"net/http"	"strconv"	"testing"	"time") func TestParseCodexRetryAfter(t *testing.T) {	now := time.Unix(1_700_000_000, 0) 	t.Run("resets_in_seconds", func(t *testing.T) {		body := []byte(`{"error":{"type":"usage_limit_reached","resets_in_seconds":123}}`)		retryAfter := parseCodexRetryAfter(http.StatusTooManyRequests, body, now)		if retryAfter == nil {			t.Fatalf("expected retryAfter, got nil")		}		if *retryAfter != 123*time.Second {			t.Fatalf("retryAfter = %v, want %v", *retryAfter, 123*time.Second)		}	}) 	t.Run("prefers resets_at", func(t *testing.T) {		resetAt := now.Add(5 * time.Minute).Unix()		body := []byte(`{"error":{"type":"usage_limit_reached","resets_at":` + itoa(resetAt) + `,"resets_in_seconds":1}}`)		retryAfter := parseCodexRetryAfter(http.StatusTooManyRequests, body, now)		if retryAfter == nil {			t.Fatalf("expected retryAfter, got nil")		}		if *retryAfter != 5*time.Minute {			t.Fatalf("retryAfter = %v, want %v", *retryAfter, 5*time.Minute)		}	}) 	t.Run("fallback when resets_at is past", func(t *testing.T) {		resetAt := now.Add(-1 * time.Minute).Unix()		body := []byte(`{"error":{"type":"usage_limit_reached","resets_at":` + itoa(resetAt) + `,"resets_in_seconds":77}}`)		retryAfter := parseCodexRetryAfter(http.StatusTooManyRequests, body, now)		if retryAfter == nil {			t.Fatalf("expected retryAfter, got nil")		}		if *retryAfter != 77*time.Second {			t.Fatalf("retryAfter = %v, want %v", *retryAfter, 77*time.Second)		}	}) 	t.Run("non-429 status code", func(t *testing.T) {		body := []byte(`{"error":{"type":"usage_limit_reached","resets_in_seconds":30}}`)		if got := parseCodexRetryAfter(http.StatusBadRequest, body, now); got != nil {			t.Fatalf("expected nil for non-429, got %v", *got)		}	}) 	t.Run("non usage_limit_reached error type", func(t *testing.T) {		body := []byte(`{"error":{"type":"server_error","resets_in_seconds":30}}`)		if got := parseCodexRetryAfter(http.StatusTooManyRequests, body, now); got != nil {			t.Fatalf("expected nil for non-usage_limit_reached, got %v", *got)		}	})} func TestNewCodexStatusErrTreatsCapacityAsRetryableRateLimit(t *testing.T) {	body := []byte(`{"error":{"message":"Selected model is at capacity. Please try a different model."}}`) 	err := newCodexStatusErr(http.StatusBadRequest, body) 	if got := err.StatusCode(); got != http.StatusTooManyRequests {		t.Fatalf("status code = %d, want %d", got, http.StatusTooManyRequests)	}	if err.RetryAfter() != nil {		t.Fatalf("expected nil explicit retryAfter for capacity fallback, got %v", *err.RetryAfter())	}} func itoa(v int64) string {	return strconv.FormatInt(v, 10)}