Skip to content

Commit 0c2bcb2

Browse files
committed
test(core): integration coverage for blob_fetcher early-return paths
`blob_fetcher_edges_e2e.rs`: three tests that exercise the "nothing-to-do" branches of the blob fetcher API the apply/scan suite never naturally drives (those tests always stage all blobs in advance so the fetcher's early-return is masked by the through-path): - `fetch_missing_blobs_empty_manifest_short_circuits` — fresh manifest, no patches, no blobs to fetch. - `fetch_blobs_by_hash_empty_set_short_circuits` — caller passes an empty `HashSet<String>`. - `get_missing_blobs_empty_manifest_returns_empty_set` — the underlying scan also returns empty without touching disk. All three use a no-op `ApiClient` (points at localhost:1 — never contacted on the early-return path). Workspace test sweep stays green. Assisted-by: Claude Code:claude-opus-4-7
1 parent b465992 commit 0c2bcb2

1 file changed

Lines changed: 74 additions & 0 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//! Integration coverage for `api::blob_fetcher`'s early-return /
2+
//! filesystem-error branches the existing apply/scan e2e tests
3+
//! never drive (those tests stage all blobs in advance so the
4+
//! fetcher only sees the "nothing to do" path through the inner
5+
//! loop).
6+
7+
use socket_patch_core::api::blob_fetcher::{
8+
fetch_blobs_by_hash, fetch_missing_blobs, get_missing_blobs,
9+
};
10+
use socket_patch_core::api::client::{ApiClient, ApiClientOptions};
11+
use socket_patch_core::manifest::schema::PatchManifest;
12+
use std::collections::HashSet;
13+
14+
/// Build an `ApiClient` that never actually performs network I/O.
15+
/// Tests below use it only to satisfy the `&ApiClient` parameter
16+
/// of fetcher functions whose early-return paths short-circuit
17+
/// before any HTTP call.
18+
fn dummy_client() -> ApiClient {
19+
ApiClient::new(ApiClientOptions {
20+
api_url: "http://127.0.0.1:1".to_string(),
21+
api_token: None,
22+
use_public_proxy: true,
23+
org_slug: None,
24+
})
25+
}
26+
27+
/// `fetch_missing_blobs` with a fresh manifest reports `total=0`
28+
/// downloaded=0 without touching the API — there's nothing to do.
29+
#[tokio::test]
30+
async fn fetch_missing_blobs_empty_manifest_short_circuits() {
31+
let tmp = tempfile::tempdir().unwrap();
32+
let blobs = tmp.path().join("blobs");
33+
std::fs::create_dir(&blobs).unwrap();
34+
let manifest = PatchManifest::new();
35+
let client = dummy_client();
36+
37+
let result = fetch_missing_blobs(&manifest, &blobs, &client, None).await;
38+
assert_eq!(result.total, 0);
39+
assert_eq!(result.downloaded, 0);
40+
assert_eq!(result.failed, 0);
41+
assert!(result.results.is_empty());
42+
}
43+
44+
/// `fetch_blobs_by_hash` with an empty set returns the empty-result
45+
/// envelope without I/O.
46+
#[tokio::test]
47+
async fn fetch_blobs_by_hash_empty_set_short_circuits() {
48+
let tmp = tempfile::tempdir().unwrap();
49+
let blobs = tmp.path().join("blobs");
50+
std::fs::create_dir(&blobs).unwrap();
51+
let hashes: HashSet<String> = HashSet::new();
52+
let client = dummy_client();
53+
54+
let result = fetch_blobs_by_hash(&hashes, &blobs, &client, None).await;
55+
assert_eq!(result.total, 0);
56+
assert_eq!(result.downloaded, 0);
57+
assert_eq!(result.failed, 0);
58+
assert!(result.results.is_empty());
59+
}
60+
61+
/// `get_missing_blobs` against a manifest that lists no patches
62+
/// returns the empty set. Covers the early-return inside the
63+
/// function — the existing apply tests always stage at least one
64+
/// patch, so this branch needed its own driver.
65+
#[tokio::test]
66+
async fn get_missing_blobs_empty_manifest_returns_empty_set() {
67+
let tmp = tempfile::tempdir().unwrap();
68+
let blobs = tmp.path().join("blobs");
69+
std::fs::create_dir(&blobs).unwrap();
70+
let manifest = PatchManifest::new();
71+
72+
let missing = get_missing_blobs(&manifest, &blobs).await;
73+
assert!(missing.is_empty());
74+
}

0 commit comments

Comments
 (0)