feat: add official full pull smoke

Emit runtime download progress and validation summaries for official sync.

Add repeatable real-network full pull smoke runbook and script.

Fixes #4

Fixes #6
This commit is contained in:
2026-07-14 00:48:59 +08:00
parent 2ff99ae9e3
commit 25c2c4d40f
15 changed files with 435 additions and 57 deletions
+42 -8
View File
@@ -1048,6 +1048,10 @@ impl OfficialUpdateService {
};
if !should_download {
progress(OfficialUpdateProgress::new(
"audit",
verification_progress_message(&report.verification_summary),
));
progress(OfficialUpdateProgress::new(
"finish",
"资源已是最新;无需下载",
@@ -1138,6 +1142,16 @@ impl OfficialUpdateService {
let final_audit = staging_fetcher
.audit_local_manifest(&pull_plan)
.map_err(anyhow::Error::msg)?;
let final_verification_summary = OfficialVerificationSummary::new(
final_audit.manifest_blake3_verified_count(),
final_audit.repair_needed_count(),
pull_report.official_hash_verified_count(),
final_audit.zip_structure_verified_count(),
);
progress(OfficialUpdateProgress::new(
"audit",
verification_progress_message(&final_verification_summary),
));
progress(OfficialUpdateProgress::new(
"snapshot",
format!("写入快照 {}", staging_snapshot_path.display()),
@@ -1175,12 +1189,7 @@ impl OfficialUpdateService {
report.official_seed_hash_verified_count = pull_report.official_hash_verified_count();
report.local_manifest_verified_count = final_audit.verified_count();
report.local_manifest_repair_needed_count = final_audit.repair_needed_count();
report.verification_summary = OfficialVerificationSummary::new(
final_audit.manifest_blake3_verified_count(),
final_audit.repair_needed_count(),
pull_report.official_hash_verified_count(),
final_audit.zip_structure_verified_count(),
);
report.verification_summary = final_verification_summary;
report.snapshot_written = Some(final_snapshot_path);
progress(OfficialUpdateProgress::new(
@@ -1356,7 +1365,13 @@ fn progress_from_pull_event(event: OfficialResourcePullProgress) -> OfficialUpda
match event.kind {
OfficialResourcePullProgressKind::Started => OfficialUpdateProgress::new(
"download",
format!("({}/{}) 开始 {}", event.index, event.total, event.url),
format!(
"下载进度:总体 {}/{} ({:.1}%);单文件开始 URL={}",
event.index,
event.total,
download_progress_percent(event.index, event.total),
event.url
),
)
.with_download_progress(&event),
OfficialResourcePullProgressKind::Finished => {
@@ -1364,9 +1379,10 @@ fn progress_from_pull_event(event: OfficialResourcePullProgress) -> OfficialUpda
OfficialUpdateProgress::new(
"download",
format!(
"({}/{}) 完成 状态={} 文件字节={} 本轮传输字节={} {}",
"下载进度:总体 {}/{} ({:.1}%);单文件完成 状态={} 文件字节={} 本轮传输字节={} URL={}",
event.index,
event.total,
download_progress_percent(event.index, event.total),
status,
event.bytes.unwrap_or(0),
event.transferred_bytes.unwrap_or(0),
@@ -1378,6 +1394,24 @@ fn progress_from_pull_event(event: OfficialResourcePullProgress) -> OfficialUpda
}
}
fn download_progress_percent(index: usize, total: usize) -> f64 {
if total == 0 {
100.0
} else {
(index as f64 / total as f64) * 100.0
}
}
fn verification_progress_message(summary: &OfficialVerificationSummary) -> String {
format!(
"校验结果:官方 .hash={};本地 BLAKE3 通过={};本地需修复={}ZIP 结构通过={}",
summary.official_hash_verified_count,
summary.local_manifest_blake3_verified_count,
summary.local_manifest_repair_needed_count,
summary.zip_structure_verified_count
)
}
fn localized_pull_status(status: crate::OfficialResourcePullStatus) -> &'static str {
match status {
crate::OfficialResourcePullStatus::SkippedExisting => "已复用",