From ba11a72214db1fd903199f0cea546fd3e561e989 Mon Sep 17 00:00:00 2001 From: ZheFox <77232781+zhefox@users.noreply.github.com> Date: Fri, 4 Sep 2026 13:54:50 +0800 Subject: [PATCH] test(gateway): align CI fixtures with routing contracts --- .../src/ai_serving/finalize/tests_sync.rs | 5 ++-- .../src/tests/architecture/admin_provider.rs | 5 ++-- .../src/tests/control/admin/models/global.rs | 9 +++---- .../src/tests/control/admin/system.rs | 9 +++---- apps/aether-gateway/src/tests/frontdoor/ai.rs | 6 ++++- .../src/tests/frontdoor/internal.rs | 6 ++++- apps/aether-gateway/src/tests/proxy.rs | 25 ++++++++++++++++--- 7 files changed, 43 insertions(+), 22 deletions(-) diff --git a/apps/aether-gateway/src/ai_serving/finalize/tests_sync.rs b/apps/aether-gateway/src/ai_serving/finalize/tests_sync.rs index 2bf0b7aa4..cd34e1417 100644 --- a/apps/aether-gateway/src/ai_serving/finalize/tests_sync.rs +++ b/apps/aether-gateway/src/ai_serving/finalize/tests_sync.rs @@ -1,6 +1,5 @@ use std::collections::BTreeMap; -use aether_ai_formats::openai_responses_message_item_id; use axum::body::to_bytes; use base64::Engine as _; use serde_json::json; @@ -12,10 +11,10 @@ use super::{ convert_gemini_chat_response_to_openai_chat, convert_gemini_response_to_openai_responses, maybe_build_local_core_sync_finalize_response, }; -use crate::ai_serving::GatewayControlDecision; use crate::ai_serving::{ convert_openai_chat_response_to_openai_responses, - convert_openai_responses_response_to_openai_chat, + convert_openai_responses_response_to_openai_chat, openai_responses_message_item_id, + GatewayControlDecision, }; use crate::usage::GatewaySyncReportRequest; diff --git a/apps/aether-gateway/src/tests/architecture/admin_provider.rs b/apps/aether-gateway/src/tests/architecture/admin_provider.rs index b67ad922e..4173e3fe8 100644 --- a/apps/aether-gateway/src/tests/architecture/admin_provider.rs +++ b/apps/aether-gateway/src/tests/architecture/admin_provider.rs @@ -1963,8 +1963,9 @@ fn admin_provider_oauth_quota_mod_stays_thin() { "handlers/admin/provider/oauth/quota/antigravity.rs should import common quota helpers from shared.rs" ); assert!( - quota_antigravity - .contains("use aether_provider_pool::build_antigravity_pool_quota_request;"), + quota_antigravity.contains("use aether_provider_pool::{") + && quota_antigravity.contains("build_antigravity_pool_quota_request") + && quota_antigravity.contains("build_antigravity_pool_quota_summary_request"), "handlers/admin/provider/oauth/quota/antigravity.rs should delegate antigravity quota request construction to aether-provider-pool" ); let quota_chatgpt_web = read_workspace_file( diff --git a/apps/aether-gateway/src/tests/control/admin/models/global.rs b/apps/aether-gateway/src/tests/control/admin/models/global.rs index 38027db47..cec076492 100644 --- a/apps/aether-gateway/src/tests/control/admin/models/global.rs +++ b/apps/aether-gateway/src/tests/control/admin/models/global.rs @@ -850,10 +850,7 @@ async fn gateway_handles_admin_global_model_routing_locally_with_trusted_admin_p provider_catalog_repository, ) .with_global_model_repository_for_tests(global_model_repository) - .with_system_config_values_for_tests(vec![ - ("scheduling_mode".to_string(), json!("fixed_order")), - ("provider_priority_mode".to_string(), json!("global_key")), - ]), + .with_system_default_routing_group_for_tests(), ), ); let (gateway_url, gateway_handle) = start_server(gateway).await; @@ -876,8 +873,8 @@ async fn gateway_handles_admin_global_model_routing_locally_with_trusted_admin_p assert_eq!(payload["global_model_name"], "gpt-5"); assert_eq!(payload["display_name"], "GPT 5"); assert_eq!(payload["global_model_mappings"], json!(["gpt-5-upstream"])); - assert_eq!(payload["scheduling_mode"], "fixed_order"); - assert_eq!(payload["priority_mode"], "global_key"); + assert_eq!(payload["scheduling_mode"], "cache_affinity"); + assert_eq!(payload["priority_mode"], "provider"); assert_eq!(payload["total_providers"], 2); assert_eq!(payload["active_providers"], 2); diff --git a/apps/aether-gateway/src/tests/control/admin/system.rs b/apps/aether-gateway/src/tests/control/admin/system.rs index d2763f71a..b54269579 100644 --- a/apps/aether-gateway/src/tests/control/admin/system.rs +++ b/apps/aether-gateway/src/tests/control/admin/system.rs @@ -1948,7 +1948,7 @@ async fn gateway_validates_chat_pii_redaction_system_config_locally_with_trusted } #[tokio::test] -async fn gateway_handles_admin_system_provider_priority_mode_locally_with_bearer_admin_session() { +async fn gateway_rejects_removed_admin_system_provider_priority_mode_with_bearer_admin_session() { let upstream_hits = Arc::new(Mutex::new(0usize)); let upstream_hits_clone = Arc::clone(&upstream_hits); let upstream = Router::new().route( @@ -1962,7 +1962,7 @@ async fn gateway_handles_admin_system_provider_priority_mode_locally_with_bearer }), ); - let (upstream_url, upstream_handle) = start_server(upstream).await; + let (_upstream_url, upstream_handle) = start_server(upstream).await; let state = AppState::new().expect("gateway should build"); let access_token = issue_test_admin_access_token(&state, "device-admin-config").await; let gateway = build_router_with_state(state); @@ -1978,10 +1978,7 @@ async fn gateway_handles_admin_system_provider_priority_mode_locally_with_bearer .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["key"], "provider_priority_mode"); - assert_eq!(payload["value"], "provider"); + assert_eq!(response.status(), StatusCode::NOT_FOUND); assert_eq!(*upstream_hits.lock().expect("mutex should lock"), 0); gateway_handle.abort(); diff --git a/apps/aether-gateway/src/tests/frontdoor/ai.rs b/apps/aether-gateway/src/tests/frontdoor/ai.rs index 13bcd07e4..93bcc450a 100644 --- a/apps/aether-gateway/src/tests/frontdoor/ai.rs +++ b/apps/aether-gateway/src/tests/frontdoor/ai.rs @@ -5,6 +5,7 @@ use super::{ InMemoryVideoTaskRepository, StoredAuthApiKeySnapshot, UpsertVideoTask, VideoTaskLookupKey, VideoTaskReadRepository, VideoTaskStatus, VideoTaskWriteRepository, DEVELOPMENT_ENCRYPTION_KEY, }; +use crate::data::GatewayDataState; use crate::image_capabilities::openai_image_gateway_max_generation_count; use crate::tests::{ any, build_router_with_state, build_state_with_execution_runtime_override, json, start_server, @@ -3477,7 +3478,10 @@ async fn gateway_does_not_locally_reject_image_model_name_on_chat_completions() let gateway = build_router_with_state( AppState::new() .expect("gateway should build") - .with_auth_api_key_data_reader_for_tests(auth_repository), + .with_data_state_for_tests( + GatewayDataState::with_auth_api_key_reader_for_tests(auth_repository) + .with_system_default_routing_group_for_tests(), + ), ); let (gateway_url, gateway_handle) = start_server(gateway).await; diff --git a/apps/aether-gateway/src/tests/frontdoor/internal.rs b/apps/aether-gateway/src/tests/frontdoor/internal.rs index c2fba96f9..21313518b 100644 --- a/apps/aether-gateway/src/tests/frontdoor/internal.rs +++ b/apps/aether-gateway/src/tests/frontdoor/internal.rs @@ -5,6 +5,7 @@ use super::{ InMemoryProviderCatalogReadRepository, InMemoryRequestCandidateRepository, DEVELOPMENT_ENCRYPTION_KEY, }; +use crate::data::GatewayDataState; use crate::tests::{ any, build_router, build_router_with_state, build_state_with_execution_runtime_override, json, start_server, strip_sse_keepalive_comments, AppState, Arc, Body, HeaderValue, Json, Mutex, @@ -1301,7 +1302,10 @@ async fn gateway_returns_internal_gateway_decision_sync_fallback_with_resolved_a let gateway = build_router_with_state( AppState::new() .expect("gateway should build") - .with_auth_api_key_data_reader_for_tests(auth_repository), + .with_data_state_for_tests( + GatewayDataState::with_auth_api_key_reader_for_tests(auth_repository) + .with_system_default_routing_group_for_tests(), + ), ); let (gateway_url, gateway_handle) = start_server(gateway).await; diff --git a/apps/aether-gateway/src/tests/proxy.rs b/apps/aether-gateway/src/tests/proxy.rs index 81c9e6dda..f4a798aba 100644 --- a/apps/aether-gateway/src/tests/proxy.rs +++ b/apps/aether-gateway/src/tests/proxy.rs @@ -18,6 +18,10 @@ use aether_data::repository::provider_catalog::InMemoryProviderCatalogReadReposi use aether_data_contracts::repository::provider_catalog::{ StoredProviderCatalogEndpoint, StoredProviderCatalogKey, StoredProviderCatalogProvider, }; +use aether_scheduler_core::{ + build_scheduler_affinity_cache_key_for_api_key_id_with_client_session_and_scope, + SchedulerAffinityScope, +}; use sha2::{Digest, Sha256}; fn hash_api_key(value: &str) -> String { @@ -26,6 +30,18 @@ fn hash_api_key(value: &str) -> String { format!("{:x}", hasher.finalize()) } +fn system_default_affinity_cache_key(api_key_id: &str, api_format: &str, model: &str) -> String { + let scope = SchedulerAffinityScope::new("system-default", Some(1)); + build_scheduler_affinity_cache_key_for_api_key_id_with_client_session_and_scope( + api_key_id, + api_format, + model, + None, + Some(&scope), + ) + .expect("system-default affinity cache key should build") +} + fn sample_auth_snapshot( api_key_id: &str, user_id: &str, @@ -626,6 +642,7 @@ async fn gateway_forwards_public_request_to_remote_tunnel_owner_before_fallback_ "development-key", ) .with_auth_api_key_reader(auth_repository) + .with_system_default_routing_group_for_tests() .with_system_config_values_for_tests(vec![( tunnel_attachment_key("node-owner"), serde_json::to_value(crate::tunnel::TunnelAttachmentRecord { @@ -648,7 +665,7 @@ async fn gateway_forwards_public_request_to_remote_tunnel_owner_before_fallback_ state.client = short_timeout_client.clone(); state.owner_forward_client = short_timeout_client; state.remember_scheduler_affinity_target( - "scheduler_affinity:api-key-affinity-1:openai:chat:gpt-4.1", + &system_default_affinity_cache_key("api-key-affinity-1", "openai:chat", "gpt-4.1"), crate::cache::SchedulerAffinityTarget { provider_id: "provider-owner".to_string(), endpoint_id: "endpoint-owner".to_string(), @@ -853,6 +870,7 @@ async fn gateway_aggregates_sync_sse_from_remote_tunnel_owner_before_returning_t "development-key", ) .with_auth_api_key_reader(auth_repository) + .with_system_default_routing_group_for_tests() .with_system_config_values_for_tests(vec![( tunnel_attachment_key("node-cli-owner"), serde_json::to_value(crate::tunnel::TunnelAttachmentRecord { @@ -869,7 +887,7 @@ async fn gateway_aggregates_sync_sse_from_remote_tunnel_owner_before_returning_t .with_data_state_for_tests(data_state) .with_tunnel_identity_for_tests("gateway-a", Some("http://gateway-a:8080")); state.remember_scheduler_affinity_target( - "scheduler_affinity:api-key-affinity-cli-1:openai:responses:gpt-5.4", + &system_default_affinity_cache_key("api-key-affinity-cli-1", "openai:responses", "gpt-5.4"), crate::cache::SchedulerAffinityTarget { provider_id: "provider-cli-owner".to_string(), endpoint_id: "endpoint-cli-owner".to_string(), @@ -1100,6 +1118,7 @@ async fn gateway_streamifies_sync_json_from_remote_tunnel_owner_before_returning "development-key", ) .with_auth_api_key_reader(auth_repository) + .with_system_default_routing_group_for_tests() .with_system_config_values_for_tests(vec![( tunnel_attachment_key("node-cli-owner"), serde_json::to_value(crate::tunnel::TunnelAttachmentRecord { @@ -1120,7 +1139,7 @@ async fn gateway_streamifies_sync_json_from_remote_tunnel_owner_before_returning .build() .expect("short shared client should build"); state.remember_scheduler_affinity_target( - "scheduler_affinity:api-key-affinity-cli-1:openai:responses:gpt-5.4", + &system_default_affinity_cache_key("api-key-affinity-cli-1", "openai:responses", "gpt-5.4"), crate::cache::SchedulerAffinityTarget { provider_id: "provider-cli-owner".to_string(), endpoint_id: "endpoint-cli-owner".to_string(),