Add projects
This commit is contained in:
parent
2d3a9ad623
commit
8b607dd700
1802 changed files with 503346 additions and 2 deletions
184
backend/sdk/api/handlers/handlers_metadata_test.go
Normal file
184
backend/sdk/api/handlers/handlers_metadata_test.go
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/internal/logging"
|
||||
coreexecutor "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/executor"
|
||||
coresession "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/session"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/sdk/config"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func TestGetContextWithCancelCapturesClientRequestMetadata(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
ginCtx, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
ginCtx.Request = httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
|
||||
ginCtx.Request.RemoteAddr = "192.0.2.10:43123"
|
||||
ginCtx.Request.Header.Add("X-Forwarded-For", "203.0.113.5")
|
||||
ginCtx.Request.Header.Add("X-Forwarded-For", "198.51.100.8")
|
||||
ginCtx.Request.Header.Set("User-Agent", "test-client/1.0")
|
||||
|
||||
handler := &BaseAPIHandler{Cfg: &config.SDKConfig{}}
|
||||
ctx, cancel := handler.GetContextWithCancel(nil, ginCtx, context.Background())
|
||||
defer cancel()
|
||||
|
||||
metadata := logging.GetClientRequestMetadata(ctx)
|
||||
if metadata.ClientIP != "192.0.2.10" {
|
||||
t.Fatalf("ClientIP = %q, want direct peer IP", metadata.ClientIP)
|
||||
}
|
||||
if metadata.XForwardedFor != "203.0.113.5, 198.51.100.8" {
|
||||
t.Fatalf("XForwardedFor = %q", metadata.XForwardedFor)
|
||||
}
|
||||
if metadata.UserAgent != "test-client/1.0" {
|
||||
t.Fatalf("UserAgent = %q", metadata.UserAgent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestExecutionMetadataIncludesExecutionSessionWithoutIdempotencyKey(t *testing.T) {
|
||||
ctx := WithExecutionSessionID(context.Background(), "session-1")
|
||||
|
||||
meta := requestExecutionMetadata(ctx)
|
||||
if got := meta[coreexecutor.ExecutionSessionMetadataKey]; got != "session-1" {
|
||||
t.Fatalf("ExecutionSessionMetadataKey = %v, want %q", got, "session-1")
|
||||
}
|
||||
if _, ok := meta[idempotencyKeyMetadataKey]; ok {
|
||||
t.Fatalf("unexpected idempotency key in metadata: %v", meta[idempotencyKeyMetadataKey])
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestExecutionMetadataIncludesHashedCallerScope(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
ginCtx, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
ginCtx.Request = httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
|
||||
ginCtx.Set("userApiKey", "downstream-secret")
|
||||
ctx := context.WithValue(context.Background(), "gin", ginCtx)
|
||||
|
||||
meta := requestExecutionMetadata(ctx)
|
||||
got, _ := meta[coreexecutor.CallerScopeMetadataKey].(string)
|
||||
want := coresession.CallerScope("downstream-secret")
|
||||
if got != want {
|
||||
t.Fatalf("CallerScopeMetadataKey = %q, want %q", got, want)
|
||||
}
|
||||
if got == "downstream-secret" {
|
||||
t.Fatal("caller scope contains the raw downstream credential")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestExecutionMetadataTraceCallbackWebsocketDetection(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
t.Run("skips websocket upgrade", func(t *testing.T) {
|
||||
ginCtx, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
ginCtx.Request = httptest.NewRequest(http.MethodGet, "/v1/responses", nil)
|
||||
ginCtx.Request.Header.Set("Connection", "Upgrade")
|
||||
ginCtx.Request.Header.Set("Upgrade", "websocket")
|
||||
logging.SetGinRequestID(ginCtx, "1234abcd")
|
||||
ctx := context.WithValue(context.Background(), "gin", ginCtx)
|
||||
|
||||
meta := requestExecutionMetadata(ctx)
|
||||
|
||||
if _, exists := meta[coreexecutor.SelectedAuthIndexCallbackMetadataKey]; exists {
|
||||
t.Fatal("unexpected selected auth index callback for websocket upgrade")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("keeps callback for incomplete upgrade headers", func(t *testing.T) {
|
||||
ginCtx, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
ginCtx.Request = httptest.NewRequest(http.MethodPost, "/v1/responses", nil)
|
||||
ginCtx.Request.Header.Set("Upgrade", "websocket")
|
||||
logging.SetGinRequestID(ginCtx, "1234abcd")
|
||||
ctx := context.WithValue(context.Background(), "gin", ginCtx)
|
||||
|
||||
meta := requestExecutionMetadata(ctx)
|
||||
|
||||
if _, exists := meta[coreexecutor.SelectedAuthIndexCallbackMetadataKey]; !exists {
|
||||
t.Fatal("missing selected auth index callback for ordinary HTTP request")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetReasoningEffortMetadataUsesSuffixOverBody(t *testing.T) {
|
||||
meta := make(map[string]any)
|
||||
|
||||
setReasoningEffortMetadata(meta, "openai", "gpt-5.4(high)", []byte(`{"reasoning_effort":"low"}`))
|
||||
|
||||
if got := meta[coreexecutor.ReasoningEffortMetadataKey]; got != "high" {
|
||||
t.Fatalf("ReasoningEffortMetadataKey = %v, want %q", got, "high")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetReasoningEffortMetadataSupportsOpenAIResponses(t *testing.T) {
|
||||
meta := make(map[string]any)
|
||||
|
||||
setReasoningEffortMetadata(meta, "openai-response", "gpt-5.4", []byte(`{"reasoning":{"effort":"medium"}}`))
|
||||
|
||||
if got := meta[coreexecutor.ReasoningEffortMetadataKey]; got != "medium" {
|
||||
t.Fatalf("ReasoningEffortMetadataKey = %v, want %q", got, "medium")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetServiceTierMetadataExtractsValue(t *testing.T) {
|
||||
meta := make(map[string]any)
|
||||
|
||||
setServiceTierMetadata(meta, []byte(`{"service_tier":"priority"}`))
|
||||
|
||||
gotServiceTier := meta[coreexecutor.ServiceTierMetadataKey]
|
||||
if gotServiceTier != "priority" {
|
||||
t.Fatalf("ServiceTierMetadataKey = %v, want %q", gotServiceTier, "priority")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetServiceTierMetadataDefaultsWhenMissing(t *testing.T) {
|
||||
meta := make(map[string]any)
|
||||
|
||||
setServiceTierMetadata(meta, []byte(`{"model":"gpt-5.4"}`))
|
||||
|
||||
gotServiceTier := meta[coreexecutor.ServiceTierMetadataKey]
|
||||
if gotServiceTier != "auto" {
|
||||
t.Fatalf("ServiceTierMetadataKey = %v, want %q", gotServiceTier, "auto")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetServiceTierMetadataPreservesExplicitDefault(t *testing.T) {
|
||||
meta := make(map[string]any)
|
||||
|
||||
setServiceTierMetadata(meta, []byte(`{"service_tier":"default"}`))
|
||||
|
||||
if gotServiceTier := meta[coreexecutor.ServiceTierMetadataKey]; gotServiceTier != "default" {
|
||||
t.Fatalf("ServiceTierMetadataKey = %v, want %q", gotServiceTier, "default")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetGenerateMetadataDefaultsWhenMissing(t *testing.T) {
|
||||
meta := make(map[string]any)
|
||||
|
||||
setGenerateMetadata(meta, []byte(`{"model":"gpt-5.4"}`))
|
||||
|
||||
if got := meta[coreexecutor.GenerateMetadataKey]; got != true {
|
||||
t.Fatalf("GenerateMetadataKey = %v, want true", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetGenerateMetadataPreservesTrue(t *testing.T) {
|
||||
meta := make(map[string]any)
|
||||
|
||||
setGenerateMetadata(meta, []byte(`{"generate":true}`))
|
||||
|
||||
if got := meta[coreexecutor.GenerateMetadataKey]; got != true {
|
||||
t.Fatalf("GenerateMetadataKey = %v, want true", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetGenerateMetadataHonorsExplicitFalse(t *testing.T) {
|
||||
meta := make(map[string]any)
|
||||
|
||||
setGenerateMetadata(meta, []byte(`{"generate":false}`))
|
||||
|
||||
if got := meta[coreexecutor.GenerateMetadataKey]; got != false {
|
||||
t.Fatalf("GenerateMetadataKey = %v, want false", got)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue