diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8728d06747f..782f28ec034 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -164,6 +164,7 @@ jobs: - macos-latest - ubuntu-latest - ubuntu-24.04-arm + fail-fast: false runs-on: ${{ matrix.os }} @@ -184,6 +185,76 @@ jobs: - name: Check that tracked archives are up to date run: git diff --exit-code # If this fails, the fix is usually to commit a regenerated archive. + # TODO(integration): Remove all or at least most test-ext4-casefold jobs prior to merging #2008. + test-ext4-casefold: + strategy: + matrix: + # `--test-threads` operand + parallel-tests: + - 1 # Never fails. + - 2 # Usually fails. + - 3 # Almost never fails, somehow! + - 4 # Usually fails. + # Duplicate jobs + rep: [A, B, C, D, E, F, G] + fail-fast: false + + runs-on: ubuntu-latest + + steps: + - name: Warn if we could use tmpfs mounted with `-o casefold` instead + run: | + case "$(cat > "$GITHUB_ENV" + - name: Verify case folding in workspace and TMPDIR + run: | + set -ux + shopt -s nullglob + verify() { + touch a A + files=(?) + test "${#files[@]}" -eq 1 + rm a + } + verify + (cd -- "$TMPDIR"; verify) + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: taiki-e/install-action@v2 + with: + tool: nextest + - name: Increase writes_through_symlinks_are_prevented_even_if_overwriting_is_allowed reps + run: | + # Prepend leading digits "24" to the upper bound of the label range. + sed -Ei 's/^(#\[test_matrix\(0\.\.=)([[:digit:]]+\)])$/\124\2/' \ + gix-worktree-state/tests/state/checkout.rs + - name: Display the changes made for this test + run: git diff + - name: Test writes_through_symlinks_are_prevented_even_if_overwriting_is_allowed (nextest) + run: | + cargo nextest run -p gix-worktree-state-tests --no-default-features \ + writes_through_symlinks_are_prevented_even_if_overwriting_is_allowed \ + --status-level=fail --test-threads=${{ matrix.parallel-tests }} + test-fixtures-windows: runs-on: windows-latest @@ -496,6 +567,7 @@ jobs: - test - test-journey - test-fast + - test-ext4-casefold - test-fixtures-windows - test-32bit - test-32bit-windows-size-doc diff --git a/Cargo.lock b/Cargo.lock index a154c740c80..3e6feba3de8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2600,6 +2600,7 @@ dependencies = [ "gix-worktree-state", "once_cell", "symlink", + "test-case", "walkdir", ] @@ -4757,6 +4758,39 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" +[[package]] +name = "test-case" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" +dependencies = [ + "test-case-macros", +] + +[[package]] +name = "test-case-core" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "test-case-macros" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", + "test-case-core", +] + [[package]] name = "thiserror" version = "1.0.69" diff --git a/gix-worktree-state/tests/Cargo.toml b/gix-worktree-state/tests/Cargo.toml index 7f41c26467b..e4e5e0fba17 100644 --- a/gix-worktree-state/tests/Cargo.toml +++ b/gix-worktree-state/tests/Cargo.toml @@ -33,3 +33,4 @@ symlink = "0.1.0" once_cell = "1.21.3" walkdir = "2.3.2" +test-case = "3.3.1" diff --git a/gix-worktree-state/tests/state/checkout.rs b/gix-worktree-state/tests/state/checkout.rs index 764b52020d3..506b6471e06 100644 --- a/gix-worktree-state/tests/state/checkout.rs +++ b/gix-worktree-state/tests/state/checkout.rs @@ -12,6 +12,7 @@ use gix_object::{bstr::ByteSlice, Data}; use gix_testtools::tempfile::TempDir; use gix_worktree_state::checkout::Collision; use once_cell::sync::Lazy; +use test_case::test_matrix; use crate::fixture_path; @@ -103,8 +104,8 @@ fn accidental_writes_through_symlinks_are_prevented_if_overwriting_is_forbidden( } } -#[test] -fn writes_through_symlinks_are_prevented_even_if_overwriting_is_allowed() { +#[test_matrix(0..=999)] +fn writes_through_symlinks_are_prevented_even_if_overwriting_is_allowed(_i: i32) { let mut opts = opts_from_probe(); // with overwrite mode opts.overwrite_existing = true; @@ -688,10 +689,11 @@ fn probe_gitoxide_dir() -> crate::Result { fn opts_from_probe() -> gix_worktree_state::checkout::Options { static CAPABILITIES: Lazy = Lazy::new(|| probe_gitoxide_dir().unwrap()); + // FIXME(integration): Restore multithreaded `thread_limit` prior to merging #2008. gix_worktree_state::checkout::Options { fs: *CAPABILITIES, destination_is_initially_empty: true, - thread_limit: gix_features::parallel::num_threads(None).into(), + thread_limit: Some(1), // gix_features::parallel::num_threads(None).into(), ..Default::default() } }