diff options
Diffstat (limited to 'vendor/gix-negotiate/tests/baseline')
-rw-r--r-- | vendor/gix-negotiate/tests/baseline/mod.rs | 226 |
1 files changed, 0 insertions, 226 deletions
diff --git a/vendor/gix-negotiate/tests/baseline/mod.rs b/vendor/gix-negotiate/tests/baseline/mod.rs deleted file mode 100644 index f4ba0449f..000000000 --- a/vendor/gix-negotiate/tests/baseline/mod.rs +++ /dev/null @@ -1,226 +0,0 @@ -use std::cell::RefCell; - -use gix_negotiate::Algorithm; -use gix_object::{bstr, bstr::ByteSlice}; -use gix_odb::{Find, FindExt}; -use gix_ref::{file::ReferenceExt, store::WriteReflog}; - -#[test] -fn run() -> crate::Result { - let root = gix_testtools::scripted_fixture_read_only("make_repos.sh")?; - for case in [ - "no_parents", - "clock_skew", - "two_colliding_skips", - "multi_round", - "advertisement_as_filter", - ] { - let base = root.join(case); - - for (algo_name, algo) in [ - ("noop", Algorithm::Noop), - ("consecutive", Algorithm::Consecutive), - ("skipping", Algorithm::Skipping), - ] { - let obj_buf = RefCell::new(Vec::new()); - let buf = std::fs::read(base.join(format!("baseline.{algo_name}")))?; - let store = gix_odb::at(base.join("client").join(".git/objects"))?; - let refs = gix_ref::file::Store::at( - base.join("client").join(".git"), - WriteReflog::Disable, - gix_hash::Kind::Sha1, - ); - let lookup_names = |names: &[&str]| -> Vec<gix_hash::ObjectId> { - names - .iter() - .filter_map(|name| { - refs.try_find(*name).expect("one tag per commit").map(|mut r| { - r.peel_to_id_in_place(&refs, &mut |id, buf| { - store.try_find(&id, buf).map(|d| d.map(|d| (d.kind, d.data))) - }) - .expect("works"); - r.target.into_id() - }) - }) - .collect() - }; - let message = |id: gix_hash::ObjectId| { - store - .find_commit(&id, obj_buf.borrow_mut().as_mut()) - .expect("present") - .message - .trim() - .as_bstr() - .to_owned() - }; - - let debug = false; - for use_cache in [false, true] { - let cache = use_cache - .then(|| gix_commitgraph::at(store.store_ref().path().join("info")).ok()) - .flatten(); - let mut graph = gix_revwalk::Graph::new( - |id, buf| { - store - .try_find(id, buf) - .map(|r| r.and_then(gix_object::Data::try_into_commit_iter)) - }, - cache, - ); - let mut negotiator = algo.into_negotiator(); - if debug { - eprintln!("ALGO {algo_name} CASE {case}"); - } - // // In --negotiate-only mode, which seems to be the only thing that's working after trying --dry-run, we unfortunately - // // don't get to see what happens if known-common commits are added as git itself doesn't do that in this mode - // // for some reason. - // for common in lookup_names(&["origin/main"]) { - // eprintln!("COMMON {name} {common}", name = message(common)); - // negotiator.known_common(common)?; - // } - for tip in lookup_names(&["HEAD"]).into_iter().chain( - refs.iter()? - .prefixed("refs/heads".as_ref())? - .filter_map(Result::ok) - .map(|r| r.target.into_id()), - ) { - if debug { - eprintln!("TIP {name} {tip}", name = message(tip)); - } - negotiator.add_tip(tip, &mut graph)?; - } - for (round, Round { mut haves, common }) in ParseRounds::new(buf.lines()).enumerate() { - if algo == Algorithm::Skipping { - if case == "clock_skew" { - // Here for some reason the prio-queue of git manages to not sort the parent of C2, which is in the future, to be - // ahead of old4 that is in the past. In the git version of this test, they say to expect exactly this sequence - // as well even though it's not actually happening (but that they can't see due to the way they are testing). - haves = lookup_names(&["c2", "c1", "old4", "old2", "old1"]); - } else if case == "two_colliding_skips" { - // The same thing, we actually get exactly the right order, whereas git for some reason doesn't. - // This is the order expected in the git tests. - haves = lookup_names(&["c5side", "c11", "c9", "c6", "c1"]); - } else if case == "multi_round" && round == 1 { - // Here, probably also because of priority queue quirks, `git` emits the commits out of order, with only one - // branch, b5 I think, being out of place. This list puts the expectation in the right order, which is ordered - // by commit date. - haves = lookup_names(&[ - "b8.c14", "b7.c14", "b6.c14", "b5.c14", "b4.c14", "b3.c14", "b2.c14", "b8.c9", "b7.c9", - "b6.c9", "b5.c9", "b4.c9", "b3.c9", "b2.c9", "b8.c1", "b7.c1", "b6.c1", "b5.c1", - "b4.c1", "b3.c1", "b2.c1", "b8.c0", "b7.c0", "b6.c0", "b5.c0", "b4.c0", "b3.c0", - "b2.c0", - ]); - } else if case == "advertisement_as_filter" { - haves = lookup_names(&["c2side", "c5", "origin/main"]) - .into_iter() - .chain(Some( - gix_hash::ObjectId::from_hex(b"f36cefa0be2ac180d360a54b1cc4214985cea60a").unwrap(), - )) - .collect(); - } - } - for have in haves { - let actual = negotiator.next_have(&mut graph).unwrap_or_else(|| { - panic!("{algo_name}:cache={use_cache}: one have per baseline: {have} missing or in wrong order", have = message(have)) - })?; - assert_eq!( - actual, - have, - "{algo_name}:cache={use_cache}: order and commit matches exactly, wanted {expected}, got {actual}, commits left: {:?}", - std::iter::from_fn(|| negotiator.next_have(&mut graph)).map(|id| message(id.unwrap())).collect::<Vec<_>>(), - actual = message(actual), - expected = message(have) - ); - if debug { - eprintln!("have {}", message(actual)); - } - } - for common_revision in common { - if debug { - eprintln!("ACK {}", message(common_revision)); - } - negotiator.in_common_with_remote(common_revision, &mut graph)?; - } - } - assert!( - negotiator.next_have(&mut graph).is_none(), - "{algo_name}:cache={use_cache}: negotiator should be depleted after all recorded baseline rounds" - ); - } - } - } - Ok(()) -} - -struct ParseRounds<'a> { - lines: bstr::Lines<'a>, -} - -impl<'a> ParseRounds<'a> { - pub fn new(mut lines: bstr::Lines<'a>) -> Self { - parse::command(&mut lines, parse::Command::Incoming).expect("handshake"); - Self { lines } - } -} - -impl<'a> Iterator for ParseRounds<'a> { - type Item = Round; - - fn next(&mut self) -> Option<Self::Item> { - let haves = parse::object_ids("have", parse::command(&mut self.lines, parse::Command::Outgoing)?); - let common = parse::object_ids("ACK", parse::command(&mut self.lines, parse::Command::Incoming)?); - if haves.is_empty() { - assert!(common.is_empty(), "cannot ack what's not there"); - return None; - } - Round { haves, common }.into() - } -} - -struct Round { - pub haves: Vec<gix_hash::ObjectId>, - pub common: Vec<gix_hash::ObjectId>, -} - -mod parse { - use gix_object::{ - bstr, - bstr::{BStr, ByteSlice}, - }; - - #[derive(Debug, Eq, PartialEq, Copy, Clone)] - pub enum Command { - Incoming, - Outgoing, - } - - pub fn object_ids(prefix: &str, lines: impl IntoIterator<Item = impl AsRef<[u8]>>) -> Vec<gix_hash::ObjectId> { - lines - .into_iter() - .filter_map(|line| { - line.as_ref() - .strip_prefix(prefix.as_bytes()) - .map(|id| gix_hash::ObjectId::from_hex(id.trim()).expect("valid hash")) - }) - .collect() - } - - pub fn command<'a>(lines: &mut bstr::Lines<'a>, wanted: Command) -> Option<Vec<&'a BStr>> { - let mut out = Vec::new(); - for line in lines { - let pos = line.find(b"fetch").expect("fetch token"); - let line_mode = match &line[pos + 5..][..2] { - b"< " => Command::Incoming, - b"> " => Command::Outgoing, - invalid => unreachable!("invalid fetch token: {:?}", invalid.as_bstr()), - }; - assert_eq!(line_mode, wanted, "command with unexpected mode"); - let line = line[pos + 7..].as_bstr(); - if line == "0000" { - break; - } - out.push(line); - } - (!out.is_empty()).then_some(out) - } -} |