From cec1877e180393eba0f6ddb0cf97bf3a791631c7 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 7 Jun 2024 07:48:42 +0200 Subject: Merging upstream version 1.75.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/gix-features-0.35.0/tests/features.rs | 1 + vendor/gix-features-0.35.0/tests/hash.rs | 13 +++ .../tests/parallel/in_order_iter.rs | 54 +++++++++ vendor/gix-features-0.35.0/tests/parallel/mod.rs | 125 +++++++++++++++++++++ .../gix-features-0.35.0/tests/parallel_shared.rs | 1 + .../tests/parallel_shared_threaded.rs | 1 + .../gix-features-0.35.0/tests/parallel_threaded.rs | 122 ++++++++++++++++++++ vendor/gix-features-0.35.0/tests/pipe.rs | 117 +++++++++++++++++++ vendor/gix-features-0.35.0/tests/trace/mod.rs | 15 +++ 9 files changed, 449 insertions(+) create mode 100644 vendor/gix-features-0.35.0/tests/features.rs create mode 100644 vendor/gix-features-0.35.0/tests/hash.rs create mode 100644 vendor/gix-features-0.35.0/tests/parallel/in_order_iter.rs create mode 100644 vendor/gix-features-0.35.0/tests/parallel/mod.rs create mode 100644 vendor/gix-features-0.35.0/tests/parallel_shared.rs create mode 100644 vendor/gix-features-0.35.0/tests/parallel_shared_threaded.rs create mode 100644 vendor/gix-features-0.35.0/tests/parallel_threaded.rs create mode 100644 vendor/gix-features-0.35.0/tests/pipe.rs create mode 100644 vendor/gix-features-0.35.0/tests/trace/mod.rs (limited to 'vendor/gix-features-0.35.0/tests') diff --git a/vendor/gix-features-0.35.0/tests/features.rs b/vendor/gix-features-0.35.0/tests/features.rs new file mode 100644 index 000000000..fc1f25c36 --- /dev/null +++ b/vendor/gix-features-0.35.0/tests/features.rs @@ -0,0 +1 @@ +mod trace; diff --git a/vendor/gix-features-0.35.0/tests/hash.rs b/vendor/gix-features-0.35.0/tests/hash.rs new file mode 100644 index 000000000..c8e48da57 --- /dev/null +++ b/vendor/gix-features-0.35.0/tests/hash.rs @@ -0,0 +1,13 @@ +use gix_features::hash::Sha1; + +#[cfg(not(feature = "fast-sha1"))] +#[test] +fn size_of_sha1() { + assert_eq!(std::mem::size_of::(), 96) +} + +#[cfg(feature = "fast-sha1")] +#[test] +fn size_of_sha1() { + assert_eq!(std::mem::size_of::(), 104) +} diff --git a/vendor/gix-features-0.35.0/tests/parallel/in_order_iter.rs b/vendor/gix-features-0.35.0/tests/parallel/in_order_iter.rs new file mode 100644 index 000000000..9e1881215 --- /dev/null +++ b/vendor/gix-features-0.35.0/tests/parallel/in_order_iter.rs @@ -0,0 +1,54 @@ +use std::convert::Infallible; + +use gix_features::parallel::InOrderIter; + +#[test] +fn in_order_stays_in_order() { + assert_eq!( + InOrderIter::from(vec![Ok::<_, Infallible>((0usize, 'a')), Ok((1, 'b')), Ok((2, 'c'))].into_iter()) + .collect::, _>>() + .expect("infallible"), + vec!['a', 'b', 'c'] + ) +} + +#[test] +fn out_of_order_items_are_held_until_the_sequence_is_complete() { + assert_eq!( + InOrderIter::from( + vec![ + Ok::<_, Infallible>((2usize, 'c')), + Ok((1, 'b')), + Ok((0, 'a')), + Ok((3, 'd')) + ] + .into_iter() + ) + .collect::, _>>() + .expect("infallible"), + vec!['a', 'b', 'c', 'd'] + ) +} + +#[test] +fn in_sequence_errors_immediately_trigger_a_fuse() { + let mut iter = InOrderIter::from(vec![Ok::<_, &'static str>((0usize, 'a')), Err("err"), Ok((1, 'b'))].into_iter()); + assert_eq!(iter.next(), Some(Ok('a'))); + assert_eq!(iter.next(), Some(Err("err"))); + assert_eq!( + iter.next(), + None, + "fuse should have triggered so we don't see anything else" + ); +} + +#[test] +fn out_of_sequence_errors_immediately_trigger_a_fuse() { + let mut iter = InOrderIter::from(vec![Ok::<_, &'static str>((1usize, 'b')), Err("err"), Ok((0, 'a'))].into_iter()); + assert_eq!(iter.next(), Some(Err("err"))); + assert_eq!( + iter.next(), + None, + "fuse should have triggered so we don't see anything else" + ); +} diff --git a/vendor/gix-features-0.35.0/tests/parallel/mod.rs b/vendor/gix-features-0.35.0/tests/parallel/mod.rs new file mode 100644 index 000000000..cc824332d --- /dev/null +++ b/vendor/gix-features-0.35.0/tests/parallel/mod.rs @@ -0,0 +1,125 @@ +//! Tests that are working similarly in parallel and serial mode +use gix_features::parallel; + +mod in_order_iter; + +#[derive(Default)] +struct Adder { + count: usize, +} + +impl parallel::Reduce for Adder { + type Input = usize; + type FeedProduce = usize; + type Output = usize; + type Error = (); + + fn feed(&mut self, item: Self::Input) -> Result { + self.count += item; + Ok(item) + } + + fn finalize(self) -> Result { + Ok(self.count) + } +} + +#[test] +fn in_parallel() { + let res = parallel::in_parallel( + std::iter::from_fn(|| Some(1)).take(100), + None, + |_n| (), + |input, _state| input, + Adder::default(), + ) + .expect("successful computation"); + assert_eq!(res, 100); +} + +#[test] +fn in_parallel_with_mut_slice_in_chunks() { + let num_items = 33; + let mut input: Vec<_> = std::iter::repeat(1).take(num_items).collect(); + let counts = parallel::in_parallel_with_slice( + &mut input, + None, + |_| 0usize, + |item, acc, _threads_eft, _should_interrupt| { + *acc += *item; + *item += 1; + Ok::<_, ()>(()) + }, + || Some(std::time::Duration::from_millis(10)), + std::convert::identity, + ) + .unwrap(); + let expected = std::iter::repeat(1).take(num_items).sum::(); + assert_eq!(counts.iter().sum::(), expected); + assert_eq!(input.iter().sum::(), expected * 2, "we increment each entry"); +} + +#[test] +fn stepped_reduce_next() { + let mut iter = parallel::reduce::Stepwise::new( + std::iter::from_fn(|| Some(1)).take(100), + None, + |_n| (), + |input, _state| input, + Adder::default(), + ); + + let mut aggregate = 0; + for value in iter.by_ref() { + aggregate += value.expect("success"); + } + assert_eq!(aggregate, 100); +} + +#[test] +fn stepped_reduce_ref_input_and_consume() { + let seq = std::sync::Arc::new(vec![0usize, 1, 2]); + struct ArcIter(std::sync::Arc>, usize); + impl Iterator for ArcIter { + type Item = usize; + + fn next(&mut self) -> Option { + let n = self.0.get(self.1).copied(); + self.1 += 1; + n + } + } + + let mut iter = parallel::reduce::Stepwise::new( + ArcIter(seq.clone(), 0).enumerate(), + None, + { + let seq = std::sync::Arc::clone(&seq); + move |_n| seq.len() + }, + { + let seq = std::sync::Arc::clone(&seq); + move |(idx, ref_val): (usize, usize), _state| seq[idx] * ref_val + }, + Adder::default(), + ); + + let mut aggregate = 0; + for value in iter.by_ref() { + aggregate += value.expect("success"); + } + assert_eq!(aggregate, 5); +} + +#[test] +fn stepped_reduce_finalize() { + let iter = parallel::reduce::Stepwise::new( + std::iter::from_fn(|| Some(1)).take(100), + None, + |_n| (), + |input, _state| input, + Adder::default(), + ); + + assert_eq!(iter.finalize().expect("success"), 100); +} diff --git a/vendor/gix-features-0.35.0/tests/parallel_shared.rs b/vendor/gix-features-0.35.0/tests/parallel_shared.rs new file mode 100644 index 000000000..055a899ea --- /dev/null +++ b/vendor/gix-features-0.35.0/tests/parallel_shared.rs @@ -0,0 +1 @@ +mod parallel; diff --git a/vendor/gix-features-0.35.0/tests/parallel_shared_threaded.rs b/vendor/gix-features-0.35.0/tests/parallel_shared_threaded.rs new file mode 100644 index 000000000..055a899ea --- /dev/null +++ b/vendor/gix-features-0.35.0/tests/parallel_shared_threaded.rs @@ -0,0 +1 @@ +mod parallel; diff --git a/vendor/gix-features-0.35.0/tests/parallel_threaded.rs b/vendor/gix-features-0.35.0/tests/parallel_threaded.rs new file mode 100644 index 000000000..05f49d195 --- /dev/null +++ b/vendor/gix-features-0.35.0/tests/parallel_threaded.rs @@ -0,0 +1,122 @@ +mod optimize_chunk_size_and_thread_limit { + use gix_features::parallel::optimize_chunk_size_and_thread_limit; + + #[test] + fn not_enough_chunks_for_threads() { + assert_eq!( + optimize_chunk_size_and_thread_limit(1, Some(10), None, Some(10)), + (1, Some(5), 5) + ); + assert_eq!( + optimize_chunk_size_and_thread_limit(1, Some(10), Some(3), Some(10)), + (1, Some(3), 3), + "the thread limit is always respected" + ); + } + + #[test] + fn some_more_chunks_per_thread() { + assert_eq!( + optimize_chunk_size_and_thread_limit(1, Some(30), None, Some(10)), + (1, Some(10), 10) + ); + assert_eq!( + optimize_chunk_size_and_thread_limit(1, Some(30), Some(5), Some(10)), + (3, Some(5), 5), + "the thread limit is always respected" + ); + } + + #[test] + fn chunk_size_too_small() { + assert_eq!( + optimize_chunk_size_and_thread_limit(1, Some(100), None, Some(10)), + (5, Some(10), 10) + ); + assert_eq!( + optimize_chunk_size_and_thread_limit(1, Some(100), Some(5), Some(10)), + (10, Some(5), 5), + "the thread limit is always respected" + ); + } + + #[test] + fn chunk_size_too_big() { + assert_eq!( + optimize_chunk_size_and_thread_limit(50, Some(100), None, Some(10)), + (5, Some(10), 10) + ); + assert_eq!( + optimize_chunk_size_and_thread_limit(50, Some(100), Some(5), Some(10)), + (10, Some(5), 5), + "the thread limit is always respected" + ); + } + + mod unknown_chunk_count { + use gix_features::parallel::optimize_chunk_size_and_thread_limit; + + #[test] + fn medium_chunk_size_many_threads() { + assert_eq!( + optimize_chunk_size_and_thread_limit(50, None, None, Some(4)), + (50, Some(4), 4), + "really, what do we know" + ); + } + + #[test] + fn medium_chunk_size_single_thread() { + assert_eq!( + optimize_chunk_size_and_thread_limit(50, None, None, Some(1)), + (50, Some(1), 1), + "single threaded - we don't touch that" + ); + } + + #[test] + fn small_chunk_size_single_thread() { + assert_eq!( + optimize_chunk_size_and_thread_limit(1, None, None, Some(1)), + (1, Some(1), 1), + "single threaded - we don't touch that" + ); + } + + #[test] + fn small_chunk_size_many_threads() { + assert_eq!( + optimize_chunk_size_and_thread_limit(1, None, None, Some(4)), + (50, Some(4), 4), + "we prefer an arbitrary number, which should really be based on effort, but the caller has to adjust for that" + ); + } + } + + mod real_values { + use gix_features::parallel::optimize_chunk_size_and_thread_limit; + + #[test] + fn linux_kernel_pack_my_machine_lookup() { + assert_eq!( + optimize_chunk_size_and_thread_limit(10000, Some(7_500_000), None, Some(4)), + (1000, Some(4), 4), + "the bucket size is capped actually, somewhat arbitrarily" + ); + } + + #[test] + fn linux_kernel_pack_my_machine_indexed() { + assert_eq!( + optimize_chunk_size_and_thread_limit(1, None, None, Some(4)), + (50, Some(4), 4), + "low values are raised to arbitrary value" + ); + assert_eq!( + optimize_chunk_size_and_thread_limit(10000, None, None, Some(4)), + (1000, Some(4), 4), + "high values are capped" + ); + } + } +} diff --git a/vendor/gix-features-0.35.0/tests/pipe.rs b/vendor/gix-features-0.35.0/tests/pipe.rs new file mode 100644 index 000000000..38cd8e598 --- /dev/null +++ b/vendor/gix-features-0.35.0/tests/pipe.rs @@ -0,0 +1,117 @@ +mod io { + use std::io::{BufRead, ErrorKind, Read, Write}; + + use gix_features::io; + + #[test] + fn threaded_read_to_end() { + let (mut writer, mut reader) = gix_features::io::pipe::unidirectional(0); + + let message = "Hello, world!"; + std::thread::spawn(move || { + writer + .write_all(message.as_bytes()) + .expect("writes to work if reader is present") + }); + + let mut received = String::new(); + reader.read_to_string(&mut received).unwrap(); + + assert_eq!(&received, message); + } + + #[test] + fn lack_of_reader_fails_with_broken_pipe() { + let (mut writer, _) = io::pipe::unidirectional(0); + assert_eq!( + writer.write_all(b"must fail").unwrap_err().kind(), + ErrorKind::BrokenPipe + ); + } + #[test] + fn line_reading_one_by_one() { + let (mut writer, mut reader) = io::pipe::unidirectional(2); + writer.write_all(b"a\n").expect("success"); + writer.write_all(b"b\nc").expect("success"); + drop(writer); + let mut buf = String::new(); + for expected in &["a\n", "b\n", "c"] { + buf.clear(); + assert_eq!(reader.read_line(&mut buf).expect("success"), expected.len()); + assert_eq!(buf, *expected); + } + } + + #[test] + fn line_reading() { + let (mut writer, reader) = io::pipe::unidirectional(2); + writer.write_all(b"a\n").expect("success"); + writer.write_all(b"b\nc\n").expect("success"); + drop(writer); + assert_eq!( + reader.lines().map_while(Result::ok).collect::>(), + vec!["a", "b", "c"] + ) + } + + #[test] + fn writer_can_inject_errors() { + let (writer, mut reader) = io::pipe::unidirectional(1); + writer + .channel + .send(Err(std::io::Error::new(std::io::ErrorKind::Other, "the error"))) + .expect("send success"); + let mut buf = [0]; + assert_eq!( + reader.read(&mut buf).unwrap_err().to_string(), + "the error", + "using Read trait, errors are propagated" + ); + + writer + .channel + .send(Err(std::io::Error::new(std::io::ErrorKind::Other, "the error"))) + .expect("send success"); + assert_eq!( + reader.fill_buf().unwrap_err().to_string(), + "the error", + "using BufRead trait, errors are propagated" + ); + } + + #[test] + fn continue_on_empty_writes() { + let (mut writer, mut reader) = io::pipe::unidirectional(2); + writer.write_all(&[]).expect("write successful and non-blocking"); + let input = b"hello"; + writer + .write_all(input) + .expect("second write works as well as there is capacity"); + let mut buf = vec![0u8; input.len()]; + assert_eq!(reader.read(&mut buf).expect("read succeeds"), input.len()); + assert_eq!(buf, &input[..]); + } + + #[test] + fn small_reads() { + const BLOCK_SIZE: usize = 20; + let block_count = 20; + let (mut writer, mut reader) = io::pipe::unidirectional(4); + std::thread::spawn(move || { + for _ in 0..block_count { + let data = &[0; BLOCK_SIZE]; + writer.write_all(data).unwrap(); + } + }); + + let mut small_read_buf = [0; BLOCK_SIZE / 2]; + let mut bytes_read = 0; + while let Ok(size) = reader.read(&mut small_read_buf) { + if size == 0 { + break; + } + bytes_read += size; + } + assert_eq!(block_count * BLOCK_SIZE, bytes_read); + } +} diff --git a/vendor/gix-features-0.35.0/tests/trace/mod.rs b/vendor/gix-features-0.35.0/tests/trace/mod.rs new file mode 100644 index 000000000..614a0bb62 --- /dev/null +++ b/vendor/gix-features-0.35.0/tests/trace/mod.rs @@ -0,0 +1,15 @@ +use gix_features::trace::{coarse, detail, span}; +#[test] +fn span() { + let _x = span!(gix_features::trace::Level::Coarse, "hello"); + span!(gix_features::trace::Level::Coarse, "hello", x = "value", y = 42); + span!(target: "other", gix_features::trace::Level::Coarse, "hello", x = "value", y = 42); + + let _x = coarse!("hello"); + coarse!("hello", x = "value", y = 42); + coarse!(target: "other", "hello", x = "value", y = 42); + + let _y = detail!("hello"); + detail!("hello", x = "value", y = 42); + detail!(target: "other", "hello", x = "value", y = 42); +} -- cgit v1.2.3