Commit Diff


commit - 417c56da5e451e4c04b12d9a17cb2215e13b95aa
commit + 5c9a53ccc23c395922ea5747fde1a5fe6c45af9d
blob - dcfa0f6eedf2d865d8d255194293b49e8ffb5ff3
blob + 803eb4958024659ae980b5f51216764b4ebbe37b
--- regress/gotwebd/Makefile
+++ regress/gotwebd/Makefile
@@ -1,6 +1,6 @@
 .PATH:${.CURDIR}/../../lib
 
-REGRESS_TARGETS=test_gotwebd
+REGRESS_TARGETS=test_gotwebd test_gotwebd_paginate
 
 PROG = gotwebd_test
 SRCS = gotwebd_test.c error.c hash.c pollfd.c
@@ -10,7 +10,7 @@ CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../
 NOMAN = yes
 
 .PHONY: ensure_root prepare_test_env prepare_test_repo start_gotwebd \
-	gotwebd_test_conf
+	gotwebd_test_conf gotwebd_test_conf_paginate
 
 GOTWEBD_TEST_TMPDIR=/tmp
 GOTWEBD_TEST_ROOT?!!=mktemp -d "${GOTWEBD_TEST_TMPDIR}/gotwebd-test-XXXXXXXXXX"
@@ -18,6 +18,7 @@ GOTWEBD_TEST_CHROOT=${GOTWEBD_TEST_ROOT}/var/www
 GOTWEBD_TEST_CONF=${GOTWEBD_TEST_ROOT}/gotwebd.conf
 GOTWEBD_TEST_SOCK=${GOTWEBD_TEST_CHROOT}/gotweb.sock
 GOTWEBD_TEST_FCGI=${.OBJDIR}/${PROG}
+GOTWEBD_TEST_PAGINATE_NITEMS?=15  # must be a multiple of 3 (items per page)
 GOTWEBD_CHECK_MEMLEAK=export MALLOC_OPTIONS=1; ktrace -d -tu -i -f ${GOTWEBD_TEST_ROOT}/ktrace.out
 
 GOTWEBD_TEST_USER?=${DOAS_USER}
