Commit Diff


commit - 1c9d898d6c7c6c8681e8e191ebe2c01b8d066f6e
commit + 6ae16afd7eb87b9d1ae10d16f29e1a66649decc7
blob - fe7db9a3d673041a04256447d4b529fc4109ed8c
blob + 99d51d96d08b0d903c4f125505849210d5da93b2
--- Makefile
+++ Makefile
@@ -55,4 +55,7 @@ server-install:
 	${MAKE} -C gotd install
 	${MAKE} -C gotsh install
 
+server-regress:
+	${MAKE} -C regress/gotd
+
 .include <bsd.subdir.mk>
blob - b970ee903b827d35f5b176c68200ec092a13d4e8
blob + 6e6a2e8391b5ff02c1bdb7753f0ec1b51a1ff8a9
--- README
+++ README
@@ -76,7 +76,9 @@ See the following manual page files for information ab
  $ man -l gotctl/gotctl.8
  $ man -l gotsh/gotsh.1
 
+See regress/gotd/README for information about running the server test suite.
 
+
 Game of Trees Web (Gotweb) is a CGI program which displays repository data
 and is designed to work with httpd(8) and slowcgi(8). It requires the Kristaps
 Dzonsons kcgi library, version 0.12.0 or greater.
blob - /dev/null
blob + 7c2992be4f288b02a06aa7cc8ee97b9df22737f2 (mode 644)
--- /dev/null
+++ regress/gotd/Makefile
@@ -0,0 +1,63 @@
+REGRESS_TARGETS=test_repo_read test_repo_write
+NOOBJ=Yes
+
+.PHONY: ensure_root prepare_test_repo check_test_repo start_gotd
+
+GOTD_TEST_ROOT=/tmp
+GOTD_DEVUSER?=gotdev
+GOTD_DEVUSER_HOME!=userinfo $(GOTD_DEVUSER) | grep ^dir | awk '{print $$2}'
+GOTD_TEST_REPO!?=mktemp -d "$(GOTD_TEST_ROOT)/gotd-test-repo-XXXXXXXXX"
+GOTD_TEST_REPO_URL=ssh://${GOTD_DEVUSER}@127.0.0.1/test-repo
+
+GOTD_TEST_USER?=${LOGNAME}
+GOTD_TEST_USER_HOME!=userinfo $(GOTD_TEST_USER) | grep ^dir | awk '{print $$2}'
+
+# gotd.conf parameters
+GOTD_USER?=got
+GOTD_GROUP?=gotsh
+GOTD_SOCK=${GOTD_DEVUSER_HOME}/gotd.sock
+
+GOTD_START_CMD=../../gotd/obj/gotd -vv -f $(PWD)/gotd.conf
+GOTD_STOP_CMD=../../gotctl/obj/gotctl -f $(GOTD_SOCK) stop
+GOTD_TRAP=trap "$(GOTD_STOP_CMD)" HUP INT QUIT PIPE TERM
+
+GOTD_TEST_ENV=GOTD_TEST_ROOT=$(GOTD_TEST_ROOT) \
+	GOTD_TEST_REPO_URL=$(GOTD_TEST_REPO_URL) \
+	GOTD_TEST_REPO=$(GOTD_TEST_REPO) \
+	GOTD_SOCK=$(GOTD_SOCK) \
+	HOME=$(GOTD_TEST_USER_HOME) \
+	PATH=$(GOTD_TEST_USER_HOME)/bin:$(PATH)
+
+ensure_root:
+	@if [[ `id -u` -ne 0 ]]; then \
+		echo gotd test suite must be run by root >&2; \
+		false; \
+	fi
+
+start_gotd: ensure_root
+	@echo 'unix_socket "$(GOTD_SOCK)"' > $(PWD)/gotd.conf
+	@echo "unix_group $(GOTD_GROUP)" >> $(PWD)/gotd.conf
+	@echo "user $(GOTD_USER)" >> $(PWD)/gotd.conf
+	@echo 'repository "test-repo" {' >> $(PWD)/gotd.conf
+	@echo '    path "$(GOTD_TEST_REPO)"' >> $(PWD)/gotd.conf
+	@echo "}" >> $(PWD)/gotd.conf
+	@$(GOTD_TRAP); $(GOTD_START_CMD)
+	@$(GOTD_TRAP); sleep .5
+
+prepare_test_repo: ensure_root
+	@chown ${GOTD_USER} "${GOTD_TEST_REPO}"
+	@su -m ${GOTD_USER} -c 'env $(GOTD_TEST_ENV) sh ./prepare_test_repo.sh'
+
+test_repo_read: prepare_test_repo start_gotd
+	@-$(GOTD_TRAP); su ${GOTD_TEST_USER} -c \
+		'env $(GOTD_TEST_ENV) sh ./repo_read.sh'
+	@$(GOTD_STOP_CMD) 2>/dev/null
+	@su -m ${GOTD_USER} -c 'env $(GOTD_TEST_ENV) sh ./check_test_repo.sh'
+
+test_repo_write: prepare_test_repo start_gotd
+	@-$(GOTD_TRAP); su ${GOTD_TEST_USER} -c \
+		'env $(GOTD_TEST_ENV) sh ./repo_write.sh'
+	@$(GOTD_STOP_CMD) 2>/dev/null
+	@su -m ${GOTD_USER} -c 'env $(GOTD_TEST_ENV) sh ./check_test_repo.sh'
+	
+.include <bsd.regress.mk>
blob - /dev/null
blob + e45f172997d4e491bc2a34fe0494284c43c94cfb (mode 644)
--- /dev/null
+++ regress/gotd/README
@@ -0,0 +1,57 @@
+Running server regression tests requires some manual system preparation.
+
+Two dedicated user accounts and a group must be created. Password login
+for these users should be disabled by passing a blank password to useradd
+and confirming useradd's question about disabling passwords with 'yes'.
+
+ $ doas adduser got
+ $ doas adduser gotdev
+ $ doas addgroup gotsh
+
+The above user and group names correspond to defaults used by the test suite.
+If needed, the defaults can be overridden on by passing values for the
+following variables to make(1): GOTD_USER, GOTD_DEVUSER, GOTD_GROUP
+
+An SSH key must be added to ~gotdev/.ssh/authorized_keys, such that the
+following command succeeds non-interactively:
+
+ $ ssh gotdev@127.0.0.1
+
+The login shell of the gotdev user should be set to gotsh(1).
+It is recommended to run the test suite using a locally built gotsh binary,
+rather than /usr/local/bin/gotsh (which might be using messages in an
+out-of-date format on the gotd socket).
+For this to work, $HOME/bin/gotsh must be added to /etc/shells first.
+
+ $ doas usermod -s $HOME/bin/gotsh gotdev
+
+If adding this file to /etc/shells is a problem, a locally built gotsh
+binary can be made available in the command search path of the gotdev
+user under the names git-receive-pack and git-upload-pack. When made
+available in a non-standard PATH directory such as ~gotdev/bin, the
+gotdev user's PATH must be set appropriately in sshd_config (see below).
+
+Tests will run the locally built gotd binary found in gotd/obj/gotd.
+The test suite creates the corresponding gotd socket in ~gotdev/gotd.sock.
+To make this work, the GOTD_UNIX_SOCKET variable must be set by sshd
+when the gotdev user logs in. The following should be added to the file
+/etc/ssh/sshd_config:
+
+ Match User gotdev
+    SetEnv GOTD_UNIX_SOCKET=/home/gotdev/gotd.sock
+    # The following line is not needed when gotsh is used as login shell:
+    SetEnv PATH=/home/gotdev/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
+    DisableForwarding yes
+    PermitTTY no
+
+sshd must be restarted for configuration changes to take effect:
+
+ $ doas rcctl restart sshd
+
+The server test suite can now be run from the top-level directory:
+
+ $ doas pkg_add git  # if not already done
+ $ doas make server-regress
+
+The suite must be started as root in order to be able to start and stop gotd.
+The test suite switches to non-root users as appropriate.
blob - /dev/null
blob + dfb810129ddb968ff5a57845ede251ff9daead91 (mode 644)
--- /dev/null
+++ regress/gotd/check_test_repo.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Copyright (c) 2022 Stefan Sperling <stsp@openbsd.org>
+#
+# 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.
+
+. ../cmdline/common.sh
+
+git_fsck "${GOTD_TEST_REPO}" "${GOTD_TEST_REPO}"
blob - /dev/null
blob + 016110f9a8369c7d2288fbc68fa858b04c36f2c4 (mode 644)
--- /dev/null
+++ regress/gotd/common.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# Copyright (c) 2022 Stefan Sperling <stsp@openbsd.org>
+#
+# 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.
+
+test_init()
+{
+	local testname="$1"
+	local no_tree="$2"
+	if [ -z "$testname" ]; then
+		echo "No test name provided" >&2
+		return 1
+	fi
+	local testroot=`mktemp -d "$GOTD_TEST_ROOT/gotd-test-$testname-XXXXXXXX"`
+	mkdir $testroot/repo
+	git_init $testroot/repo
+	if [ -z "$no_tree" ]; then
+		make_test_tree $testroot/repo
+		(cd $repo && git add .)
+		git_commit $testroot/repo -m "adding the test tree"
+	fi
+	echo "$testroot"
+}
+
+test_done()
+{
+	local testroot="$1"
+	local result="$2"
+	if [ "$result" = "0" ]; then
+		test_cleanup "$testroot" || return 1
+		if [ -z "$GOT_TEST_QUIET" ]; then
+			echo "ok"
+		fi
+	elif echo "$result" | grep -q "^xfail"; then
+		# expected test failure; test reproduces an unfixed bug
+		echo "$result"
+		test_cleanup "$testroot" || return 1
+	else
+		echo "test failed; leaving test data in $testroot"
+	fi
+}
blob - /dev/null
blob + 712a02a775533761863f614cf975ef0dae5a8b49 (mode 644)
--- /dev/null
+++ regress/gotd/prepare_test_repo.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Copyright (c) 2022 Stefan Sperling <stsp@openbsd.org>
+#
+# 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.
+
+. ../cmdline/common.sh
+
+if [ -e "${GOTD_TEST_REPO}" ]; then
+	rm -rf "${GOTD_TEST_REPO}"
+fi
+
+gotadmin init "${GOTD_TEST_REPO}"
+
+test_tree=`mktemp -d "${GOTD_TEST_ROOT}/gotd-test-tree-XXXXXXXXX"`
+make_test_tree "$test_tree"
+got import -m "import the test tree" -r "${GOTD_TEST_REPO}" "$test_tree" \
+	> /dev/null
+rm -r "$test_tree" # TODO: trap
blob - /dev/null
blob + 82df572967b423dd79abedbe9e1315e14be9b6bf (mode 644)
--- /dev/null
+++ regress/gotd/repo_read.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+#
+# Copyright (c) 2022 Stefan Sperling <stsp@openbsd.org>
+#
+# 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.
+
+. ../cmdline/common.sh
+. ./common.sh
+
+test_clone_basic() {
+	local testroot=`test_init clone_basic 1`
+
+	cp -r ${GOTD_TEST_REPO} $testroot/repo-copy
+
+	got clone -q ${GOTD_TEST_REPO_URL} $testroot/repo-clone
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got clone failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	# Verify that the clone operation worked fine.
+	git_fsck "$testroot" "$testroot/repo-clone"
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	got tree -R -r "$testroot/repo-clone" > $testroot/stdout
+	cat > $testroot/stdout.expected <<EOF
+alpha
+beta
+epsilon/
+epsilon/zeta
+gamma/
+gamma/delta
+EOF
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# cloning a repository should not result in modifications
+	diff -urN ${GOTD_TEST_REPO} $testroot/repo-copy \
+		> $testroot/stdout
+	echo -n > $testroot/stdout.expected
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	test_done "$testroot" "$ret"
+}
+
+test_parseargs "$@"
+run_test test_clone_basic
blob - /dev/null
blob + 9ae1427dc0f407b85f6caeec7b424406e17b7cac (mode 644)
--- /dev/null
+++ regress/gotd/repo_write.sh
@@ -0,0 +1,114 @@
+#!/bin/sh
+#
+# Copyright (c) 2022 Stefan Sperling <stsp@openbsd.org>
+#
+# 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.
+
+. ../cmdline/common.sh
+. ./common.sh
+
+test_send_basic() {
+	local testroot=`test_init send_basic 1`
+
+	ls -R ${GOTD_TEST_REPO} > $testroot/repo-list.before
+
+	got clone -q ${GOTD_TEST_REPO_URL} $testroot/repo-clone
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got clone failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	got checkout -q $testroot/repo-clone $testroot/wt >/dev/null
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got checkout failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	mkdir $testroot/wt/psi
+	echo "new" > $testroot/wt/psi/new
+	(cd $testroot/wt && got add psi/new > /dev/null)
+	echo "more alpha" >> $testroot/wt/alpha
+	(cd $testroot/wt && got commit -m 'make changes' > /dev/null)
+
+	got send -q -r $testroot/repo-clone
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got send failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	# Verify that the send operation worked fine.
+	got clone -q ${GOTD_TEST_REPO_URL} $testroot/repo-clone2
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got clone failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	got tree -R -r $testroot/repo-clone2 > $testroot/stdout
+	cat > $testroot/stdout.expected <<EOF
+alpha
+beta
+epsilon/
+epsilon/zeta
+gamma/
+gamma/delta
+psi/
+psi/new
+EOF
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# sending to a repository should result in a new pack file
+	ls -R ${GOTD_TEST_REPO} > $testroot/repo-list.after
+	diff -u $testroot/repo-list.before $testroot/repo-list.after \
+		> $testroot/repo-list.diff
+	grep '^+[^+]' < $testroot/repo-list.diff > $testroot/repo-list.newlines
+	nplus=`wc -l < $testroot/repo-list.newlines | tr -d ' '`
+	if [ "$nplus" != "2" ]; then
+		echo "$nplus new files created"
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+	egrep -q '\+pack-[a-f0-9]{40}.pack' $testroot/repo-list.newlines
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "new pack file not found in ${GOTD_TEST_REPO}"
+		cat $testroot/repo-list.newlines
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+	egrep -q '\+pack-[a-f0-9]{40}.idx' $testroot/repo-list.newlines
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "new pack index not found in ${GOTD_TEST_REPO}"
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	test_done "$testroot" "$ret"
+}
+
+test_parseargs "$@"
+run_test test_send_basic