| #!/bin/sh |
| |
| test_description='Test that adding/removing many notes triggers automatic fanout restructuring' |
| |
| TEST_PASSES_SANITIZE_LEAK=true |
| . ./test-lib.sh |
| |
| path_has_fanout() { |
| path=$1 && |
| fanout=$2 && |
| after_last_slash=$(($(test_oid hexsz) - $fanout * 2)) && |
| echo $path | grep -q "^\([0-9a-f]\{2\}/\)\{$fanout\}[0-9a-f]\{$after_last_slash\}$" |
| } |
| |
| touched_one_note_with_fanout() { |
| notes_commit=$1 && |
| modification=$2 && # 'A' for addition, 'D' for deletion |
| fanout=$3 && |
| diff=$(git diff-tree --no-commit-id --name-status --root -r $notes_commit) && |
| path=$(echo $diff | sed -e "s/^$modification[\t ]//") && |
| path_has_fanout "$path" $fanout; |
| } |
| |
| all_notes_have_fanout() { |
| notes_commit=$1 && |
| fanout=$2 && |
| git ls-tree -r --name-only $notes_commit | |
| while read path |
| do |
| path_has_fanout $path $fanout || return 1 |
| done |
| } |
| |
| test_expect_success 'tweak test environment' ' |
| git checkout -b nondeterminism && |
| test_commit A && |
| git checkout --orphan with_notes; |
| ' |
| |
| test_expect_success 'creating many notes with git-notes' ' |
| num_notes=300 && |
| i=0 && |
| while test $i -lt $num_notes |
| do |
| i=$(($i + 1)) && |
| test_tick && |
| echo "file for commit #$i" > file && |
| git add file && |
| git commit -q -m "commit #$i" && |
| git notes add -m "note #$i" || return 1 |
| done |
| ' |
| |
| test_expect_success !SANITIZE_LEAK 'many notes created correctly with git-notes' ' |
| git log >output.raw && |
| grep "^ " output.raw >output && |
| i=$num_notes && |
| while test $i -gt 0 |
| do |
| echo " commit #$i" && |
| echo " note #$i" && |
| i=$(($i - 1)) || return 1 |
| done > expect && |
| test_cmp expect output |
| ' |
| |
| test_expect_success 'stable fanout 0 is followed by stable fanout 1' ' |
| i=$num_notes && |
| fanout=0 && |
| while test $i -gt 0 |
| do |
| i=$(($i - 1)) && |
| if touched_one_note_with_fanout refs/notes/commits~$i A $fanout |
| then |
| continue |
| elif test $fanout -eq 0 |
| then |
| fanout=1 && |
| if all_notes_have_fanout refs/notes/commits~$i $fanout |
| then |
| echo "Fanout 0 -> 1 at refs/notes/commits~$i" && |
| continue |
| fi |
| fi && |
| echo "Failed fanout=$fanout check at refs/notes/commits~$i" && |
| git ls-tree -r --name-only refs/notes/commits~$i && |
| return 1 |
| done && |
| all_notes_have_fanout refs/notes/commits 1 |
| ' |
| |
| test_expect_success 'deleting most notes with git-notes' ' |
| remove_notes=285 && |
| i=0 && |
| git rev-list HEAD >revs && |
| while test $i -lt $remove_notes && read sha1 |
| do |
| i=$(($i + 1)) && |
| test_tick && |
| git notes remove "$sha1" || return 1 |
| done <revs |
| ' |
| |
| test_expect_success 'most notes deleted correctly with git-notes' ' |
| git log HEAD~$remove_notes | grep "^ " > output && |
| i=$(($num_notes - $remove_notes)) && |
| while test $i -gt 0 |
| do |
| echo " commit #$i" && |
| echo " note #$i" && |
| i=$(($i - 1)) || return 1 |
| done > expect && |
| test_cmp expect output |
| ' |
| |
| test_expect_success 'stable fanout 1 is followed by stable fanout 0' ' |
| i=$remove_notes && |
| fanout=1 && |
| while test $i -gt 0 |
| do |
| i=$(($i - 1)) && |
| if touched_one_note_with_fanout refs/notes/commits~$i D $fanout |
| then |
| continue |
| elif test $fanout -eq 1 |
| then |
| fanout=0 && |
| if all_notes_have_fanout refs/notes/commits~$i $fanout |
| then |
| echo "Fanout 1 -> 0 at refs/notes/commits~$i" && |
| continue |
| fi |
| fi && |
| echo "Failed fanout=$fanout check at refs/notes/commits~$i" && |
| git ls-tree -r --name-only refs/notes/commits~$i && |
| return 1 |
| done && |
| all_notes_have_fanout refs/notes/commits 0 |
| ' |
| |
| test_done |