mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-01 17:00:21 +08:00
Align runtime miss tests with skipped candidates
This commit is contained in:
@@ -1610,6 +1610,7 @@ fn local_execution_runtime_miss_skip_reason_label(reason: &str) -> &str {
|
||||
"auth_snapshot_missing" => "API Key 本地执行配置缺失",
|
||||
"endpoint_api_format_changed" => "端点 API 格式已变更",
|
||||
"endpoint_inactive" => "端点未启用",
|
||||
"format_conversion_disabled" => "格式转换未启用",
|
||||
"key_api_format_disabled" => "API Key 未启用该 API 格式",
|
||||
"key_inactive" => "API Key 未启用",
|
||||
"key_model_disabled" => "API Key 未允许该模型",
|
||||
|
||||
@@ -952,20 +952,25 @@ async fn gateway_marks_claude_cli_cross_format_runtime_miss_when_format_conversi
|
||||
.headers()
|
||||
.get(LOCAL_EXECUTION_RUNTIME_MISS_REASON_HEADER)
|
||||
.and_then(|value| value.to_str().ok()),
|
||||
Some("candidate_list_empty")
|
||||
Some("all_candidates_skipped")
|
||||
);
|
||||
let response_json: serde_json::Value = response.json().await.expect("body should parse");
|
||||
assert_eq!(response_json["error"]["type"], "http_error");
|
||||
assert_eq!(
|
||||
response_json["error"]["message"],
|
||||
"没有可用提供商支持模型 gpt-5.4 的同步请求"
|
||||
"找到 1 个支持模型 gpt-5.4 的候选提供商,但本次同步请求全部不可用:格式转换未启用 2 次"
|
||||
);
|
||||
|
||||
let stored_candidates = request_candidate_repository
|
||||
.list_by_request_id("trace-claude-cli-openai-local-miss-123")
|
||||
.await
|
||||
.expect("request candidate trace should read");
|
||||
assert!(stored_candidates.is_empty());
|
||||
assert_eq!(stored_candidates.len(), 1);
|
||||
assert_eq!(stored_candidates[0].status, RequestCandidateStatus::Skipped);
|
||||
assert_eq!(
|
||||
stored_candidates[0].skip_reason.as_deref(),
|
||||
Some("format_conversion_disabled")
|
||||
);
|
||||
assert_eq!(*public_hits.lock().expect("mutex should lock"), 0);
|
||||
|
||||
gateway_handle.abort();
|
||||
|
||||
@@ -370,14 +370,18 @@ fn scheduler_candidate_runtime_paths_depend_on_scheduler_core_and_state_trait()
|
||||
}
|
||||
|
||||
let affinity = read_workspace_file("apps/aether-gateway/src/scheduler/candidate/affinity.rs");
|
||||
let ranking = read_workspace_file("apps/aether-gateway/src/scheduler/candidate/ranking.rs");
|
||||
let resolution =
|
||||
read_workspace_file("apps/aether-gateway/src/scheduler/candidate/resolution.rs");
|
||||
let candidate_runtime_path_source = format!("{affinity}\n{ranking}\n{resolution}");
|
||||
assert!(
|
||||
affinity.contains("SchedulerRuntimeState"),
|
||||
"candidate/affinity.rs should depend on SchedulerRuntimeState"
|
||||
);
|
||||
assert!(
|
||||
affinity.contains("aether_scheduler_core::{")
|
||||
&& affinity.contains("SchedulerAffinityTarget"),
|
||||
"candidate/affinity.rs should depend on core SchedulerAffinityTarget"
|
||||
candidate_runtime_path_source.contains("aether_scheduler_core::{")
|
||||
&& candidate_runtime_path_source.contains("SchedulerAffinityTarget"),
|
||||
"scheduler candidate runtime path should depend on core SchedulerAffinityTarget"
|
||||
);
|
||||
for pattern in [
|
||||
"candidate_affinity_hash",
|
||||
@@ -385,21 +389,21 @@ fn scheduler_candidate_runtime_paths_depend_on_scheduler_core_and_state_trait()
|
||||
"candidate_key",
|
||||
] {
|
||||
assert!(
|
||||
affinity.contains(pattern),
|
||||
"candidate/affinity.rs should depend on core affinity helper {pattern}"
|
||||
candidate_runtime_path_source.contains(pattern),
|
||||
"scheduler candidate runtime path should depend on core affinity helper {pattern}"
|
||||
);
|
||||
}
|
||||
assert!(
|
||||
!affinity.contains("use crate::AppState"),
|
||||
"candidate/affinity.rs should not depend on AppState directly"
|
||||
!candidate_runtime_path_source.contains("use crate::AppState"),
|
||||
"scheduler candidate runtime path should not depend on AppState directly"
|
||||
);
|
||||
assert!(
|
||||
!affinity.contains("crate::cache::SchedulerAffinityTarget"),
|
||||
"candidate/affinity.rs should not depend on gateway-local SchedulerAffinityTarget"
|
||||
!candidate_runtime_path_source.contains("crate::cache::SchedulerAffinityTarget"),
|
||||
"scheduler candidate runtime path should not depend on gateway-local SchedulerAffinityTarget"
|
||||
);
|
||||
assert!(
|
||||
!affinity.contains("use sha2::{Digest, Sha256};"),
|
||||
"candidate/affinity.rs should not own affinity hashing implementation anymore"
|
||||
!candidate_runtime_path_source.contains("use sha2::{Digest, Sha256};"),
|
||||
"scheduler candidate runtime path should not own affinity hashing implementation anymore"
|
||||
);
|
||||
for pattern in [
|
||||
"fn compare_affinity_order(",
|
||||
|
||||
@@ -1570,13 +1570,13 @@ async fn gateway_records_failed_usage_when_all_local_claude_cli_candidates_are_s
|
||||
.headers()
|
||||
.get(LOCAL_EXECUTION_RUNTIME_MISS_REASON_HEADER)
|
||||
.and_then(|value| value.to_str().ok()),
|
||||
Some("candidate_list_empty")
|
||||
Some("all_candidates_skipped")
|
||||
);
|
||||
let body_json: serde_json::Value = response.json().await.expect("body should parse");
|
||||
assert_eq!(body_json["error"]["type"], "http_error");
|
||||
assert_eq!(
|
||||
body_json["error"]["message"],
|
||||
"没有可用提供商支持模型 gpt-5.4 的同步请求"
|
||||
"找到 1 个支持模型 gpt-5.4 的候选提供商,但本次同步请求全部不可用:格式转换未启用 2 次"
|
||||
);
|
||||
|
||||
let stored_usage = wait_for_usage_status(
|
||||
@@ -1610,12 +1610,12 @@ async fn gateway_records_failed_usage_when_all_local_claude_cli_candidates_are_s
|
||||
);
|
||||
assert_eq!(
|
||||
stored_usage.routing_local_execution_runtime_miss_reason(),
|
||||
Some("candidate_list_empty")
|
||||
Some("all_candidates_skipped")
|
||||
);
|
||||
assert_eq!(
|
||||
stored_usage.error_message.as_deref(),
|
||||
Some(
|
||||
"没有可用提供商支持模型 gpt-5.4 的同步请求。请检查模型映射、端点启用状态和 API Key 权限(原因代码: candidate_list_empty)"
|
||||
"找到 1 个支持模型 gpt-5.4 的候选提供商,但本次同步请求全部不可用:格式转换未启用 2 次(原因代码: all_candidates_skipped)"
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -1656,7 +1656,12 @@ async fn gateway_records_failed_usage_when_all_local_claude_cli_candidates_are_s
|
||||
.list_by_request_id("trace-claude-cli-usage-local-miss-123")
|
||||
.await
|
||||
.expect("request candidate trace should read");
|
||||
assert!(stored_candidates.is_empty());
|
||||
assert_eq!(stored_candidates.len(), 1);
|
||||
assert_eq!(stored_candidates[0].status, RequestCandidateStatus::Skipped);
|
||||
assert_eq!(
|
||||
stored_candidates[0].skip_reason.as_deref(),
|
||||
Some("format_conversion_disabled")
|
||||
);
|
||||
assert_eq!(stored_usage.routing_candidate_id(), None);
|
||||
assert_eq!(*public_hits.lock().expect("mutex should lock"), 0);
|
||||
|
||||
@@ -1878,7 +1883,7 @@ async fn gateway_keeps_failed_usage_request_capture_lightweight_for_large_local_
|
||||
.headers()
|
||||
.get(LOCAL_EXECUTION_RUNTIME_MISS_REASON_HEADER)
|
||||
.and_then(|value| value.to_str().ok()),
|
||||
Some("candidate_list_empty")
|
||||
Some("all_candidates_skipped")
|
||||
);
|
||||
|
||||
let stored_usage = wait_for_usage_status(
|
||||
@@ -1914,7 +1919,12 @@ async fn gateway_keeps_failed_usage_request_capture_lightweight_for_large_local_
|
||||
.list_by_request_id("trace-claude-cli-usage-local-miss-large-123")
|
||||
.await
|
||||
.expect("request candidate trace should read");
|
||||
assert!(stored_candidates.is_empty());
|
||||
assert_eq!(stored_candidates.len(), 1);
|
||||
assert_eq!(stored_candidates[0].status, RequestCandidateStatus::Skipped);
|
||||
assert_eq!(
|
||||
stored_candidates[0].skip_reason.as_deref(),
|
||||
Some("format_conversion_disabled")
|
||||
);
|
||||
|
||||
gateway_handle.abort();
|
||||
execution_runtime_handle.abort();
|
||||
|
||||
Reference in New Issue
Block a user