"GOT", but the "O" is a cute, smiling sun Index | Thread

From:
Stefan Sperling <stsp@stsp.name>
Subject:
new gotd regression test: test_repo_write_empty
To:
gameoftrees@openbsd.org
Date:
Mon, 7 Nov 2022 21:40:11 +0100

Download raw body.

This tests gotd by sending to empty repositories. Testing this use
case this uncovered a couple of bugs in several places. I fixed
some bugs directly on the main branch, and some bugs have outstanding
fixes on this list I sent earlier today.

With all those changes, this new test is passing.

ok? (will commit on top of all the other changes once they are in)

diff 5a3cf3b6bde9a6f3b33391a2229d7a6870417361 073e150a7dbb6832e56f9db10ab893441e996dfd
commit - 5a3cf3b6bde9a6f3b33391a2229d7a6870417361
commit + 073e150a7dbb6832e56f9db10ab893441e996dfd
blob - 785eb48bd53304382de88cd45d349c595ff2ec96
blob + 0ac2352fd9d6c39216dc6fe24a959fdd62f17cbe
--- regress/gotd/Makefile
+++ regress/gotd/Makefile
@@ -1,4 +1,4 @@
-REGRESS_TARGETS=test_repo_read test_repo_write
+REGRESS_TARGETS=test_repo_read test_repo_write test_repo_write_empty
 NOOBJ=Yes
 
 .PHONY: ensure_root prepare_test_repo check_test_repo start_gotd
@@ -25,6 +25,7 @@ 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) \
+	GOTD_DEVUSER=$(GOTD_DEVUSER) \
 	HOME=$(GOTD_TEST_USER_HOME) \
 	PATH=$(GOTD_TEST_USER_HOME)/bin:$(PATH)
 
@@ -48,6 +49,10 @@ test_repo_read: prepare_test_repo start_gotd
 	@chown ${GOTD_USER} "${GOTD_TEST_REPO}"
 	@su -m ${GOTD_USER} -c 'env $(GOTD_TEST_ENV) sh ./prepare_test_repo.sh'
 
+prepare_test_repo_empty: ensure_root
+	@chown ${GOTD_USER} "${GOTD_TEST_REPO}"
+	@su -m ${GOTD_USER} -c 'env $(GOTD_TEST_ENV) sh ./prepare_test_repo.sh 1'
+
 test_repo_read: prepare_test_repo start_gotd
 	@-$(GOTD_TRAP); su ${GOTD_TEST_USER} -c \
 		'env $(GOTD_TEST_ENV) sh ./repo_read.sh'
@@ -59,5 +64,11 @@ test_repo_write: prepare_test_repo start_gotd
 		'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'
+
+test_repo_write_empty: prepare_test_repo_empty start_gotd
+	@-$(GOTD_TRAP); su ${GOTD_TEST_USER} -c \
+		'env $(GOTD_TEST_ENV) sh ./repo_write_empty.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 - 712a02a775533761863f614cf975ef0dae5a8b49
blob + 24bceaedbd0b5f96864aeb98fb8f75684810689b
--- regress/gotd/prepare_test_repo.sh
+++ regress/gotd/prepare_test_repo.sh
@@ -16,14 +16,27 @@ if [ -e "${GOTD_TEST_REPO}" ]; then
 
 . ../cmdline/common.sh
 
+make_repo()
+{
+	local repo_path="$1"
+	local no_tree="$2"
+
+	gotadmin init "${repo_path}"
+
+	if [ -n "$no_tree" ]; then
+		return
+	fi
+
+	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
+}
+
+
 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
+make_repo "${GOTD_TEST_REPO}" "$1"
blob - /dev/null
blob + ff025cb335faccdf7917ec4892f40d2cb1f25548 (mode 644)
--- /dev/null
+++ regress/gotd/repo_write_empty.sh
@@ -0,0 +1,153 @@
+#!/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_empty() {
+	local testroot=`test_init send_empty`
+	local commit_id=`git_show_head $testroot/repo`
+
+	(cd ${GOTD_TEST_REPO} && find . > $testroot/repo-list.before)
+
+	# The gotd-controlled test repository starts out empty.
+	got ref -l -r ${GOTD_TEST_REPO} > $testroot/ref-list.before
+	echo "HEAD: refs/heads/main" > $testroot/ref-list.expected
+	cmp -s $testroot/ref-list.expected $testroot/ref-list.before
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/ref-list.expected $testroot/ref-list.before
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	got checkout -q $testroot/repo $testroot/wt >/dev/null
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got checkout failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	# send contents of $testroot/repo to ${GOTD_TEST_REPO}
+	cat >> $testroot/wt/.got/got.conf <<EOF
+remote "gotd" {
+	server ${GOTD_DEVUSER}@127.0.0.1
+	repository "test-repo"
+	protocol ssh
+}
+EOF
+	(cd $testroot/wt && got send -q -a gotd)
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got send failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	# Server should have created a new reference.
+	got ref -l -r ${GOTD_TEST_REPO} > $testroot/ref-list.after
+	cat > $testroot/ref-list.expected <<EOF
+HEAD: refs/heads/main
+refs/heads/master: $commit_id
+EOF
+	cmp -s $testroot/ref-list.expected $testroot/ref-list.after
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/ref-list.expected $testroot/ref-list.after
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# Verify that the result can be cloned again.
+	# XXX need -b master at present because gotd does not rewrite HEAD
+	got clone -q -b master ${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
+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
+	(cd ${GOTD_TEST_REPO} && find . > $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" != "4" ]; then
+		echo "$nplus new files created:"
+		cat $testroot/repo-list.diff
+		test_done "$testroot" "1"
+		return 1
+	fi
+	egrep -q '\+\.\/objects\/pack\/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 '\+\.\/objects\/pack\/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
+	egrep -q '\+\.\/refs\/heads' $testroot/repo-list.newlines
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "new refs/heads directory not found"
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+	if ! [ -d ${GOTD_TEST_REPO}/refs/heads ]; then
+		echo "new refs/heads is not a directory"
+		test_done "$testroot" "1"
+		return 1
+	fi
+	egrep -q '\+\.\/refs\/heads\/master' $testroot/repo-list.newlines
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "new refs/heads/master not found"
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	test_done "$testroot" "$ret"
+}
+
+test_parseargs "$@"
+run_test test_send_empty