fix(m197): 复审 r1 的 P1 + 三条 P2(描述对齐行为 / 内部编号下屏 / kind 守卫 / gh-proxy 可覆盖)
P1(阻断)`java.auto_install` 的描述与行为不一致——那句会进 AI 工具的 JSON Schema `description`,等于让助手对用户说一件实现刻意不做的事: - `crates/core/src/setting/keys.rs`:改成「缺 Java 时在 Java 页标出推荐版本并可一键安装; 不会自动下载」,去掉 `(D13 基准 JDK17)`。 - `SettingsJavaAutoInstallHint` 中英两侧各补一句显式否定(「不会自己开始下载 —— 点「安装」 才会下」/ "Nothing is downloaded on its own — you press Install."),标签从「自动准备」改成 「缺 JDK 时推荐一档」;金表同步。 - 新增守卫 `the_auto_install_description_says_it_never_downloads_by_itself`(描述必须含 「不会自动下载」、不含旧说法与内部编号)。 P2-1 内部决策编号印在界面上:`SettingsJavaDownloadBaseline` 的 `Baseline (D13)` / `基准版本(D13)` → `Recommended baseline` / `推荐基准版本`(金表同步)。另加两条目录级守卫 (`no_user_visible_string_mentions_an_internal_decision_id` / `no_user_visible_string_carries_markdown_backticks`);后者顺带清掉 M168 遗留的 `FontCjkStatusHint` 里的 `ui.font_cdn` 反引号——全仓最后一条。 P2-2 `ProgressEvent::SourceFailed.kind` 没有守卫:`engine_mock_test` - `reports_progress_events_and_errors_when_all_sources_fail` 的解构补 `kind`,断言 `ServerError`; - 新增 `a_404_is_classified_as_not_found_and_never_cools_the_source_down`(404 → `NotFound`, 与「源坏了」分开)。 P2-3 交付任务书那句「(默认值可改)」:新增 `download.gh_proxy`(空 = 跟随内置默认 / `off` = 关 / 其它 = 覆盖前缀),`engine_with` 是它的真消费者(改 `RegionProfile`,因为 `gh_proxy_candidates` 读的就是档案里的前缀);Java 页不画 UI(归 M193)。**内置默认值没动**。 schema minor 1.7.0 → 1.8.0(新键必须推 minor),三处硬编码 minor 的用例同步。 另:真下载用例改成 panic 也清理(复审顺带项 7④);`downloads/refusal.rs` 的「四档」改「五档」。
This commit is contained in:
1 parent
9a7b138d08
commit
a14b00aced
15 files changed
+387
-28
No files matched your search
@@ -338,9 +338,19 @@ async fn reports_progress_events_and_errors_when_all_sources_fail() {
|
||||
started = true;
|
||||
assert!(candidates >= 1);
|
||||
}
|
||||
ProgressEvent::SourceFailed { will_retry, .. } => {
|
||||
ProgressEvent::SourceFailed {
|
||||
will_retry, kind, ..
|
||||
} => {
|
||||
failed_source = true;
|
||||
assert!(!will_retry, "单次尝试用尽后不应再声明重试");
|
||||
// M197:`kind` 是诊断字段,必须来自**真实**的失败分类(HTTP 500 → ServerError)。
|
||||
// 变异证明:把 `engine.rs` 的 `kind: err.kind` 写成常量
|
||||
// `DownloadErrorKind::Network` ⇒ 本断言红。
|
||||
assert_eq!(
|
||||
kind,
|
||||
DownloadErrorKind::ServerError,
|
||||
"HTTP 500 必须被分类成 ServerError(诊断字段不许是常量)"
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -348,3 +358,57 @@ async fn reports_progress_events_and_errors_when_all_sources_fail() {
|
||||
assert!(started && failed_source, "进度事件缺失");
|
||||
server.stop();
|
||||
}
|
||||
|
||||
/// `SourceFailed.kind` 的另一半:**404 不是「源坏了」**,是「该源没有这个文件」。
|
||||
///
|
||||
/// 这两档在引擎里的后果完全不同(`NotFound` 走 `record_missing`,不冷却源;`ServerError` 走
|
||||
/// `record_failure`)。把两者混成一个常量最贵的地方就在这里:院校镜像只留最新补丁,请求旧补丁
|
||||
/// 必然 404,判成「源坏了」会把唯一可用镜像冷却掉(M33/M34 实测)。
|
||||
///
|
||||
/// 变异证明:把 `engine.rs` / `bytes.rs` 两处 `kind: err.kind` 改成 `DownloadErrorKind::NotFound`
|
||||
/// 常量 ⇒ 上面那条 500 用例红;改成 `Network` ⇒ 本条红。
|
||||
#[tokio::test]
|
||||
async fn a_404_is_classified_as_not_found_and_never_cools_the_source_down() {
|
||||
let server = MockServer::start(vec![
|
||||
MockResponse::status(404),
|
||||
MockResponse::status(404),
|
||||
MockResponse::status(404),
|
||||
MockResponse::status(404),
|
||||
])
|
||||
.await;
|
||||
let url = server.url("/gone.jar");
|
||||
let dir = temp_dir("engine-404");
|
||||
let cache = Arc::new(ContentCache::open(dir.join("cache")));
|
||||
let (emitter, mut events) = ProgressEmitter::channel();
|
||||
let engine = DownloadEngine::new(
|
||||
fast_config(1),
|
||||
Arc::new(MirrorTable::builtin()),
|
||||
Arc::new(direct_region()),
|
||||
Arc::new(HealthRegistry::in_memory()),
|
||||
cache,
|
||||
)
|
||||
.with_progress(emitter);
|
||||
|
||||
let error = engine
|
||||
.download(DownloadRequest::new(
|
||||
ResourceKind::Library,
|
||||
url.as_str(),
|
||||
dir.join("gone.jar"),
|
||||
))
|
||||
.await
|
||||
.expect_err("只有 404 的源必须失败");
|
||||
assert_eq!(error.kind, DownloadErrorKind::AllSourcesFailed);
|
||||
|
||||
let mut seen: Vec<DownloadErrorKind> = Vec::new();
|
||||
while let Ok(event) = events.try_recv() {
|
||||
if let ProgressEvent::SourceFailed { kind, .. } = event {
|
||||
seen.push(kind);
|
||||
}
|
||||
}
|
||||
assert!(!seen.is_empty(), "至少要有一条 SourceFailed");
|
||||
assert!(
|
||||
seen.iter().all(|kind| *kind == DownloadErrorKind::NotFound),
|
||||
"404 必须分类成 NotFound,实际:{seen:?}"
|
||||
);
|
||||
server.stop();
|
||||
}
|
||||
Reference in new issue
Block a user