@@ -43,6 +44,7 @@ GOTWEBD_TEST_ENV=GOTWEBD_TEST_SOCK=${GOTWEBD_TEST_SOCK
 	GOTWEBD_TEST_CONF=${GOTWEBD_TEST_CONF} \
 	GOTWEBD_TEST_USER=${GOTWEBD_TEST_USER} \
 	GOTWEBD_TEST_FCGI=${GOTWEBD_TEST_FCGI} \
+	GOTWEBD_TEST_PAGINATE_NITEMS=${GOTWEBD_TEST_PAGINATE_NITEMS} \
 	PATH=$(GOTWEBD_TEST_USER_HOME)/bin:${PATH} \
 	HOME=$(GOTWEBD_TEST_USER_HOME) \
 	GOTWEBD_TEST_DATA_DIR=${.CURDIR}
@@ -80,11 +82,15 @@ gotwebd_test_conf:
 	@echo '    show_repo_owner off' >> ${GOTWEBD_TEST_CONF}
 	@echo '}' >> ${GOTWEBD_TEST_CONF}
 
-start_gotwebd: prepare_test_repo gotwebd_test gotwebd_test_conf
+gotwebd_test_conf_paginate: gotwebd_test_conf
+	@printf '5i\n    max_commits_display 3\n.\nwq\n' | \
+	    ed -s ${GOTWEBD_TEST_CONF}
+
+start_gotwebd: prepare_test_repo gotwebd_test
 	@${GOTWEBD_TRAP}; ${GOTWEBD_CHECK_MEMLEAK} ${GOTWEBD_START_CMD}
 	@${GOTWEBD_TRAP}; sleep .5
 
-test_gotwebd: start_gotwebd
+test_gotwebd: gotwebd_test_conf start_gotwebd
 	@-$(GOTWEBD_TRAP); su -m ${GOTWEBD_TEST_USER} -c \
 		'env $(GOTWEBD_TEST_ENV) sh ${.CURDIR}/test_gotwebd.sh'
 	@${GOTWEBD_STOP_CMD} 2>/dev/null
@@ -95,4 +101,15 @@ test_gotwebd: start_gotwebd
 		exit 1; \
 	fi
 
+test_gotwebd_paginate: gotwebd_test_conf_paginate start_gotwebd
+	@-${GOTWEBD_TRAP}; su -m ${GOTWEBD_TEST_USER} -c \
+	    'env ${GOTWEBD_TEST_ENV} sh ${.CURDIR}/test_gotwebd_paginate.sh'
+	@${GOTWEBD_STOP_CMD} 2>/dev/null
+	@kdump -u malloc -f ${GOTWEBD_TEST_ROOT}/ktrace.out \
+	    > ${GOTWEBD_TEST_ROOT}/leak-report && \
+	if grep -q "/gotwebd 0x" ${GOTWEBD_TEST_ROOT}/leak-report; then \
+		cat ${GOTWEBD_TEST_ROOT}/leak-report; \
+		exit 1; \
+	fi
+
 .include <bsd.regress.mk>
blob - /dev/null
blob + 0ba11972706fcd6c426e26892e500abd253024cb (mode 644)
--- /dev/null
+++ regress/gotwebd/commits_page.html
@@ -0,0 +1,13 @@
+Content-Security-Policy: default-src 'self'; script-src 'none'; object-src 'none';

+Content-Type: text/html

+

+<!doctype html><html><head><meta charset="utf-8" /><title>Gotweb</title><meta name="viewport" content="initial-scale=1.0" /><meta name="msapplication-TileColor" content="#da532c" /><meta name="theme-color" content="#ffffff"/><link rel="apple-touch-icon" sizes="180x180" href="/gotwebd_test_harness/apple-touch-icon.png" /><link rel="icon" type="image/png" sizes="32x32" href="/gotwebd_test_harness/favicon-32x32.png" /><link rel="icon" type="image/png" sizes="16x16" href="/gotwebd_test_harness/favicon-16x16.png" /><link rel="manifest" href="/gotwebd_test_harness/site.webmanifest"/><link rel="mask-icon" href="/gotwebd_test_harness/safari-pinned-tab.svg" /><link rel="stylesheet" type="text/css" href="/gotwebd_test_harness/gotweb.css" /></head><body><header id="header"><div id="got_link"><a href="https://gameoftrees.org" target="_blank"><img src="/gotwebd_test_harness/got.png" /></a></div></header><nav id="site_path"><div id="site_link"><a href="?index_page=0">Repos</a> / <a href="?action=summary&path=repo.git">repo.git</a> / <a href="?action=commits&commit=${COMMIT_ID1}&path=repo.git">commits</a> / </div></nav><main class="action-commits"><header class="subtitle"><h2>Commits</h2></header><div class="commits_content"><div class="page_header_wrapper"><dl><dt>Commit:</dt><dd><code class="commit-id">${COMMIT_ID1}</code></dd><dt>From:</dt><dd>${COMMITTER} &lt;${COMMITTER_EMAIL}&gt;</dd><dt>Date:</dt><dd><time datetime="${COMMIT_YMDHMS1}">${COMMIT_DATE1}
+ UTC</time></dd></dl></div><hr /><div class="commit">
+${LOGMSG1}
+</div><div class="navs_wrapper"><div class="navs"><a href="?action=diff&commit=${COMMIT_ID1}&path=repo.git">diff</a> | <a href="?action=patch&commit=${COMMIT_ID1}&path=repo.git">patch</a> | <a href="?action=tree&commit=${COMMIT_ID1}&path=repo.git">tree</a></div></div><hr /><div class="page_header_wrapper"><dl><dt>Commit:</dt><dd><code class="commit-id">${COMMIT_ID2}</code></dd><dt>From:</dt><dd>${COMMITTER} &lt;${COMMITTER_EMAIL}&gt;</dd><dt>Date:</dt><dd><time datetime="${COMMIT_YMDHMS2}">${COMMIT_DATE2}
+ UTC</time></dd></dl></div><hr /><div class="commit">
+${LOGMSG2}
+</div><div class="navs_wrapper"><div class="navs"><a href="?action=diff&commit=${COMMIT_ID2}&path=repo.git">diff</a> | <a href="?action=patch&commit=${COMMIT_ID2}&path=repo.git">patch</a> | <a href="?action=tree&commit=${COMMIT_ID2}&path=repo.git">tree</a></div></div><hr /><div class="page_header_wrapper"><dl><dt>Commit:</dt><dd><code class="commit-id">${COMMIT_ID3}</code></dd><dt>From:</dt><dd>${COMMITTER} &lt;${COMMITTER_EMAIL}&gt;</dd><dt>Date:</dt><dd><time datetime="${COMMIT_YMDHMS3}">${COMMIT_DATE3}
+ UTC</time></dd></dl></div><hr /><div class="commit">
+${LOGMSG3}
+</div><div class="navs_wrapper"><div class="navs"><a href="?action=diff&commit=${COMMIT_ID3}&path=repo.git">diff</a> | <a href="?action=patch&commit=${COMMIT_ID3}&path=repo.git">patch</a> | <a href="?action=tree&commit=${COMMIT_ID3}&path=repo.git">tree</a></div></div><hr /><div id="np_wrapper"><div id="nav_more"><a href="?action=commits&commit=${COMMIT_ID_MORE}&headref=HEAD&path=repo.git">More&nbsp;&darr;</a></div></div></div></main><footer id="site_owner_wrapper"><p id="site_owner">Got Owner</p></footer></body></html>

blob - /dev/null
blob + ee353a9c8c369e0d33e69d970b1f70fdbd3a3f6f (mode 644)
--- /dev/null
+++ regress/gotwebd/test_gotwebd_paginate.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+#
+# Copyright (c) 2025 Mark Jamsek <mark@jamsek.dev>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+. ${GOTWEBD_TEST_DATA_DIR}/common.sh
+
+test_gotwebd_paginate_commits()
+{
+	local testroot=$(test_init gotwebd_paginate_commits 1)
+	local wt="$testroot/wt"
+	local repo="${GOTWEBD_TEST_CHROOT}/got/public/repo.git"
+	local ids="$(git_show_head $repo)"
+	local dates="$(git_show_author_time $repo)"
+
+	got checkout "$repo" "$wt" > /dev/null
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got checkout failed unexpectedly"
+		test_done "$testroot" "$repo" "$ret"
+		return 1
+	fi
+
+	cd "$wt"
+
+	for i in $(seq 2 $GOTWEBD_TEST_PAGINATE_NITEMS); do
+		echo "alpha $i" > alpha
+
+		got commit -m "commit $i" > /dev/null
+		ret=$?
+		if [ $ret -ne 0 ]; then
+			echo "got commit failed unexpectedly" >&2
+			test_done "$testroot" "$repo" "$ret"
+			return 1
+		fi
+
+		ids="$ids $(git_show_head "$repo")"
+		dates="$dates $(git_show_author_time "$repo")"
+	done
+
+	for i in $(seq $GOTWEBD_TEST_PAGINATE_NITEMS -3 1); do
+		local id_more=$i
+		local id=$(pop_idx $i $ids)
+		local d1=$(pop_idx $i $dates)
+		local d2=$(pop_idx $((i - 1)) $dates)
+		local d3=$(pop_idx $((i - 2)) $dates)
+		local logmsg3="commit $((i - 2))"
+		local page="${GOTWEBD_TEST_DATA_DIR}/commits_page.html"
+		local qs="action=commits&commit=${id}&path=repo.git"
+
+		if [ $i -gt 3 ]; then
+			id_more=$((i - 3))
+		else
+			# remove "nav_more" div from the final page footer
+			perl -pe 'substr($_, 275, 150, q{}) if eof' "$page" \
+			    > "$testroot/commits_page_end.html"
+			page="$testroot/commits_page_end.html"
+			logmsg3="import the test tree"
+		fi
+
+		LOGMSG1="commit $i" \
+		LOGMSG2="commit $((i - 1))" \
+		LOGMSG3="$logmsg3" \
+		COMMITTER="Flan Hacker" \
+		COMMIT_ID1="$id" \
+		COMMIT_ID2=$(pop_idx $((i - 1)) $ids) \
+		COMMIT_ID3=$(pop_idx $((i - 2)) $ids) \
+		COMMIT_ID_MORE=$(pop_idx $id_more $ids) \
+		COMMITTER_EMAIL="flan_hacker@openbsd.org" \
+		COMMIT_YMDHMS1=$(date -u -r $d1 +"%FT%TZ") \
+		COMMIT_YMDHMS2=$(date -u -r $d2 +"%FT%TZ") \
+		COMMIT_YMDHMS3=$(date -u -r $d3 +"%FT%TZ") \
+		COMMIT_DATE1=$(date -u -r $d1 +"%a %b %e %X %Y") \
+		COMMIT_DATE2=$(date -u -r $d2 +"%a %b %e %X %Y") \
+		COMMIT_DATE3=$(date -u -r $d3 +"%a %b %e %X %Y") \
+		interpolate "$page" > "$testroot/content.expected"
+
+		$GOTWEBD_TEST_FCGI -q "$qs" > "$testroot/content"
+
+		cmp -s $testroot/content.expected $testroot/content
+		ret=$?
+		if [ $ret -ne 0 ]; then
+			diff -u $testroot/content.expected $testroot/content
+			test_done "$testroot" "$repo" "$ret"
+			return 1
+		fi
+	done
+
+	test_done "$testroot" "$repo" 0
+}
+
+test_parseargs "$@"
+run_test test_gotwebd_paginate_commits