mirror of
https://gh-proxy.org/https://github.com/klinsmaya/CLIProxyAPI.git
synced 2026-11-08 01:16:47 +08:00
test(antigravity): cover invalid-signature replay cache clear
Add executor httptest for upstream 400 clearing HOME reasoning replay items, and a whitespace call_id matcher regression test for replay filtering.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
internalcache "github.com/router-for-me/CLIProxyAPI/v7/internal/cache"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/internal/config"
|
||||
cliproxyauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/auth"
|
||||
cliproxyexecutor "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/executor"
|
||||
sdktranslator "github.com/router-for-me/CLIProxyAPI/v7/sdk/translator"
|
||||
)
|
||||
|
||||
func TestAntigravityReasoningReplayClearsOnInvalidSignature400(t *testing.T) {
|
||||
internalcache.ClearAntigravityReasoningReplayCache()
|
||||
t.Cleanup(internalcache.ClearAntigravityReasoningReplayCache)
|
||||
|
||||
model := "gemini-3-flash-agent"
|
||||
sessionKey := "session:pr3900-invalid-sig"
|
||||
bad := []byte(`{"type":"thought_signature","thoughtSignature":"INVALID_REPLAY_SIGNATURE_PR3900_XXXXXXXXX","contentIndex":1,"partIndex":0}`)
|
||||
if !internalcache.CacheAntigravityReasoningReplayItems(model, sessionKey, [][]byte{bad}) {
|
||||
t.Fatal("failed to seed replay cache")
|
||||
}
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = io.ReadAll(r.Body)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
_, _ = w.Write([]byte(`{"error":{"message":"Invalid thoughtSignature in model content","code":400}}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
exec := NewAntigravityExecutor(&config.Config{RequestRetry: 1})
|
||||
auth := &cliproxyauth.Auth{
|
||||
ID: "auth-pr3900-invalid-sig",
|
||||
Attributes: map[string]string{
|
||||
"base_url": server.URL,
|
||||
},
|
||||
Metadata: map[string]any{
|
||||
"access_token": "token",
|
||||
"project_id": "project-1",
|
||||
"expired": time.Now().Add(1 * time.Hour).Format(time.RFC3339),
|
||||
},
|
||||
}
|
||||
|
||||
payload := []byte(`{"sessionId":"pr3900-invalid-sig","request":{"contents":[{"role":"user","parts":[{"text":"hi"}]},{"role":"user","parts":[{"functionResponse":{"id":"id1","name":"Bash","response":{"result":"ok"}}}]}]}}`)
|
||||
_, err := exec.Execute(context.Background(), auth, cliproxyexecutor.Request{
|
||||
Model: model,
|
||||
Payload: payload,
|
||||
}, cliproxyexecutor.Options{
|
||||
SourceFormat: sdktranslator.FormatAntigravity,
|
||||
Stream: false,
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("expected upstream 400 error")
|
||||
}
|
||||
if _, ok, errGet := internalcache.GetAntigravityReasoningReplayItemsRequired(context.Background(), model, sessionKey); errGet != nil {
|
||||
t.Fatalf("get after clear: %v", errGet)
|
||||
} else if ok {
|
||||
t.Fatal("invalid signature 400 should clear cached replay item")
|
||||
}
|
||||
}
|
||||
@@ -137,3 +137,10 @@ func TestAntigravityReplayToolCallKeysUsesNativeFunctionCallID(t *testing.T) {
|
||||
t.Fatalf("parallel tool calls should not share replay key: %v vs %v", keys, keys2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAntigravityRequestHasMatchingFunctionResponseWhitespaceCallID(t *testing.T) {
|
||||
item := gjson.Parse(`{"call_id":" "}`)
|
||||
if !antigravityRequestHasMatchingFunctionResponse(nil, item) {
|
||||
t.Fatal("whitespace-only call_id should be treated as empty => true")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user