feat: track official versions and import resources

Persist official version-state, extend CAS/ResourceRepository import classification, and add offline catalog and failure regression fixtures.

Fixes #13

Fixes #12

Fixes #8
This commit is contained in:
2026-07-15 19:53:10 +08:00
parent 4192d7ee4c
commit 90307a3243
30 changed files with 1269 additions and 157 deletions
+53
View File
@@ -2787,6 +2787,59 @@ exit 22
assert!(service.read_download_manifest().unwrap().entries.is_empty());
}
#[test]
fn official_http_failure_regression_fixtures_are_enforced() {
for fixture in [
include_str!("../tests/fixtures/official_regression/http_403.json"),
include_str!("../tests/fixtures/official_regression/http_404.json"),
] {
let fixture: serde_json::Value = serde_json::from_str(fixture).unwrap();
let out_dir = TempDir::new().unwrap();
let bin_dir = TempDir::new().unwrap();
let curl_path = bin_dir.path().join("curl");
let status = fixture["http_status"].as_u64().unwrap() as u16;
write_fake_http_error_curl(&curl_path, status);
let service =
OfficialResourcePullService::with_curl_command(out_dir.path(), &curl_path)
.with_retry_attempts(3);
let url = fixture["url"].as_str().unwrap();
let error = service.pull(&one_url_plan(url)).unwrap_err();
let expected_kind = fixture["failure_kind"].as_str().unwrap();
let expected_retryable = fixture["retryable"].as_bool().unwrap();
let expected_attempts = fixture["expected_attempts"].as_u64().unwrap();
assert!(error.contains(expected_kind));
assert!(error.contains(&format!("retryable={expected_retryable}")));
assert_eq!(
fs::read_to_string(curl_path.with_extension("state")).unwrap(),
expected_attempts.to_string()
);
let quarantine = service.read_download_quarantine().unwrap();
let entry = quarantine.entries.get(url).unwrap();
assert_eq!(entry.failure_kind.as_deref(), Some(expected_kind));
assert_eq!(entry.retryable, Some(expected_retryable));
assert_eq!(entry.attempts, expected_attempts as usize);
}
}
#[test]
fn official_hash_mismatch_regression_fixture_is_enforced() {
let fixture: serde_json::Value = serde_json::from_str(include_str!(
"../tests/fixtures/official_regression/hash_mismatch_catalog.json"
))
.unwrap();
let error = verify_official_seed_catalog_hash(
fixture["data_url"].as_str().unwrap(),
fixture["data"].as_str().unwrap().as_bytes(),
fixture["hash_url"].as_str().unwrap(),
fixture["official_hash"].as_str().unwrap().as_bytes(),
)
.unwrap_err();
assert!(error.contains(fixture["expected_error_contains"].as_str().unwrap()));
}
#[test]
fn retries_http_5xx_before_quarantine() {
let out_dir = TempDir::new().unwrap();