This repository has no description
2.9 kB
86 lines
1#![cfg(feature = "instrument")]
2
3use knot_bench::{ChurnCount, CommitCount, HistorySpec, PathCount, build_history};
4use knot_git::instrument::measure;
5use knot_git::{Filter, Haves, PackBudget, Wants};
6use knot_pack::upload_pack;
7use knot_types::Oid;
8
9fn gate_spec() -> HistorySpec {
10 HistorySpec {
11 commits: CommitCount::new(32),
12 paths: PathCount::new(64),
13 churn: ChurnCount::new(4),
14 }
15}
16
17const SELECTION_ODB_READS: u64 = 129;
18const SERVER_FETCH_ODB_READS: u64 = 2;
19
20fn pkt(payload: &[u8]) -> Vec<u8> {
21 let mut out = format!("{:04x}", payload.len() + 4).into_bytes();
22 out.extend_from_slice(payload);
23 out
24}
25
26fn fetch_request(want: Oid) -> Vec<u8> {
27 let mut request = pkt(b"command=fetch\n");
28 request.extend_from_slice(b"0001");
29 request.extend(pkt(format!("want {}\n", want.to_hex()).as_bytes()));
30 request.extend(pkt(b"done\n"));
31 request.extend_from_slice(b"0000");
32 request
33}
34
35#[test]
36fn a_single_selection_walk_has_an_exact_odb_read_count() {
37 let history = build_history(gate_spec());
38 let tips = history.tips();
39 let (_selection, reads) = measure(|| {
40 history
41 .repo()
42 .select_pack_objects_filtered(
43 Wants::new(&tips),
44 Haves::new(&[]),
45 Filter::None,
46 PackBudget::unbounded(),
47 )
48 .unwrap()
49 });
50 assert_eq!(
51 reads.get(),
52 SELECTION_ODB_READS,
53 "the selection walk made {} explicit object loads through Repo::load_object. \
54 The gate pins this at {SELECTION_ODB_READS}. A lower count means the single-pass \
55 commit-walk fix landed. A higher count is a regression. The counter records loads \
56 on the calling thread only. gix's internal rev-walk decodes never reach load_object \
57 and stay uncounted. Update the constant only when the change is deliberate",
58 reads.get()
59 );
60}
61
62#[test]
63fn the_upload_pack_server_path_has_an_exact_odb_read_count() {
64 let history = build_history(gate_spec());
65 let tips = history.tips();
66 let walk = history
67 .repo()
68 .rev_walk(Wants::new(&tips), Haves::new(&[]))
69 .unwrap();
70 let hidden = walk
71 .iter()
72 .copied()
73 .find(|commit| *commit != history.tip())
74 .expect("multi-commit history has a non-tip commit to want");
75 let request = fetch_request(hidden);
76 let (_response, reads) = measure(|| upload_pack(history.repo(), &request).unwrap());
77 assert_eq!(
78 reads.get(),
79 SERVER_FETCH_ODB_READS,
80 "server fetch made {} Repo::load_object calls, gate pins {SERVER_FETCH_ODB_READS}. \
81 No-haves fetch enumerates inside gix, so only the want check and root peel reach \
82 load_object. A count near the old manual-walk figure means the full-clone fast path \
83 stopped firing",
84 reads.get()
85 );
86}