]> git.ipfire.org Git - thirdparty/git.git/commitdiff
test-lib: teach test_seq the -f option
authorJeff King <peff@peff.net>
Mon, 23 Jun 2025 10:56:25 +0000 (06:56 -0400)
committerJunio C Hamano <gitster@pobox.com>
Tue, 24 Jun 2025 13:34:25 +0000 (06:34 -0700)
The "seq" tool has a "-f" option to produce printf-style formatted
lines. Let's teach our test_seq helper the same trick. This lets us get
rid of some shell loops in test snippets (which are particularly verbose
in our test suite because we have to "|| return 1" to keep the &&-chain
going).

This converts a few call-sites I found by grepping around the test
suite. A few notes on these:

  - In "seq", the format specifier is a "%g" float. Since test_seq only
    supports integers, I've kept the more natural "%d" (which is what
    these call sites were using already).

  - Like "seq", test_seq automatically adds a newline to the specified
    format. This is what all callers are doing already except for t0021,
    but there we do not care about the exact format. We are just trying
    to printf a large number of bytes to a file. It's not worth
    complicating other callers or adding an option to avoid the newline
    in that caller.

  - Most conversions are just replacing a shell loop (which does get rid
    of an extra fork, since $() requires a subshell). In t0612 we can
    replace an awk invocation, which I think makes the end result more
    readable, as there's less quoting.

  - In t7422 we can replace one loop, but sadly we have to leave the
    loop directly above it. This is because that earlier loop wants to
    include the seq value twice in the output, which test_seq does not
    support (nor does regular seq). If you run:

      test_seq -f "foo-%d %d" 10

    the second "%d" will always be the empty string. You might naively
    think that test_seq could add some extra arguments, like:

      # 3 ought to be enough for anyone...
      printf "$fmt\n" "$i "$i" $i"

    but that just triggers printf to format multiple lines, one per
    extra set of arguments.

    So we'd have to actually parse the format string, figure out how
    many "%" placeholders are there, and then feed it that many
    instances of the sequence number. The complexity isn't worth it.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t0021-conversion.sh
t/t0610-reftable-basics.sh
t/t0612-reftable-jgit-compatibility.sh
t/t0613-reftable-write-options.sh
t/t1400-update-ref.sh
t/t5004-archive-corner-cases.sh
t/t6422-merge-rename-corner-cases.sh
t/t7422-submodule-output.sh
t/test-lib-functions.sh

index bf10d253ec40991a077ae985857781542b14aec8..f0d50d769e9fc56f6147e9cc5421ba7408eb2fe6 100755 (executable)
@@ -281,7 +281,7 @@ test_expect_success 'required filter with absent smudge field' '
 test_expect_success 'filtering large input to small output should use little memory' '
        test_config filter.devnull.clean "cat >/dev/null" &&
        test_config filter.devnull.required true &&
-       for i in $(test_seq 1 30); do printf "%1048576d" 1 || return 1; done >30MB &&
+       test_seq -f "%1048576d" 1 30 >30MB &&
        echo "30MB filter=devnull" >.gitattributes &&
        GIT_MMAP_LIMIT=1m GIT_ALLOC_LIMIT=1m git add 30MB
 '
@@ -299,7 +299,7 @@ test_expect_success 'filter that does not read is fine' '
 test_expect_success EXPENSIVE 'filter large file' '
        test_config filter.largefile.smudge cat &&
        test_config filter.largefile.clean cat &&
-       for i in $(test_seq 1 2048); do printf "%1048576d" 1 || return 1; done >2GB &&
+       test_seq -f "%1048576d" 1 2048 >2GB &&
        echo "2GB filter=largefile" >.gitattributes &&
        git add 2GB 2>err &&
        test_must_be_empty err &&
index 1be534a89533d00ff2d4cf29ecb7bce437a361f5..3ea5d51532a8b88ac8e36d79613812ed4668234a 100755 (executable)
@@ -477,11 +477,7 @@ test_expect_success !CYGWIN 'ref transaction: many concurrent writers' '
                test_commit --no-tag initial &&
 
                head=$(git rev-parse HEAD) &&
