# Performance testing framework.  Each perf script starts much like
# a normal test script, except it sources this library instead of
# test-lib.sh.  See t/perf/README for documentation.
#
# Copyright (c) 2011 Thomas Rast
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see http://www.gnu.org/licenses/ .

# do the --tee work early; it otherwise confuses our careful
# GIT_BUILD_DIR mangling
case "$GIT_TEST_TEE_STARTED, $* " in
done,*)
	# do not redirect again
	;;
*' --tee '*|*' --va'*)
	mkdir -p test-results
	BASE=test-results/$(basename "$0" .sh)
	(GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
	 echo $? > $BASE.exit) | tee $BASE.out
	test "$(cat $BASE.exit)" = 0
	exit
	;;
esac

TEST_DIRECTORY=$(pwd)/..
TEST_OUTPUT_DIRECTORY=$(pwd)
if test -z "$GIT_TEST_INSTALLED"; then
	perf_results_prefix=
else
	perf_results_prefix=$(printf "%s" "${GIT_TEST_INSTALLED%/bin-wrappers}" | tr -c "[a-zA-Z0-9]" "[_*]")"."
	# make the tested dir absolute
	GIT_TEST_INSTALLED=$(cd "$GIT_TEST_INSTALLED" && pwd)
fi

TEST_NO_CREATE_REPO=t
TEST_NO_MALLOC_CHECK=t

. ../test-lib.sh

# Variables from test-lib that are normally internal to the tests; we
# need to export them for test_perf subshells
export TEST_DIRECTORY TRASH_DIRECTORY GIT_BUILD_DIR GIT_TEST_CMP

MODERN_GIT=$GIT_BUILD_DIR/bin-wrappers/git
export MODERN_GIT

perf_results_dir=$TEST_OUTPUT_DIRECTORY/test-results
mkdir -p "$perf_results_dir"
rm -f "$perf_results_dir"/$(basename "$0" .sh).subtests

if test -z "$GIT_PERF_REPEAT_COUNT"; then
	GIT_PERF_REPEAT_COUNT=3
fi
die_if_build_dir_not_repo () {
	if ! ( cd "$TEST_DIRECTORY/.." &&
		    git rev-parse --build-dir >/dev/null 2>&1 ); then
		error "No $1 defined, and your build directory is not a repo"
	fi
}

if test -z "$GIT_PERF_REPO"; then
	die_if_build_dir_not_repo '$GIT_PERF_REPO'
	GIT_PERF_REPO=$TEST_DIRECTORY/..
fi
if test -z "$GIT_PERF_LARGE_REPO"; then
	die_if_build_dir_not_repo '$GIT_PERF_LARGE_REPO'
	GIT_PERF_LARGE_REPO=$TEST_DIRECTORY/..
fi

test_perf_create_repo_from () {
	test "$#" = 2 ||
	error "bug in the test script: not 2 parameters to test-create-repo"
	repo="$1"
	source="$2"
	source_git="$(git -C "$source" rev-parse --git-dir)"
	objects_dir="$("$MODERN_GIT" -C "$source" rev-parse --git-path objects)"
	mkdir -p "$repo/.git"
	(
		cd "$source" &&
		{ cp -Rl "$objects_dir" "$repo/.git/" 2>/dev/null ||
			cp -R "$objects_dir" "$repo/.git/"; } &&
		for stuff in "$source_git"/*; do
			case "$stuff" in
				*/objects|*/hooks|*/config|*/commondir)
					;;
				*)
					cp -R "$stuff" "$repo/.git/" || exit 1
					;;
			esac
		done
	) &&
	(
		cd "$repo" &&
		git init -q && {
			test_have_prereq SYMLINKS ||
			git config core.symlinks false
		} &&
		mv .git/hooks .git/hooks-disabled 2>/dev/null
	) || error "failed to copy repository '$source' to '$repo'"
}

# call at least one of these to establish an appropriately-sized repository
test_perf_default_repo () {
	test_perf_create_repo_from "${1:-$TRASH_DIRECTORY}" "$GIT_PERF_REPO"
}
test_perf_large_repo () {
	if test "$GIT_PERF_LARGE_REPO" = "$GIT_BUILD_DIR"; then
		echo "warning: \$GIT_PERF_LARGE_REPO is \$GIT_BUILD_DIR." >&2
		echo "warning: This will work, but may not be a sufficiently large repo" >&2
		echo "warning: for representative measurements." >&2
	fi
	test_perf_create_repo_from "${1:-$TRASH_DIRECTORY}" "$GIT_PERF_LARGE_REPO"
}
test_checkout_worktree () {
	git checkout-index -u -a ||
	error "git checkout-index failed"
}

# Performance tests should never fail.  If they do, stop immediately
immediate=t

# Perf tests require GNU time
case "$(uname -s)" in Darwin) GTIME="${GTIME:-gtime}";; esac
GTIME="${GTIME:-/usr/bin/time}"

test_run_perf_ () {
	test_cleanup=:
	test_export_="test_cleanup"
	export test_cleanup test_export_
	"$GTIME" -f "%E %U %S" -o test_time.$i "$SHELL" -c '
. '"$TEST_DIRECTORY"/test-lib-functions.sh'
test_export () {
	[ $# != 0 ] || return 0
	test_export_="$test_export_\\|$1"
	shift
	test_export "$@"
}
'"$1"'
ret=$?
set | sed -n "s'"/'/'\\\\''/g"';s/^\\($test_export_\\)/export '"'&'"'/p" >test_vars
exit $ret' >&3 2>&4
	eval_ret=$?

	if test $eval_ret = 0 || test -n "$expecting_failure"
	then
		test_eval_ "$test_cleanup"
		. ./test_vars || error "failed to load updated environment"
	fi
	if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
		echo ""
	fi
	return "$eval_ret"
}


test_perf () {
	test_start_
	test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
	test "$#" = 2 ||
	error "bug in the test script: not 2 or 3 parameters to test-expect-success"
	export test_prereq
	if ! test_skip "$@"
	then
		base=$(basename "$0" .sh)
		echo "$test_count" >>"$perf_results_dir"/$base.subtests
		echo "$1" >"$perf_results_dir"/$base.$test_count.descr
		if test -z "$verbose"; then
			printf "%s" "perf $test_count - $1:"
		else
			echo "perf $test_count - $1:"
		fi
		for i in $(test_seq 1 $GIT_PERF_REPEAT_COUNT); do
			say >&3 "running: $2"
			if test_run_perf_ "$2"
			then
				if test -z "$verbose"; then
					printf " %s" "$i"
				else
					echo "* timing run $i/$GIT_PERF_REPEAT_COUNT:"
				fi
			else
				test -z "$verbose" && echo
				test_failure_ "$@"
				break
			fi
		done
		if test -z "$verbose"; then
			echo " ok"
		else
			test_ok_ "$1"
		fi
		base="$perf_results_dir"/"$perf_results_prefix$(basename "$0" .sh)"."$test_count"
		"$TEST_DIRECTORY"/perf/min_time.perl test_time.* >"$base".times
	fi
	test_finish_
}

# We extend test_done to print timings at the end (./run disables this
# and does it after running everything)
test_at_end_hook_ () {
	if test -z "$GIT_PERF_AGGREGATING_LATER"; then
		( cd "$TEST_DIRECTORY"/perf && ./aggregate.perl $(basename "$0") )
	fi
}

test_export () {
	export "$@"
}
