From a3bb7c69c0295cb2fc7909559456e798b222fccd Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sat, 31 Oct 2026 14:56:59 -0700 Subject: Add the shared config writers and cgit_rc The helpers are named by kind. cgitrc_repo and cgitrc_copy write the config file named first, and cgit_url, cgit_query and cgit_rc run cgit, each named after what it is handed first. A repository copies its defaults from the globals read before its repo.url, so cgitrc_repo places every setting itself, and a global can no longer land where it silently stops applying. The t00xx and t01xx files move to them here. --- tests/setup.sh | 61 ++++++++++++++++++++++++++++++++---- tests/t0002-html-validity.sh | 11 ++----- tests/t0003-cache.sh | 46 +++++++++++++-------------- tests/t0005-markup.sh | 74 +++++++++++++++++++------------------------- tests/t0006-nolua.sh | 7 +---- tests/t0101-index.sh | 20 ++++-------- tests/t0102-summary.sh | 20 +++++------- tests/t0103-log.sh | 28 +++++------------ tests/t0104-tree.sh | 60 +++++++++-------------------------- tests/t0105-plain.sh | 16 +++------- tests/t0107-diff.sh | 18 +++-------- tests/t0109-patch.sh | 4 +-- tests/t0110-snapshot.sh | 38 ++++++++--------------- tests/t0111-atom.sh | 10 ++---- tests/t0112-stats.sh | 50 +++++++++--------------------- 15 files changed, 188 insertions(+), 275 deletions(-) (limited to 'tests') diff --git a/tests/setup.sh b/tests/setup.sh index 9f17778..92451b7 100755 --- a/tests/setup.sh +++ b/tests/setup.sh @@ -1,9 +1,10 @@ # Shared groundwork sourced by every test script. It builds a handful of small # repositories under repos/ and writes a cgitrc pointing at them, then offers -# the helpers that ask cgit for a page so a test only has to look at what comes -# back. Sourcing it also brings in the test library from the bundled Git tree, -# which is where test_expect_success and the trash directory come from. Set -# CGIT_TEST_NO_CREATE_REPOS to get the helpers without paying for the fixtures. +# the helpers that write a config of a test's own and ask cgit for a page, so +# a test only has to look at what comes back. Sourcing it also brings in the +# test library from the bundled Git tree, which is where test_expect_success +# and the trash directory come from. Set CGIT_TEST_NO_CREATE_REPOS to get the +# helpers without paying for the fixtures. LF=' ' @@ -168,12 +169,60 @@ EOF fi } +# Writes a config to the file named first that serves repos/ under the +# url named second, with the cache off and links rooted at /, and takes the +# rest as settings. A repository copies its defaults from the global settings +# read before its repo.url, so whatever order they come in, the repo.* ones +# go after the repository and all others ahead of it. A repo.path setting +# names a repository kept somewhere else. +cgitrc_repo() { + cgitrc_file=$1 + cgitrc_url=$2 + shift 2 + cgitrc_path="repo.path=$PWD/repos/$cgitrc_url/.git" + cgitrc_before= + cgitrc_after= + for cgitrc_setting + do + case "$cgitrc_setting" in + repo.path=*) + cgitrc_path=$cgitrc_setting + ;; + repo.*) + cgitrc_after="$cgitrc_after$cgitrc_setting$LF" + ;; + *) + cgitrc_before="$cgitrc_before$cgitrc_setting$LF" + ;; + esac + done + printf '%s' "virtual-root=/$LF" "cache-size=0$LF" "$cgitrc_before" \ + "repo.url=$cgitrc_url$LF" "$cgitrc_path$LF" "$cgitrc_after" >"$cgitrc_file" +} + +# Writes the global settings named after the file ahead of a copy of the +# shared cgitrc. The copy turns the cache off, because a page is cached under +# its request alone and would otherwise come back as the shared config made +# it. +cgitrc_copy() { + cgitrc_file=$1 + shift + { + test $# = 0 || printf '%s\n' "$@" + sed "s/^cache-size=.*/cache-size=0/" cgitrc + } >"$cgitrc_file" +} + +cgit_rc() { + CGIT_CONFIG="$PWD/$1" QUERY_STRING="$2" cgit +} + cgit_query() { - CGIT_CONFIG="$PWD/cgitrc" QUERY_STRING="$1" cgit + cgit_rc cgitrc "$1" } cgit_url() { - CGIT_CONFIG="$PWD/cgitrc" QUERY_STRING="url=$1" cgit + cgit_rc cgitrc "url=$1" } # The response headers run down to the first empty line, and a test comparing diff --git a/tests/t0002-html-validity.sh b/tests/t0002-html-validity.sh index b9020d6..bdccaf2 100755 --- a/tests/t0002-html-validity.sh +++ b/tests/t0002-html-validity.sh @@ -11,7 +11,7 @@ test_description='Validate html with tidy' test_url() { # A second argument names a config of its own, for pages the shared # config keeps turned off. - CGIT_CONFIG="$PWD/${2:-cgitrc}" QUERY_STRING="url=$1" cgit >tidy-$test_count.tmp || return + cgit_rc "${2:-cgitrc}" "url=$1" >tidy-$test_count.tmp || return # Tidy reads what it is given as a whole document, so the response # headers are dropped before it sees the page. strip_headers tidy-$test_count || return @@ -49,14 +49,7 @@ test_expect_success 'error page' 'test_url "no-such-repo"' # Stats and blame stay off in the shared config, so their pages validate # through a config of their own. test_expect_success 'set up a features config' ' - { - echo "virtual-root=/" && - echo "cache-size=0" && - echo "max-stats=year" && - echo "enable-blame=1" && - echo "repo.url=feat" && - echo "repo.path=$PWD/repos/foo/.git" - } >featrc + cgitrc_repo featrc feat max-stats=year enable-blame=1 "repo.path=$PWD/repos/foo/.git" ' test_expect_success 'stats page' 'test_url "feat/stats/" featrc' diff --git a/tests/t0003-cache.sh b/tests/t0003-cache.sh index 17816c3..ec88046 100755 --- a/tests/t0003-cache.sh +++ b/tests/t0003-cache.sh @@ -77,9 +77,9 @@ test_expect_success 'set up a repo with a page larger than the output buffer' ' ' test_expect_success 'the first request fills the slot and the second replays it' ' - CGIT_CONFIG="$PWD/bigrc" QUERY_STRING="url=bigpage/tree/big.txt" cgit >big.first && + cgit_rc bigrc "url=bigpage/tree/big.txt" >big.first && test $(wc -c big.second && + cgit_rc bigrc "url=bigpage/tree/big.txt" >big.second && strip_headers big.first.body && strip_headers big.second.body && test_cmp big.first.body big.second.body @@ -87,7 +87,7 @@ test_expect_success 'the first request fills the slot and the second replays it' test_expect_success 'the cached body matches one generated with the cache off' ' sed -e "s/^cache-size=64$/cache-size=0/" bigrc >bignocache && - CGIT_CONFIG="$PWD/bignocache" QUERY_STRING="url=bigpage/tree/big.txt" cgit >big.nocache && + cgit_rc bignocache "url=bigpage/tree/big.txt" >big.nocache && strip_headers big.nocache.body && test_cmp big.nocache.body big.second.body ' @@ -104,14 +104,14 @@ test_expect_success 'an over-long cache key leaves no slot behind' ' rm -rf cache3 && mkdir cache3 && sed -e "s|^cache-root=.*|cache-root=$PWD/cache3|" bigrc >bigkeyrc && long=$(awk "BEGIN{s=\"\";for(i=0;i<6000;i++)s=s \"k\"; print s}") && - CGIT_CONFIG="$PWD/bigkeyrc" QUERY_STRING="url=bigpage/&q=$long" cgit >key.out 2>/dev/null && + cgit_rc bigkeyrc "url=bigpage/&q=$long" >key.out 2>/dev/null && grep "" key.out && test_dir_is_empty cache3 ' test_expect_success 'an ordinary key still fills a slot' ' rm -rf cache3 && mkdir cache3 && - CGIT_CONFIG="$PWD/bigkeyrc" QUERY_STRING="url=bigpage/" cgit >/dev/null && + cgit_rc bigkeyrc "url=bigpage/" >/dev/null && ls cache3 >key.slots && test_line_count = 1 key.slots ' @@ -137,7 +137,7 @@ test_expect_success 'set up a repo missing a parent object' ' ' test_expect_success 'an error after output began ends the page with it and caches nothing' ' - CGIT_CONFIG="$PWD/brokenrc" QUERY_STRING="url=broken/commit/&id=$tip" cgit >broken.out && + cgit_rc brokenrc "url=broken/commit/&id=$tip" >broken.out && grep "Not a commit" broken.out && test $(grep -c "^Status:" broken.out) = 1 && test_dir_is_empty cache4 @@ -159,9 +159,9 @@ test_expect_success 'an error page leaves no slot behind' ' # a slot would only double the disk they take. test_expect_success 'a clone file leaves no slot behind' ' rm -rf cache3 && mkdir cache3 && - CGIT_CONFIG="$PWD/bigkeyrc" QUERY_STRING="url=bigpage/info/refs" cgit >clone.out && + cgit_rc bigkeyrc "url=bigpage/info/refs" >clone.out && grep "refs/heads/master" clone.out && - CGIT_CONFIG="$PWD/bigkeyrc" QUERY_STRING="url=bigpage/objects/info/packs" cgit >packs.out && + cgit_rc bigkeyrc "url=bigpage/objects/info/packs" >packs.out && grep "^Status: 200" packs.out && test_dir_is_empty cache3 ' @@ -176,21 +176,21 @@ test_expect_success 'a response over cache-max-slot-size is served but not kept' echo "cache-max-slot-size=32" && cat bigkeyrc } >slotsizerc && - CGIT_CONFIG="$PWD/slotsizerc" QUERY_STRING="url=bigpage/tree/big.txt" cgit >big.unkept && + cgit_rc slotsizerc "url=bigpage/tree/big.txt" >big.unkept && tail -c 200 big.unkept | grep "" && test_dir_is_empty cache3 && - CGIT_CONFIG="$PWD/slotsizerc" QUERY_STRING="url=bigpage/" cgit >/dev/null && + cgit_rc slotsizerc "url=bigpage/" >/dev/null && ls cache3 >kept.slots && test_line_count = 1 kept.slots ' test_expect_success 'an expired slot is dropped when its refill is too large' ' rm -rf cache3 && mkdir cache3 && - CGIT_CONFIG="$PWD/bigkeyrc" QUERY_STRING="url=bigpage/tree/big.txt" cgit >/dev/null && + cgit_rc bigkeyrc "url=bigpage/tree/big.txt" >/dev/null && ls cache3 >filled.slots && test_line_count = 1 filled.slots && touch -t 200001010000 cache3/* && - CGIT_CONFIG="$PWD/slotsizerc" QUERY_STRING="url=bigpage/tree/big.txt" cgit >big.refill && + cgit_rc slotsizerc "url=bigpage/tree/big.txt" >big.refill && tail -c 200 big.refill | grep "" && test_dir_is_empty cache3 ' @@ -204,11 +204,11 @@ test_expect_success 'pages following a branch take the dynamic ttl' ' echo "cache-dynamic-ttl=0" && cat bigkeyrc } >dynamicrc && - CGIT_CONFIG="$PWD/dynamicrc" QUERY_STRING="url=bigpage/log/" cgit >/dev/null && - CGIT_CONFIG="$PWD/dynamicrc" QUERY_STRING="url=bigpage/log/&h=master" cgit >/dev/null && + cgit_rc dynamicrc "url=bigpage/log/" >/dev/null && + cgit_rc dynamicrc "url=bigpage/log/&h=master" >/dev/null && test_dir_is_empty cache3 && - CGIT_CONFIG="$PWD/dynamicrc" QUERY_STRING="url=bigpage/" cgit >/dev/null && - CGIT_CONFIG="$PWD/dynamicrc" QUERY_STRING="url=bigpage/summary/" cgit >/dev/null && + cgit_rc dynamicrc "url=bigpage/" >/dev/null && + cgit_rc dynamicrc "url=bigpage/summary/" >/dev/null && ls cache3 >summary.slots && test_line_count = 2 summary.slots ' @@ -222,7 +222,7 @@ test_expect_success 'a failed final write still delivers the page' ' ( trap "" XFSZ && ulimit -f 2 && - CGIT_CONFIG="$PWD/bigkeyrc" QUERY_STRING="url=bigpage/" cgit 2>flush.err + cgit_rc bigkeyrc "url=bigpage/" 2>flush.err ) | cat >flush.out && grep "^Status: 200" flush.out && grep "" flush.out && @@ -234,13 +234,13 @@ test_expect_success 'a failed final write still delivers the page' ' overlap_requests() { n=0 rm -f filter-running - CGIT_CONFIG="$PWD/lockrc" QUERY_STRING="url=bigpage/about/" cgit >first.out 2>first.err & + cgit_rc lockrc "url=bigpage/about/" >first.out 2>first.err & while ! test -f filter-running && test $n -lt 10 do sleep 1 n=$((n + 1)) done - CGIT_CONFIG="$PWD/lockrc" QUERY_STRING="url=bigpage/log/" cgit >/dev/null 2>second.err + cgit_rc lockrc "url=bigpage/log/" >/dev/null 2>second.err wait } @@ -301,13 +301,13 @@ test_expect_success PERL 'a filter holds the lock file only as its stdout' ' # to the copy shows that it is what was served. test_expect_success SANITY 'a refresh that cannot lock serves the expired slot and says why' ' rm -rf cache3 && mkdir cache3 && - CGIT_CONFIG="$PWD/bigkeyrc" QUERY_STRING="url=bigpage/" cgit >/dev/null && + cgit_rc bigkeyrc "url=bigpage/" >/dev/null && slot=$(ls cache3) && echo "the expired copy" >>"cache3/$slot" && touch -t 200001010000 "cache3/$slot" && test_when_finished "chmod u+w cache3" && chmod a-w cache3 && - CGIT_CONFIG="$PWD/bigkeyrc" QUERY_STRING="url=bigpage/" cgit >stale.out 2>stale.err && + cgit_rc bigkeyrc "url=bigpage/" >stale.out 2>stale.err && grep "the expired copy" stale.out && grep "Unable to open .*\.lock: Permission denied" stale.err ' @@ -320,7 +320,7 @@ test_expect_success 'a slot lock that cannot take its key is let go' ' ( trap "" XFSZ && ulimit -f 0 && - CGIT_CONFIG="$PWD/bigkeyrc" QUERY_STRING="url=bigpage/" cgit 2>&1 + cgit_rc bigkeyrc "url=bigpage/" 2>&1 ) | cat >nokey.out && grep "" nokey.out && grep "Unable to write .*\.lock" nokey.out && @@ -341,7 +341,7 @@ test_expect_success 'set up a cached scan of two repositories' ' echo "scan-path=$PWD/scanned" } >scanrc && rm -rf cache5 && mkdir cache5 && - CGIT_CONFIG="$PWD/scanrc" QUERY_STRING="url=" cgit >/dev/null && + cgit_rc scanrc "url=" >/dev/null && scanned_rc=$(ls cache5) && test_path_is_file "cache5/$scanned_rc" ' diff --git a/tests/t0005-markup.sh b/tests/t0005-markup.sh index 60a9990..a6dd028 100755 --- a/tests/t0005-markup.sh +++ b/tests/t0005-markup.sh @@ -17,23 +17,13 @@ test_expect_success 'set up a repository with a file that has an extension' ' git add dir && git commit -m sources ) && - { - echo "virtual-root=/" && - echo "cache-size=0" && - echo "enable-blame=1" && - echo "max-stats=year" && - echo "readme=:file-1" && - echo "repo.url=hooks" && - echo "repo.path=$PWD/repos/hooks/.git" - } >hooksrc + cgitrc_repo hooksrc hooks enable-blame=1 max-stats=year readme=:file-1 ' -hooks() { CGIT_CONFIG="$PWD/hooksrc" QUERY_STRING="url=$1" cgit; } - test_expect_success 'the root names the page and the repository' ' - hooks "" >tmp && + cgit_rc hooksrc "url=" >tmp && grep "
" tmp && - hooks "hooks/log/" >tmp && + cgit_rc hooksrc "url=hooks/log/" >tmp && grep "
" tmp ' @@ -46,14 +36,14 @@ test_expect_success 'the landmarks and the search form are in place' ' ' test_expect_success 'the pages name the versions only when asked to' ' - hooks "hooks/" >footer && + cgit_rc hooksrc "url=hooks/" >footer && grep "" footer && grep "" footer && { echo "enable-version-info=1" && cat hooksrc } >versionrc && - CGIT_CONFIG="$PWD/versionrc" QUERY_STRING="url=hooks/" cgit >footer && + cgit_rc versionrc "url=hooks/" >footer && grep "]*>" footer && grep "" footer && echo "
our own
" >footer.html && @@ -62,7 +52,7 @@ test_expect_success 'the pages name the versions only when asked to' ' echo "footer=$PWD/footer.html" && cat hooksrc } >versionrc && - CGIT_CONFIG="$PWD/versionrc" QUERY_STRING="url=hooks/" cgit >footer && + cgit_rc versionrc "url=hooks/" >footer && grep "
our own
" footer && ! grep "git-scm" footer ' @@ -73,58 +63,58 @@ test_expect_success 'the listings name themselves, their sections and their rows grep "" tmp && grep "class=.active. aria-current=.page." tmp && grep "" tmp && - hooks "" >tmp && + cgit_rc hooksrc "url=" >tmp && grep "" tmp && grep "" tmp && grep "" tmp && - hooks "hooks/" >tmp && + cgit_rc hooksrc "url=hooks/" >tmp && grep "
" tmp && grep "" tmp && grep "" tmp && - hooks "hooks/tree/" >tmp && + cgit_rc hooksrc "url=hooks/tree/" >tmp && grep "
" tmp && grep "" tmp && grep "" tmp && - hooks "hooks/tree/dir/" >tmp && + cgit_rc hooksrc "url=hooks/tree/dir/" >tmp && grep "class=.ls-blob ext-c." tmp ' test_expect_success 'the diff pages wrap each file and label their controls' ' - hooks "hooks/commit/" >tmp && + cgit_rc hooksrc "url=hooks/commit/" >tmp && grep "
" tmp && grep "" tmp && grep "
" tmp && grep "" tmp && grep "
" tmp && - hooks "hooks/stats/" >tmp && + cgit_rc hooksrc "url=hooks/stats/" >tmp && grep "" tmp ' test_expect_success 'the blob, blame and about pages open with their own containers' ' - hooks "hooks/tree/dir/hello.c" >tmp && + cgit_rc hooksrc "url=hooks/tree/dir/hello.c" >tmp && grep "
" tmp && grep "tmp && + cgit_rc hooksrc "url=hooks/blame/dir/hello.c" >tmp && grep "
" tmp && - hooks "hooks/about/" >tmp && + cgit_rc hooksrc "url=hooks/about/" >tmp && grep "
" tmp ' test_expect_success 'each page names itself, then the repository and the site' ' site="Git repository browser" && - hooks "hooks/" >tmp && + cgit_rc hooksrc "url=hooks/" >tmp && grep "hooks - $site" tmp && for page in about log refs tree stats do - hooks "hooks/$page/" >tmp && + cgit_rc hooksrc "url=hooks/$page/" >tmp && grep "$page - hooks - $site" tmp || return 1 done && - hooks "hooks/tree/dir/hello.c" >tmp && + cgit_rc hooksrc "url=hooks/tree/dir/hello.c" >tmp && grep "hello.c < dir - hooks - $site" tmp && - hooks "hooks/blame/dir/hello.c" >tmp && + cgit_rc hooksrc "url=hooks/blame/dir/hello.c" >tmp && grep "blame - hello.c < dir - hooks - $site" tmp ' @@ -151,7 +141,7 @@ test_expect_success 'the page background is the same everywhere it is set' ' test_line_count = 1 expect && sed -n "/^html.cgit-standalone {\$/,/^}/s/^ background: light-dark(\(#[0-9a-f]*\), \(#[0-9a-f]*\));\$/\1 \2/p" "$css" >actual && test_cmp expect actual && - hooks "hooks/" >tmp && + cgit_rc hooksrc "url=hooks/" >tmp && light=$(sed -n "s/.*theme-color. media=.(prefers-color-scheme: light). content=.\(#[0-9a-f]*\).*/\1/p" tmp) && dark=$(sed -n "s/.*theme-color. media=.(prefers-color-scheme: dark). content=.\(#[0-9a-f]*\).*/\1/p" tmp) && echo "$light $dark" >actual && @@ -159,7 +149,7 @@ test_expect_success 'the page background is the same everywhere it is set' ' ' test_expect_success 'the script waits for the page instead of holding it up' ' - hooks "hooks/" >tmp && + cgit_rc hooksrc "url=hooks/" >tmp && grep "" tmp ' @@ -205,31 +195,29 @@ test_expect_success 'set up the remaining kinds of entry' ' } >morerc ' -more() { CGIT_CONFIG="$PWD/morerc" QUERY_STRING="url=$1" cgit; } - test_expect_success 'the refs, summary and tree name every section and row' ' - more "hooks/refs/" >tmp && + cgit_rc morerc "url=hooks/refs/" >tmp && grep "
author
" tmp && grep "" tmp && grep "" tmp && - more "hooks/" >tmp && + cgit_rc morerc "url=hooks/" >tmp && grep "" tmp && - more "hooks/tree/" >tmp && + cgit_rc morerc "url=hooks/tree/" >tmp && grep "" tmp && grep "" tmp && grep "" tmp ' test_expect_success 'the commit page has its trailer table and diffstat' ' - more "hooks/commit/" >tmp && + cgit_rc morerc "url=hooks/commit/" >tmp && grep "
" tmp && grep "
" tmp ' test_expect_success 'the breadcrumb, the pager and the ages carry their hooks' ' - more "hooks/tree/dir/" >tmp && + cgit_rc morerc "url=hooks/tree/dir/" >tmp && grep "
" tmp && grep "" tmp ' @@ -256,7 +244,7 @@ test_expect_success 'embedded mode marks the root' ' echo "embedded=1" && cat hooksrc } >embeddedrc && - CGIT_CONFIG="$PWD/embeddedrc" QUERY_STRING="url=hooks/" cgit >tmp && + cgit_rc embeddedrc "url=hooks/" >tmp && grep "
plainrc && + cgitrc_repo plainrc foo && nolua_query plainrc "url=foo/log/" >tmp && grep "^Status: 200" tmp && grep ">commit 5" tmp diff --git a/tests/t0101-index.sh b/tests/t0101-index.sh index e50f0f8..c8b9fb7 100755 --- a/tests/t0101-index.sh +++ b/tests/t0101-index.sh @@ -22,23 +22,15 @@ test_expect_success 'no tree-link' '! grep "foo/tree" tmp' test_expect_success 'no log-link' '! grep "foo/log" tmp' test_expect_success 'index links lead to the summary, log and tree' ' - echo "enable-index-links=1" >links-cgitrc && - sed "s/^cache-size=.*/cache-size=0/" cgitrc >>links-cgitrc && - CGIT_CONFIG="$PWD/links-cgitrc" QUERY_STRING="url=" cgit >tmp && + cgitrc_copy links-cgitrc enable-index-links=1 && + cgit_rc links-cgitrc "url=" >tmp && grep ">summarylog" tmp && grep "href=./foo/log/.>logtree<" tmp ' test_expect_success 'each css and js entry gets a link of its own' ' - { - echo "css=/a.css" && - echo "css=/b.css" && - echo "js=/a.js" && - echo "js=" && - echo "js=/b.js" - } >headrc && - sed "s/^cache-size=.*/cache-size=0/" cgitrc >>headrc && - CGIT_CONFIG="$PWD/headrc" QUERY_STRING="url=" cgit >tmp && + cgitrc_copy headrc css=/a.css css=/b.css js=/a.js js= js=/b.js && + cgit_rc headrc "url=" >tmp && grep "" tmp && grep "" tmp && grep "