-               for i in $(test_seq 100)
-               do
-                       printf "%s commit\trefs/heads/branch-%s\n" "$head" "$i" ||
-                       return 1
-               done >expect &&
+               test_seq -f "$head commit\trefs/heads/branch-%d" 100 >expect &&
                printf "%s commit\trefs/heads/main\n" "$head" >>expect &&
 
                for i in $(test_seq 100)
index d0d7e80b492091d1949467f9835c35f622ae0bb4..7df2ad5817e745c8caaaa5c05cfbf6137216c935 100755 (executable)
@@ -112,14 +112,11 @@ test_expect_success 'JGit can read multi-level index' '
                cd repo &&
 
                test_commit A &&
-               awk "
-                   BEGIN {
-                       print \"start\";
-                       for (i = 0; i < 10000; i++)
-                           printf \"create refs/heads/branch-%d HEAD\n\", i;
-                       print \"commit\";
-                   }
-               " >input &&
+               {
+                       echo start &&
+                       test_seq -f "create refs/heads/branch-%d HEAD" 10000 &&
+                       echo commit
+               } >input &&
                git update-ref --stdin <input &&
 
                test_same_refs &&
index 6447920c9be4c0d9805ee27cd4d6ce63ce59167b..d77e601111f6cd5c2eaf5ccd4abeb211dc606ef0 100755 (executable)
@@ -66,11 +66,7 @@ test_expect_success 'many refs results in multiple blocks' '
        (
                cd repo &&
                test_commit initial &&
-               for i in $(test_seq 200)
-               do
-                       printf "update refs/heads/branch-%d HEAD\n" "$i" ||
-                       return 1
-               done >input &&
+               test_seq -f "update refs/heads/branch-%d HEAD" 200 >input &&
                git update-ref --stdin <input &&
                git pack-refs &&
 
@@ -180,11 +176,7 @@ test_expect_success 'restart interval at every single record' '
        (
                cd repo &&
                test_commit initial &&
-               for i in $(test_seq 10)
-               do
-                       printf "update refs/heads/branch-%d HEAD\n" "$i" ||
-                       return 1
-               done >input &&
+               test_seq -f "update refs/heads/branch-%d HEAD" 10 >input &&
                git update-ref --stdin <input &&
                git -c reftable.restartInterval=1 pack-refs &&
 
@@ -224,11 +216,7 @@ test_expect_success 'object index gets written by default with ref index' '
        (
                cd repo &&
                test_commit initial &&
-               for i in $(test_seq 5)
-               do
-                       printf "update refs/heads/branch-%d HEAD\n" "$i" ||
-                       return 1
-               done >input &&
+               test_seq -f "update refs/heads/branch-%d HEAD" 5 >input &&
                git update-ref --stdin <input &&
                git -c reftable.blockSize=100 pack-refs &&
 
@@ -263,11 +251,7 @@ test_expect_success 'object index can be disabled' '
        (
                cd repo &&
                test_commit initial &&
-               for i in $(test_seq 5)
-               do
-                       printf "update refs/heads/branch-%d HEAD\n" "$i" ||
-                       return 1
-               done >input &&
+               test_seq -f "update refs/heads/branch-%d HEAD" 5 >input &&
                git update-ref --stdin <input &&
                git -c reftable.blockSize=100 -c reftable.indexObjects=false pack-refs &&
 
index d29d23cb8905f865e68da0e782c3cbe1948c6c3f..e373d9108b651a0c7622a58aab515f212a06043b 100755 (executable)
@@ -1380,10 +1380,7 @@ test_expect_success 'fails with duplicate ref update via symref' '
 
 test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction creating branches does not burst open file limit' '
 (
-       for i in $(test_seq 33)
-       do
-               echo "create refs/heads/$i HEAD" || exit 1
-       done >large_input &&
+       test_seq -f "create refs/heads/%d HEAD" 33 >large_input &&
        run_with_limited_open_files git update-ref --stdin <large_input &&
        git rev-parse --verify -q refs/heads/33
 )
@@ -1391,10 +1388,7 @@ test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction creating branches
 
 test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction deleting branches does not burst open file limit' '
 (
-       for i in $(test_seq 33)
-       do
-               echo "delete refs/heads/$i HEAD" || exit 1
-       done >large_input &&
+       test_seq -f "delete refs/heads/%d HEAD" 33 >large_input &&
        run_with_limited_open_files git update-ref --stdin <large_input &&
        test_must_fail git rev-parse --verify -q refs/heads/33
 )
index 51749951916008f8516b62fffb24437d47057025..027dedd9760a1812664cb725251523185696bd6e 100755 (executable)
@@ -176,10 +176,7 @@ test_expect_success EXPENSIVE,UNZIP,UNZIP_ZIP64_SUPPORT \
        blob=$(echo $s | git hash-object -w --stdin) &&
 
        # create tree containing 65500 entries of that blob
-       for i in $(test_seq 1 65500)
-       do
-               echo "100644 blob $blob $i" || return 1
-       done >tree &&
+       test_seq -f "100644 blob $blob\t%d" 1 65500 >tree &&
        tree=$(git mktree <tree) &&
 
        # zip it, creating an archive a bit bigger than 4GB
index 9cbe7ca78245d99a69e86723af4182db18e6db45..f14c0fb30e1bf293a7870c0210e66189bb20877e 100755 (executable)
@@ -1146,10 +1146,7 @@ test_conflicts_with_adds_and_renames() {
                        cd simple_${sideL}_${sideR} &&
 
                        # Create some related files now
-                       for i in $(test_seq 1 10)
-                       do
-                               echo Random base content line $i
-                       done >file_v1 &&
+                       test_seq -f "Random base content line %d" 1 10 >file_v1 &&
                        cp file_v1 file_v2 &&
                        echo modification >>file_v2 &&
 
@@ -1293,10 +1290,7 @@ test_setup_nested_conflicts_from_rename_rename () {
                cd nested_conflicts_from_rename_rename &&
 
                # Create some related files now
-               for i in $(test_seq 1 10)
-               do
-                       echo Random base content line $i
-               done >file_v1 &&
+               test_seq -f "Random base content line %d" 1 10 >file_v1 &&
 
                cp file_v1 file_v2 &&
                cp file_v1 file_v3 &&
index ea67057f1a41d9b290280480c1b19c924d6dea7b..aea1ddf117e8ee6c73809b67306647acab057818 100755 (executable)
@@ -187,11 +187,7 @@ test_expect_success !MINGW 'git submodule status --recursive propagates SIGPIPE'
                BLOB=$(git hash-object -w --stdin <gitmodules) &&
 
                printf "100644 blob $BLOB\t.gitmodules\n" >tree &&
-               for i in $(test_seq 2000)
-               do
-                       printf "160000 commit $COMMIT\trecursive-submodule-path-%d\n" "$i" ||
-                       return 1
-               done >>tree &&
+               test_seq -f "160000 commit $COMMIT\trecursive-submodule-path-%d" 2000 >>tree &&
                TREE=$(git mktree <tree) &&
 
                COMMIT=$(git commit-tree "$TREE") &&
index bee4a2ca3472e1b79e2a7bba5abdaa81235704c7..6230746cc4d31f33a911393a76e2cd05f8085dfc 100644 (file)
@@ -1451,9 +1451,21 @@ test_cmp_fspath () {
 #     test_seq 1 5 -- outputs 1 2 3 4 5 one line at a time
 #
 # or with one argument (end), in which case it starts counting
-# from 1.
+# from 1. In addition to the start/end arguments, you can pass an optional
+# printf format. For example:
+#
+#     test_seq -f "line %d" 1 5
+#
+# would print 5 lines, "line 1" through "line 5".
 
 test_seq () {
+       local fmt="%d"
+       case "$1" in
+       -f)
+               fmt="$2"
+               shift 2
+               ;;
+       esac
        case $# in
        1)      set 1 "$@" ;;
        2)      ;;
@@ -1462,7 +1474,7 @@ test_seq () {
        test_seq_counter__=$1
        while test "$test_seq_counter__" -le "$2"
        do
-               echo "$test_seq_counter__"
+               printf "$fmt\n" "$test_seq_counter__"
                test_seq_counter__=$(( $test_seq_counter__ + 1 ))
        done
 }