Merge remote-tracking branch 'origin/pr/498'

This commit is contained in:
fawney19
2026-05-21 22:56:43 +08:00
89 changed files with 18396 additions and 382 deletions
@@ -347,6 +347,78 @@ async fn gateway_counts_keys_with_null_api_formats_for_each_fixed_provider_endpo
upstream_handle.abort();
}
#[tokio::test]
async fn gateway_counts_inherited_windsurf_key_formats_for_admin_provider_endpoints() {
let upstream_hits = Arc::new(Mutex::new(0usize));
let upstream_hits_clone = Arc::clone(&upstream_hits);
let upstream = Router::new().route(
"/api/admin/endpoints/providers/provider-windsurf/endpoints",
any(move |_request: Request| {
let upstream_hits_inner = Arc::clone(&upstream_hits_clone);
async move {
*upstream_hits_inner.lock().expect("mutex should lock") += 1;
(StatusCode::OK, Body::from("unexpected upstream hit"))
}
}),
);
let mut key = sample_key(
"key-windsurf-a",
"provider-windsurf",
"openai:chat",
"oauth-secret",
);
key.auth_type = "oauth".to_string();
key.api_formats = None;
let mut provider = sample_provider("provider-windsurf", "windsurf", 10);
provider.provider_type = "windsurf".to_string();
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
vec![provider],
vec![sample_endpoint(
"endpoint-windsurf-chat",
"provider-windsurf",
"openai:chat",
"https://server.codeium.com",
)],
vec![key],
));
let (_, upstream_handle) = start_server(upstream).await;
let gateway = build_router_with_state(
AppState::new()
.expect("gateway should build")
.with_data_state_for_tests(GatewayDataState::with_provider_catalog_reader_for_tests(
provider_catalog_repository,
)),
);
let (gateway_url, gateway_handle) = start_server(gateway).await;
let response = reqwest::Client::new()
.get(format!(
"{gateway_url}/api/admin/endpoints/providers/provider-windsurf/endpoints?skip=0&limit=50"
))
.header(crate::constants::GATEWAY_HEADER, "rust-phase3b")
.header(TRUSTED_ADMIN_USER_ID_HEADER, "admin-user-123")
.header(TRUSTED_ADMIN_USER_ROLE_HEADER, "admin")
.header(TRUSTED_ADMIN_SESSION_ID_HEADER, "session-123")
.send()
.await
.expect("request should succeed");
assert_eq!(response.status(), StatusCode::OK);
let payload: serde_json::Value = response.json().await.expect("json body should parse");
let items = payload.as_array().expect("payload should be an array");
assert_eq!(items.len(), 1);
assert_eq!(items[0]["id"], "endpoint-windsurf-chat");
assert_eq!(items[0]["total_keys"], 1);
assert_eq!(items[0]["active_keys"], 1);
assert_eq!(*upstream_hits.lock().expect("mutex should lock"), 0);
gateway_handle.abort();
upstream_handle.abort();
}
#[tokio::test]
async fn gateway_returns_service_unavailable_for_admin_provider_endpoint_create_when_catalog_writer_unavailable(
) {
@@ -216,6 +216,23 @@ fn codex_quota_execution_result(request_id: &str) -> serde_json::Value {
})
}
fn windsurf_register_user_execution_result(request_id: &str) -> serde_json::Value {
json!({
"request_id": request_id,
"status_code": 200,
"headers": {
"content-type": "application/json"
},
"body": {
"json_body": {
"apiKey": "devin-session-token$registered",
"name": "Windsurf User",
"apiServerUrl": "https://server.codeium.com"
}
}
})
}
fn assert_single_provider_oauth_refresh_token_plan<'a>(
plans: &'a [ExecutionPlan],
) -> &'a ExecutionPlan {
@@ -281,18 +298,404 @@ async fn gateway_handles_admin_provider_oauth_supported_types_locally_with_trust
assert_eq!(response.status(), StatusCode::OK);
let payload: serde_json::Value = response.json().await.expect("json body should parse");
let items = payload.as_array().expect("items should be array");
assert_eq!(items.len(), 5);
assert_eq!(items.len(), 6);
assert_eq!(items[0]["provider_type"], "claude_code");
assert_eq!(items[1]["provider_type"], "codex");
assert_eq!(items[2]["provider_type"], "chatgpt_web");
assert_eq!(items[3]["provider_type"], "gemini_cli");
assert_eq!(items[4]["provider_type"], "antigravity");
assert_eq!(items[5]["provider_type"], "windsurf");
assert_eq!(*upstream_hits.lock().expect("mutex should lock"), 0);
gateway_handle.abort();
upstream_handle.abort();
}
#[tokio::test]
async fn gateway_handles_admin_provider_oauth_device_authorize_for_windsurf_browser() {
let mut provider = sample_provider("provider-windsurf", "windsurf", 10);
provider.provider_type = "windsurf".to_string();
let endpoint = sample_endpoint(
"endpoint-windsurf-chat",
"provider-windsurf",
"openai:chat",
"https://server.codeium.com",
);
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
vec![provider],
vec![endpoint],
vec![],
));
let state = AppState::new()
.expect("gateway should build")
.with_data_state_for_tests(GatewayDataState::with_provider_catalog_reader_for_tests(
provider_catalog_repository,
));
let response = local_admin_provider_oauth_response(
&state,
http::Method::POST,
"/api/admin/provider-oauth/providers/provider-windsurf/device-authorize",
Some(json!({
"auth_type": "browser",
"login_option": "github",
"proxy_node_id": "proxy-node-windsurf"
})),
)
.await;
assert_eq!(response.status(), StatusCode::OK);
let body = to_bytes(response.into_body(), usize::MAX)
.await
.expect("body should read");
let payload: serde_json::Value = serde_json::from_slice(&body).expect("json body should parse");
let session_id = payload["session_id"]
.as_str()
.expect("session_id should exist");
assert_eq!(payload["auth_type"], "browser");
assert_eq!(payload["login_option"], "github");
assert_eq!(payload["redirect_uri"], "show-auth-token");
assert_eq!(payload["callback_required"], true);
let authorization_url = payload["verification_uri_complete"]
.as_str()
.expect("authorization url should exist");
let parsed = url::Url::parse(authorization_url).expect("authorization url should parse");
let params = parsed
.query_pairs()
.into_owned()
.collect::<std::collections::BTreeMap<_, _>>();
assert_eq!(
parsed.as_str().split('?').next(),
Some("https://windsurf.com/windsurf/signin")
);
assert_eq!(
params.get("response_type").map(String::as_str),
Some("token")
);
assert_eq!(params.get("state").map(String::as_str), Some(session_id));
assert_eq!(
params.get("redirect_uri").map(String::as_str),
Some("show-auth-token")
);
assert_eq!(
params.get("redirect_parameters_type").map(String::as_str),
Some("query")
);
let stored = state
.load_provider_oauth_device_session_for_tests(&format!("device_auth_session:{session_id}"))
.expect("device session should be stored");
let stored: serde_json::Value =
serde_json::from_str(&stored).expect("device session json should parse");
assert_eq!(stored["provider_id"], "provider-windsurf");
assert_eq!(stored["auth_type"], "browser");
assert_eq!(stored["social_provider"], "github");
assert_eq!(stored["redirect_uri"], "show-auth-token");
assert_eq!(stored["proxy_node_id"], "proxy-node-windsurf");
assert_eq!(stored["status"], "pending");
}
#[tokio::test]
async fn gateway_rejects_generic_oauth_start_for_windsurf_provider() {
let mut provider = sample_provider("provider-windsurf", "windsurf", 10);
provider.provider_type = "windsurf".to_string();
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
vec![provider],
vec![],
vec![],
));
let state = AppState::new()
.expect("gateway should build")
.with_data_state_for_tests(GatewayDataState::with_provider_catalog_reader_for_tests(
provider_catalog_repository,
));
let response = local_admin_provider_oauth_response(
&state,
http::Method::POST,
"/api/admin/provider-oauth/providers/provider-windsurf/start",
None,
)
.await;
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
let body = to_bytes(response.into_body(), usize::MAX)
.await
.expect("body should read");
let payload: serde_json::Value = serde_json::from_slice(&body).expect("json body should parse");
assert!(
payload["detail"]
.as_str()
.is_some_and(|detail| detail.contains("浏览器登录")),
"payload={payload}"
);
}
#[tokio::test]
async fn gateway_handles_admin_provider_oauth_device_poll_for_windsurf_callback_token() {
let execution_plans = Arc::new(Mutex::new(Vec::<ExecutionPlan>::new()));
let execution_plans_clone = Arc::clone(&execution_plans);
let execution_runtime = Router::new().route(
"/v1/execute/sync",
any(move |Json(plan): Json<ExecutionPlan>| {
let execution_plans_inner = Arc::clone(&execution_plans_clone);
async move {
execution_plans_inner
.lock()
.expect("mutex should lock")
.push(plan.clone());
if plan.request_id == "provider-oauth:windsurf-register:new" {
return Json(windsurf_register_user_execution_result(&plan.request_id));
}
Json(json!({
"request_id": plan.request_id,
"status_code": 200,
"headers": {
"content-type": "application/json"
},
"body": {
"json_body": {}
}
}))
}
}),
);
let mut provider = sample_provider("provider-windsurf", "windsurf", 10);
provider.provider_type = "windsurf".to_string();
let endpoint = sample_endpoint(
"endpoint-windsurf-chat",
"provider-windsurf",
"openai:chat",
"https://server.codeium.com",
);
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
vec![provider],
vec![endpoint],
vec![],
));
let mut proxy_node = sample_proxy_node("proxy-node-windsurf");
proxy_node.status = "online".to_string();
proxy_node.is_manual = true;
proxy_node.tunnel_mode = false;
proxy_node.tunnel_connected = false;
proxy_node.proxy_url = Some("http://proxy.example:8080".to_string());
let proxy_node_repository = Arc::new(InMemoryProxyNodeRepository::seed(vec![proxy_node]));
let (execution_runtime_url, execution_runtime_handle) = start_server(execution_runtime).await;
let state = build_state_with_execution_runtime_override(execution_runtime_url)
.with_data_state_for_tests(
GatewayDataState::with_provider_catalog_repository_for_tests(
provider_catalog_repository.clone(),
)
.with_encryption_key_for_tests(DEVELOPMENT_ENCRYPTION_KEY)
.attach_proxy_node_repository_for_tests(proxy_node_repository),
)
.with_provider_oauth_device_session_entry_for_tests(
"session-windsurf",
json!({
"provider_id": "provider-windsurf",
"region": "",
"client_id": "",
"client_secret": "",
"device_code": "",
"auth_type": "browser",
"social_provider": "google",
"code_verifier": null,
"redirect_uri": "show-auth-token",
"machine_id": "123e4567-e89b-12d3-a456-426614174000",
"interval": 5,
"expires_at_unix_secs": 4_102_444_800u64,
"status": "pending",
"proxy_node_id": "proxy-node-windsurf",
"created_at_unix_ms": 1_711_000_000u64,
"key_id": null,
"email": null,
"replaced": false,
"error_msg": null,
}),
);
let response = local_admin_provider_oauth_response(
&state,
http::Method::POST,
"/api/admin/provider-oauth/providers/provider-windsurf/device-poll",
Some(json!({
"session_id": "session-windsurf",
"callback_url": "https://windsurf.com/show-auth-token?token=firebase-id-token&state=session-windsurf&provider=google"
})),
)
.await;
let status = response.status();
let body = to_bytes(response.into_body(), usize::MAX)
.await
.expect("body should read");
let payload: serde_json::Value = serde_json::from_slice(&body).expect("json body should parse");
assert_eq!(status, StatusCode::OK, "payload={payload}");
assert_eq!(payload["status"], "authorized");
assert_eq!(payload["replaced"], false);
let stored = state
.load_provider_oauth_device_session_for_tests("device_auth_session:session-windsurf")
.expect("device session should persist");
let stored: serde_json::Value =
serde_json::from_str(&stored).expect("device session json should parse");
assert_eq!(stored["status"], "authorized");
let key_id = stored["key_id"]
.as_str()
.expect("key_id should be stored")
.to_string();
assert_eq!(payload["key_id"], key_id);
let persisted = provider_catalog_repository
.list_keys_by_ids(std::slice::from_ref(&key_id))
.await
.expect("keys should load")
.into_iter()
.next()
.expect("persisted key should exist");
assert_eq!(persisted.auth_type, "oauth");
assert_eq!(
persisted.proxy,
Some(json!({"node_id": "proxy-node-windsurf", "enabled": true}))
);
let decrypted_api_key = decrypt_python_fernet_ciphertext(
DEVELOPMENT_ENCRYPTION_KEY,
persisted
.encrypted_api_key
.as_deref()
.expect("api key should be present"),
)
.expect("api key should decrypt");
assert_eq!(decrypted_api_key, "devin-session-token$registered");
let decrypted_auth_config = decrypt_python_fernet_ciphertext(
DEVELOPMENT_ENCRYPTION_KEY,
persisted
.encrypted_auth_config
.as_deref()
.expect("auth config should exist"),
)
.expect("auth config should decrypt");
let auth_config: serde_json::Value =
serde_json::from_str(&decrypted_auth_config).expect("auth config should parse");
assert_eq!(auth_config["provider_type"], "windsurf");
assert_eq!(auth_config["auth_method"], "browser");
assert_eq!(auth_config["register_source"], "new");
assert_eq!(auth_config["social_provider"], "google");
{
let plans = execution_plans.lock().expect("mutex should lock");
let register_plan = plans
.iter()
.find(|plan| plan.request_id == "provider-oauth:windsurf-register:new")
.expect("register plan should execute");
assert_eq!(register_plan.method, "POST");
assert_eq!(
register_plan
.body
.json_body
.as_ref()
.and_then(|body| body.get("firebase_id_token"))
.and_then(serde_json::Value::as_str),
Some("firebase-id-token")
);
assert_eq!(
register_plan
.proxy
.as_ref()
.and_then(|proxy| proxy.node_id.as_deref()),
Some("proxy-node-windsurf")
);
}
execution_runtime_handle.abort();
}
#[tokio::test]
async fn gateway_rejects_windsurf_callback_state_mismatch_and_missing_token() {
let mut provider = sample_provider("provider-windsurf", "windsurf", 10);
provider.provider_type = "windsurf".to_string();
let endpoint = sample_endpoint(
"endpoint-windsurf-chat",
"provider-windsurf",
"openai:chat",
"https://server.codeium.com",
);
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
vec![provider],
vec![endpoint],
vec![],
));
let state = AppState::new()
.expect("gateway should build")
.with_data_state_for_tests(GatewayDataState::with_provider_catalog_reader_for_tests(
provider_catalog_repository,
))
.with_provider_oauth_device_session_entry_for_tests(
"session-windsurf",
json!({
"provider_id": "provider-windsurf",
"region": "",
"client_id": "",
"client_secret": "",
"device_code": "",
"auth_type": "browser",
"social_provider": "google",
"code_verifier": null,
"redirect_uri": "show-auth-token",
"machine_id": "123e4567-e89b-12d3-a456-426614174000",
"interval": 5,
"expires_at_unix_secs": 4_102_444_800u64,
"status": "pending",
"proxy_node_id": null,
"created_at_unix_ms": 1_711_000_000u64,
"key_id": null,
"email": null,
"replaced": false,
"error_msg": null,
}),
);
let response = local_admin_provider_oauth_response(
&state,
http::Method::POST,
"/api/admin/provider-oauth/providers/provider-windsurf/device-poll",
Some(json!({
"session_id": "session-windsurf",
"callback_url": "https://windsurf.com/show-auth-token?token=firebase-id-token&state=wrong-state"
})),
)
.await;
assert_eq!(response.status(), StatusCode::OK);
let body = to_bytes(response.into_body(), usize::MAX)
.await
.expect("body should read");
let payload: serde_json::Value = serde_json::from_slice(&body).expect("json body should parse");
assert_eq!(payload["status"], "error");
assert!(payload["error"]
.as_str()
.is_some_and(|error| error.contains("state")));
let response = local_admin_provider_oauth_response(
&state,
http::Method::POST,
"/api/admin/provider-oauth/providers/provider-windsurf/device-poll",
Some(json!({
"session_id": "session-windsurf",
"callback_url": "https://windsurf.com/show-auth-token?state=session-windsurf"
})),
)
.await;
assert_eq!(response.status(), StatusCode::OK);
let body = to_bytes(response.into_body(), usize::MAX)
.await
.expect("body should read");
let payload: serde_json::Value = serde_json::from_slice(&body).expect("json body should parse");
assert_eq!(payload["status"], "error");
assert!(payload["error"]
.as_str()
.is_some_and(|error| error.contains("token")));
}
#[tokio::test]
async fn gateway_handles_admin_provider_oauth_device_authorize_locally_with_trusted_admin_principal(
) {
@@ -2477,6 +2880,7 @@ async fn gateway_completes_admin_provider_oauth_key_locally_with_trusted_admin_p
.expect("account_state_recheck_error should be string when recheck is attempted");
assert!(
account_state_recheck_error == "wham/usage API 返回状态码 401"
|| account_state_recheck_error == "wham/usage API 返回状态码 403"
|| account_state_recheck_error.starts_with("wham/usage 请求执行失败:"),
"unexpected account_state_recheck_error: {account_state_recheck_error}"
);
@@ -4948,6 +5352,7 @@ async fn gateway_refreshes_admin_provider_oauth_key_locally_with_trusted_admin_p
.expect("account_state_recheck_error should be string when attempted");
assert!(
account_state_recheck_error == "wham/usage API 返回状态码 401"
|| account_state_recheck_error == "wham/usage API 返回状态码 403"
|| account_state_recheck_error.starts_with("wham/usage 请求执行失败:"),
"unexpected account_state_recheck_error: {account_state_recheck_error}"
);
@@ -4997,6 +5402,14 @@ async fn gateway_refreshes_admin_provider_oauth_key_locally_with_trusted_admin_p
stored_key.oauth_invalid_reason.as_deref(),
Some("[OAUTH_EXPIRED] Codex Token 无效或已过期 (401)")
);
} else if account_state_recheck_attempted
&& payload["account_state_recheck_error"] == "wham/usage API 返回状态码 403"
{
assert!(stored_key.oauth_invalid_at_unix_secs.is_some());
assert!(stored_key
.oauth_invalid_reason
.as_deref()
.is_some_and(|reason| reason.contains("(403)")));
} else {
assert_eq!(stored_key.oauth_invalid_at_unix_secs, None);
assert_eq!(stored_key.oauth_invalid_reason, None);
@@ -242,6 +242,144 @@ async fn gateway_handles_admin_provider_query_models_fetches_upstream_for_select
execution_runtime_handle.abort();
}
#[tokio::test]
async fn gateway_handles_admin_provider_query_models_fetches_windsurf_model_configs() {
let execution_runtime_hits = Arc::new(Mutex::new(0usize));
let execution_runtime_hits_clone = Arc::clone(&execution_runtime_hits);
let execution_runtime = Router::new().route(
"/v1/execute/sync",
any(move |Json(plan): Json<ExecutionPlan>| {
let execution_runtime_hits_inner = Arc::clone(&execution_runtime_hits_clone);
async move {
*execution_runtime_hits_inner
.lock()
.expect("mutex should lock") += 1;
assert_eq!(plan.method, "POST");
assert_eq!(
plan.url,
"https://server.codeium.com/exa.api_server_pb.ApiServerService/GetCascadeModelConfigs"
);
assert_eq!(plan.client_api_format, "openai:chat");
assert_eq!(plan.provider_api_format, "windsurf:model_configs");
assert_eq!(plan.model_name.as_deref(), Some("GetCascadeModelConfigs"));
assert_eq!(
plan.headers.get("connect-protocol-version").map(String::as_str),
Some("1")
);
assert_eq!(
plan.body
.json_body
.as_ref()
.and_then(|body| body.get("metadata"))
.and_then(|metadata| metadata.get("apiKey")),
Some(&json!("devin-session-token$abc"))
);
Json(json!({
"request_id": "req-provider-query-windsurf",
"status_code": 200,
"headers": {
"content-type": "application/json"
},
"body": {
"json_body": {
"clientModelConfigs": [{
"modelUid": "claude-sonnet-4-6",
"label": "Claude Sonnet 4.6",
"provider": "anthropic",
"supportsImages": true,
"creditMultiplier": 4
}],
"defaultOverrideModelConfig": {
"modelUid": "claude-sonnet-4-6"
}
}
}
}))
}
}),
);
let (execution_runtime_url, execution_runtime_handle) = start_server(execution_runtime).await;
let mut provider = sample_provider("provider-windsurf", "Windsurf", 10);
provider.provider_type = "windsurf".to_string();
let mut windsurf_key = sample_key(
"key-windsurf-selected",
"provider-windsurf",
"openai:chat",
"devin-session-token$abc",
);
windsurf_key.auth_type = "oauth".to_string();
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
vec![provider],
vec![StoredProviderCatalogEndpoint::new(
"endpoint-windsurf-chat".to_string(),
"provider-windsurf".to_string(),
"openai:chat".to_string(),
Some("chat".to_string()),
Some("primary".to_string()),
true,
)
.expect("endpoint should build")
.with_transport_fields(
"https://server.codeium.com".to_string(),
None,
None,
None,
None,
None,
None,
None,
)
.expect("endpoint transport should build")],
vec![windsurf_key],
));
let gateway = build_router_with_state(
build_state_with_execution_runtime_override(execution_runtime_url)
.with_data_state_for_tests(GatewayDataState::with_provider_transport_reader_for_tests(
provider_catalog_repository,
DEVELOPMENT_ENCRYPTION_KEY.to_string(),
)),
);
let (gateway_url, gateway_handle) = start_server(gateway).await;
let response = reqwest::Client::new()
.post(format!("{gateway_url}/api/admin/provider-query/models"))
.header(crate::constants::GATEWAY_HEADER, "rust-phase3b")
.header(TRUSTED_ADMIN_USER_ID_HEADER, "admin-user-123")
.header(TRUSTED_ADMIN_USER_ROLE_HEADER, "admin")
.header(TRUSTED_ADMIN_SESSION_ID_HEADER, "session-123")
.json(&json!({
"provider_id": "provider-windsurf",
"api_key_id": "key-windsurf-selected"
}))
.send()
.await
.expect("request should succeed");
assert_eq!(response.status(), StatusCode::OK);
let payload: serde_json::Value = response.json().await.expect("json body should parse");
assert_eq!(payload["success"], json!(true));
assert_eq!(payload["data"]["error"], serde_json::Value::Null);
assert_eq!(payload["data"]["from_cache"], json!(false));
let models = payload["data"]["models"]
.as_array()
.expect("models should be an array");
assert_eq!(models.len(), 1);
assert_eq!(models[0]["id"], json!("claude-sonnet-4-6"));
assert_eq!(
models[0]["api_formats"],
json!(["openai:chat", "openai:responses", "claude:messages"])
);
assert_eq!(
*execution_runtime_hits.lock().expect("mutex should lock"),
1
);
gateway_handle.abort();
execution_runtime_handle.abort();
}
#[tokio::test]
async fn gateway_handles_admin_provider_query_models_with_openai_responses_endpoint() {
let execution_runtime_hits = Arc::new(Mutex::new(0usize));
@@ -2245,6 +2383,122 @@ async fn gateway_routes_grok_responses_admin_pool_model_test_through_grok_runtim
execution_runtime_handle.abort();
}
#[tokio::test]
async fn gateway_streams_windsurf_connect_upstream_for_admin_model_test() {
let execution_runtime = Router::new().route(
"/v1/execute/sync",
any(move |Json(plan): Json<ExecutionPlan>| async move {
assert_eq!(plan.provider_id, "provider-windsurf");
assert_eq!(plan.endpoint_id, "endpoint-windsurf-chat");
assert_eq!(plan.key_id, "key-windsurf-primary");
assert_eq!(plan.provider_api_format, "openai:chat");
assert_eq!(plan.content_type.as_deref(), Some("application/connect+json"));
assert!(plan.stream, "Windsurf Connect model test must stream upstream");
assert_eq!(
plan.body
.json_body
.as_ref()
.and_then(|body| body.get("stream")),
Some(&json!(true))
);
let windsurf_payload = serde_json::to_vec(&json!({
"chatMessage": {
"text": "ok"
}
}))
.expect("windsurf payload should encode");
let mut windsurf_frame = vec![0u8];
windsurf_frame.extend_from_slice(&(windsurf_payload.len() as u32).to_be_bytes());
windsurf_frame.extend_from_slice(&windsurf_payload);
Json(json!({
"request_id": plan.request_id,
"candidate_id": plan.candidate_id,
"status_code": 200,
"headers": {
"content-type": "application/connect+json"
},
"body": {
"body_bytes_b64": base64::engine::general_purpose::STANDARD.encode(windsurf_frame)
},
"telemetry": {
"elapsed_ms": 24
}
}))
}),
);
let (execution_runtime_url, execution_runtime_handle) = start_server(execution_runtime).await;
let mut provider = sample_provider("provider-windsurf", "Windsurf", 10);
provider.provider_type = "windsurf".to_string();
let mut key = sample_key(
"key-windsurf-primary",
"provider-windsurf",
"openai:chat",
"devin-session-token$abc",
);
key.auth_type = "oauth".to_string();
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
vec![provider],
vec![sample_endpoint(
"endpoint-windsurf-chat",
"provider-windsurf",
"openai:chat",
"https://server.codeium.com",
)],
vec![key],
));
let gateway = build_router_with_state(
build_state_with_execution_runtime_override(execution_runtime_url)
.with_data_state_for_tests(GatewayDataState::with_provider_transport_reader_for_tests(
provider_catalog_repository,
DEVELOPMENT_ENCRYPTION_KEY.to_string(),
)),
);
let (gateway_url, gateway_handle) = start_server(gateway).await;
let response = reqwest::Client::new()
.post(format!("{gateway_url}/api/admin/provider-query/test-model"))
.header(GATEWAY_HEADER, "rust-phase3b")
.header(TRUSTED_ADMIN_USER_ID_HEADER, "admin-user-123")
.header(TRUSTED_ADMIN_USER_ROLE_HEADER, "admin")
.header(TRUSTED_ADMIN_SESSION_ID_HEADER, "session-123")
.json(&json!({
"provider_id": "provider-windsurf",
"model": "claude-opus-4-7-medium",
"api_format": "openai:chat",
"endpoint_id": "endpoint-windsurf-chat",
"request_body": {
"model": "claude-opus-4-7-medium",
"messages": [{
"role": "user",
"content": "Hello! This is a test message."
}],
"max_tokens": 30,
"temperature": 0.7,
"stream": true
}
}))
.send()
.await
.expect("request should succeed");
assert_eq!(response.status(), StatusCode::OK);
let payload: serde_json::Value = response.json().await.expect("json body should parse");
assert_eq!(payload["success"], json!(true));
assert_eq!(
payload["attempts"][0]["request_body"]["stream"],
json!(true)
);
assert_eq!(
payload["attempts"][0]["response_body"]["choices"][0]["message"]["content"],
json!("ok")
);
gateway_handle.abort();
execution_runtime_handle.abort();
}
#[tokio::test]
async fn gateway_uses_pool_scheduler_order_for_admin_pool_model_test() {
let execution_runtime = Router::new().route(