#!/bin/sh

# please always adjust the length of file to be 1000 lines
#
# This file is auto generated, do not modify it or your changes
# might be lost.
#
# shell test suite v0.6 for kdb command


#
# VARIABLES
#

NEWLINE='
'

# variables to count up errors and tests
nbError=0
nbTest=0
nbSkip=0

# the script itself
scriptName=`basename "$0"`

MOUNTPOINT="/tests/script"

NAMESPACES="user system"

USER_ROOT="user/tests/script"
SYSTEM_ROOT="system/tests/script"

ROOTS="$USER_ROOT $SYSTEM_ROOT"

IS_INSTALLED=YES
if [ "x$IS_INSTALLED" = "xYES" ]
then
	DATADIR="/usr/share/elektra/test_data/shell"
else
	DATADIR="/chakra/desktop/elektra/src/libelektra-0.8.24/tests/shell/shell"
fi

USER="`id -un`"
GROUP="`id -gn`"

SYSTEM_FOLDER=/etc/kdb
if [ -n "$HOME" ]
then
	USER_FOLDER=$HOME/.config
else
	USER_FOLDER=/home/$USER/.config
fi
PLUGINS=`echo "base64;boolean;c;camel;ccode;conditionals;constants;counter;crypto_gcrypt;crypto_openssl;csvstorage;curlget;date;dbus;desktop;dini;directoryvalue;dpkg;dump;enum;error;fcrypt;filecheck;fstab;glob;hexcode;hexnumber;hidden;hosts;iconv;ini;ipaddr;journald;keytometa;line;lineendings;list;logchange;mathcheck;mini;multifile;network;ni;noresolver;null;path;profile;range;regexstore;rename;required;resolver_fm_b_b;resolver_fm_hb_b;resolver_fm_hp_b;resolver_fm_hpu_b;resolver_fm_pb_b;resolver_fm_ub_x;resolver_fm_uhb_xb;resolver_fm_xb_x;resolver_fm_xhp_x;resolver_fm_xp_x;shell;simpleini;spec;struct;sync;syslog;timeofday;tracer;type;uname;validation;wresolver;xmltool" | tr ';' ' '`
ADDED_PLUGINS_WITHOUT_ONLY_SHARED=`echo "base64;boolean;c;camel;ccode;conditionals;constants;counter;crypto_gcrypt;crypto_openssl;csvstorage;curlget;date;dbus;desktop;dini;directoryvalue;dpkg;dump;enum;error;fcrypt;filecheck;fstab;glob;hexcode;hexnumber;hidden;hosts;iconv;ini;ipaddr;journald;keytometa;line;lineendings;list;logchange;mathcheck;mini;multifile;network;ni;noresolver;null;path;profile;range;regexstore;rename;required;resolver_fm_b_b;resolver_fm_hb_b;resolver_fm_hp_b;resolver_fm_hpu_b;resolver_fm_pb_b;resolver_fm_ub_x;resolver_fm_uhb_xb;resolver_fm_xb_x;resolver_fm_xhp_x;resolver_fm_xp_x;shell;simpleini;spec;struct;sync;syslog;timeofday;tracer;type;uname;validation;wresolver;xmltool" | tr ';' ' '`
PLUGINS_NEWLINES=`echo "base64;boolean;c;camel;ccode;conditionals;constants;counter;crypto_gcrypt;crypto_openssl;csvstorage;curlget;date;dbus;desktop;dini;directoryvalue;dpkg;dump;enum;error;fcrypt;filecheck;fstab;glob;hexcode;hexnumber;hidden;hosts;iconv;ini;ipaddr;journald;keytometa;line;lineendings;list;logchange;mathcheck;mini;multifile;network;ni;noresolver;null;path;profile;range;regexstore;rename;required;resolver_fm_b_b;resolver_fm_hb_b;resolver_fm_hp_b;resolver_fm_hpu_b;resolver_fm_pb_b;resolver_fm_ub_x;resolver_fm_uhb_xb;resolver_fm_xb_x;resolver_fm_xhp_x;resolver_fm_xp_x;shell;simpleini;spec;struct;sync;syslog;timeofday;tracer;type;uname;validation;wresolver;xmltool" | tr ';' '\n'`

DATE=`date "+%b %d %H:%M"`

KDB_DEFAULT_STORAGE="dump"
KDB_DEFAULT_RESOLVER="resolver_fm_hpu_b"

KDB_GETENV=`kdb elektrify-getenv getenv KDB 2> /dev/null`

if [ "${KDB_GETENV}" ]
then
	KDB=${KDB_GETENV};
fi

# ensure ruby plugin finds Ruby bindings without installation
# (require both the src and the build dir)
export RUBYLIB="/chakra/desktop/elektra/src/libelektra-0.8.24/src/bindings/swig/ruby:/chakra/desktop/elektra/src/libelektra-0.8.24/build/src/bindings/swig/ruby"
export SAVE=0 # some Rubies do not accept RUBYLIB if SAVE is not 0

#
# HELPER
#

# POSIX way to test if string contains substring
contains() {
    string="$1"
    substring="$2"
    test "${string#*$substring}" != "$string"
}

#
# ASSERTIONS
#

#succeed if the previous command was successful
succeed_if ()
{
	if [ $? != "0" ]
	then
		nbError=$(( $nbError + 1 ))
		echo error: $*
	fi
	nbTest=$(( $nbTest + 1 ))
}

#fails and exits the program if the previous command failed
exit_if_fail ()
{
	if [ $? != "0" ]
	then
		if command -v cleanup > /dev/null
		then
			echo "fatal: $*"
			cleanup
		else
			echo "fatal (no cleanup necessary): $*"
		fi
		exit 1
	fi
	nbTest=$(( $nbTest + 1 ))
}

end_script()
{
	if command -v cleanup > /dev/null
	then
		cleanup
	fi

	printf "$scriptName RESULTS: $nbTest test(s) done"
	if [ $nbSkip -ne 0 ]
	then
		printf " $nbSkip skipped"
	fi
	echo " $nbError error(s)."
	exit "$nbError"
}


#
# COMMON CHECKS
#
KDB_VERSION="0.8.24"
SO_VERSION="4"

check_version()
{
	echo "Check if script tests the correct version"

	if [ "x`kdb elektrify-getenv getenv CHECK_VERSION 2> /dev/null`" = "xNO" ]
	then
		return 0
	fi

	#if no kdb elektrify-getenv getenv is installed:
	if [ "x$CHECK_VERSION" = "xNO" ]
	then
		return 0
	fi

	REAL_KDB_VERSION="`"$KDB" get system/elektra/version/constants/KDB_VERSION 2> /dev/null`"
	[ "x$REAL_KDB_VERSION" = "x$KDB_VERSION" ]
	exit_if_fail "Script was not compiled ($KDB_VERSION) with this elektra version ($REAL_KDB_VERSION): KDB_VERSION mismatch for kdb-tool ($KDB), use CHECK_VERSION=NO to disable"

	REAL_SO_VERSION="`"$KDB" get system/elektra/version/constants/SO_VERSION 2> /dev/null`"
	[ "x$REAL_SO_VERSION" = "x$SO_VERSION" ]
	exit_if_fail "Script was not compiled ($SO_VERSION) with this elektra version ($REAL_SO_VERSION): SO_VERSION mismatch for kdb-tool ($KDB), use CHECK_VERSION=NO to disable"
}

check_remaining_files()
{
	USER_REMAINING="`find $USER_FOLDER -maxdepth 1 -name $1'*' -print -quit`"
	test -z "$USER_REMAINING"
	exit_if_fail "files $USER_REMAINING in $USER_FOLDER would be removed during tests, so test is aborted"

	SYSTEM_REMAINING="`find $SYSTEM_FOLDER -maxdepth 1 -name $1'*' -print -quit`"
	test -z "$SYSTEM_REMAINING"
	exit_if_fail "files $SYSTEM_REMAINING in $SYSTEM_FOLDER would be removed during tests, so test is aborted"
}

check_set_rm()
{
	"$KDB" set "$1" "$2" 1>/dev/null
	succeed_if "could not set $1 with $2"

	[ "x`"$KDB" get "$1" 2> /dev/null`" = "x$2" ]
	succeed_if "cant get $1 (expected $2)"

	"$KDB" rm "$1" 1>/dev/null
	succeed_if "could not rm $1 (having value $2)"

	[ "x`"$KDB" sget $1 defvalue 2> /dev/null`" = "xdefvalue" ]
	succeed_if "Value still there after remove"
}


check_set_mv_rm()
{
	"$KDB" set "$1" "$3" 1>/dev/null
	succeed_if "could not set $1 with $3"

	[ "x`"$KDB" get "$1" 2> /dev/null`" = "x$3" ]
	succeed_if "cant get $1 (expected $3)"

	"$KDB" mv "$1" "$2" 1>/dev/null
	succeed_if "could not mv $1 to $2"

	[ "x`"$KDB" sget $1 defvalue 2> /dev/null`" = "xdefvalue" ]
	succeed_if "Value still there after move"

	[ "x`"$KDB" get "$2" 2> /dev/null`" = "x$3" ]
	succeed_if "cant get $2 (expected $3)"

	"$KDB" rm "$2" 1>/dev/null
	succeed_if "could not rm $2 (having value $3)"

	[ "x`"$KDB" sget $2 defvalue 2> /dev/null`" = "xdefvalue" ]
	succeed_if "Value still there after remove"
}



#
# COMMON UTILITIES
#


is_not_rw_storage()
{
	test ! "x`"$KDB" info $PLUGIN provides 2>/dev/null`" = "xstorage" \
	-o "x$PLUGIN" = "xhosts" \
	-o "x$PLUGIN" = "xfstab" \
	-o "x$PLUGIN" = "xline" \
	-o "x$PLUGIN" = "xuname" \
	-o "x$PLUGIN" = "xconstants" \
	-o "x$PLUGIN" = "xaugeas" \
	-o "x$PLUGIN" = "xcsvstorage" \
	-o "x$PLUGIN" = "xdpkg" \
	-o "x$PLUGIN" = "xregexstore" \
	-o "x$PLUGIN" = "xpasswd" \
	-o "x$PLUGIN" = "xsimplespeclang" \
	-o "x$PLUGIN" = "xmozprefs" \
	-o "x$PLUGIN" = "xfile" \
	-o "x$PLUGIN" = "xruby"
}

is_plugin_available()
{
	for PLUGIN in $PLUGINS
	do
		if [ "x$1" = "x$PLUGIN" ]
		then
			return 0
		fi
	done
	return 1
}

mktempdir_elektra()
{
	mktemp -d 2>/dev/null || mktemp -d -t 'libelektra-test'
}

mktempfile_elektra()
{
	mktemp -t elektraenv.XXXXXXXXX 2>/dev/null || mktemp -t 'elektraenv'
}

replace_newline_return () {
	awk '{if (NR>1) {printf("%s⏎", line);} line=$0;} END { printf("%s\n", line); }'
}

printerr () {
	>&2 printf "$@"
}

#
# EXPORT FUNCTIONS
#


check_failed()
{
	EXPORTS=$1
	TESTNAME=$2
	CONFIGNAME=$3

	echo "$TESTNAME did not leave $CONFIGNAME config in the same state at is was before!"
	echo "This means the test itself is flawed or the KDB was externally modified while the tests were running!"
	echo "You can inspect the original $CONFIGNAME config in $EXPORTS/$CONFIGNAME.export.dump"
	echo "compared to situation now in $EXPORTS/$CONFIGNAME.check.dump"
	echo
	echo "Other important recovery files are also in the directory $EXPORTS"
	echo "Please remove the $EXPORTS directory yourself after you fixed the situation, I cannot do it for you"
	exit 1
}

export_config()
{
	EXPORTS=$1

	if [ ! -d "$EXPORTS" ]
	then
		echo "Failed to create directory “$EXPORTS”"
		exit 1
	fi

	SPECEXPORT="$EXPORTS/spec.export.dump"
	DIREXPORT="$EXPORTS/dir.export.dump"
	USEREXPORT="$EXPORTS/user.export.dump"
	SYSTEMEXPORT="$EXPORTS/system.export.dump"
	MOUNTEXPORT="$EXPORTS/mount.export.dump"

	"$KDB" export spec dump > "$SPECEXPORT"
	exit_if_fail "Could not export spec config"

	"$KDB" export dir dump > "$DIREXPORT"
	exit_if_fail "Could not export dir config"

	"$KDB" export user dump > "$USEREXPORT"
	exit_if_fail "Could not export user config"

	"$KDB" export system --without-elektra dump > "$SYSTEMEXPORT"
	exit_if_fail "Could not export system config"

	"$KDB" export system/elektra/mountpoints dump > "$MOUNTEXPORT"
	exit_if_fail "Could not export mount config"
}

export_check()
{
	EXPORTS=$1
	TESTNAME=$2
	IMPORTCONFIG=$3

	SPECEXPORT="$EXPORTS/spec.export.dump"
	SPECCHECK="$EXPORTS/spec.check.dump"

	DIREXPORT="$EXPORTS/dir.export.dump"
	DIRCHECK="$EXPORTS/dir.check.dump"

	USEREXPORT="$EXPORTS/user.export.dump"
	USERCHECK="$EXPORTS/user.check.dump"

	SYSTEMEXPORT="$EXPORTS/system.export.dump"
	SYSTEMCHECK="$EXPORTS/system.check.dump"

	MOUNTEXPORT="$EXPORTS/mount.export.dump"
	MOUNTCHECK="$EXPORTS/mount.check.dump"

	"$KDB" export spec dump > "$SPECCHECK"
	exit_if_fail "Could not export spec config"

	"$KDB" export dir dump > "$DIRCHECK"
	exit_if_fail "Could not export dir config"

	"$KDB" export user dump > "$USERCHECK"
	exit_if_fail "Could not export user config"

	"$KDB" export system --without-elektra dump > "$SYSTEMCHECK"
	exit_if_fail "Could not export system config"

	"$KDB" export system/elektra/mountpoints dump > "$MOUNTCHECK"
	exit_if_fail "Could not export mount config"

	if [ "$IMPORTCONFIG" = 'true' ]; then
		"$KDB" import spec dump < "$SPECEXPORT"
		exit_if_fail "Could not import spec config"

		"$KDB" import dir dump < "$DIREXPORT"
		exit_if_fail "Could not import dir config"

		"$KDB" import user dump < "$USEREXPORT"
		exit_if_fail "Could not import user config"

		"$KDB" import system --without-elektra dump < "$SYSTEMEXPORT"
		exit_if_fail "Could not import system config"

		"$KDB" import system/elektra/mountpoints dump < "$MOUNTEXPORT"
		exit_if_fail "Could not import mount config"
	fi

	diff "$SPECEXPORT" "$SPECCHECK"
	if [ $? != "0" ]
	then
		check_failed "$EXPORTS" "$TESTNAME" spec
	fi

	diff "$DIREXPORT" "$DIRCHECK"
	if [ $? != "0" ]
	then
		check_failed "$EXPORTS" "$TESTNAME" dir
	fi

	diff "$USEREXPORT" "$USERCHECK"
	if [ $? != "0" ]
	then
		check_failed "$EXPORTS" "$TESTNAME" user
	fi

	diff "$SYSTEMEXPORT" "$SYSTEMCHECK"
	if [ $? != "0" ]
	then
		check_failed "$EXPORTS" "$TESTNAME" system
	fi

	diff "$MOUNTEXPORT" "$MOUNTCHECK"
	if [ $? != "0" ]
	then
		check_failed "$EXPORTS" "$TESTNAME" mount
	fi
}

















































































































































































































































































































































































































































































































































































































# empty lines up to 1000 so that line numbers in the resulting scripts are more useful
if [ -z "$KDB" ]; then KDB=kdb; fi

echo
echo ELEKTRA RACE TESTS
echo

check_version

#set -x

echo "Will skip the test, because it is sensible to ulimit settings and race might hang"
exit 0

RACE="$KDB race"
RACEKEYS=user/test/race/keys

if [ "x`"$KDB" ls $RACEKEYS | wc -l 2> /dev/null`" != "x0" ]
then
	echo "There are already keys in $RACEKEYS"
	exit 1
fi

if $RACE | grep "This program tests race condition in Elektra"
then
	echo "Doing race tests"
else
	echo "No $RACE tool installed"
	exit 0
fi

do_race_test()
{
	RES=`$RACE $*`
	succeed_if "$RACE $* did not run successfully with error $?"

	WHERE=user/test/race/keys

	KEYS=`"$KDB" ls "$WHERE"`
	succeed_if "could not run $KDB ls $WHERE successfully"

	WON=`echo "$RES" | grep won`
	SHOULD=`echo "$WON" | wc -l`
	IS=`echo "$KEYS" | wc -l`
	RUNNING=`ps aux | grep race | grep -v grep | grep -v check`
	OUTPUT="\nFOR $*\nwith KEYS: $KEYS\nWON: $WON\nIS: $IS and RUNNING: $RUNNING\n\n"

	echo "test $*: $SHOULD - $IS"

	[ "$SHOULD" -ge "$IS" ]
	succeed_if "The resolver has a race condition: $SHOULD is smaller than $IS! $OUTPUT"

	# currently multiple winners are possible as the test seems to
	# be flawed in multi-process setup
	#[ "$SHOULD" -le "1"  ]
	#succeed_if "race had not one or zero, but $SHOULD, winner(s)! $OUTPUT"

	[ "$IS" -eq "1" ]
	succeed_if "keyset had not one, but $IS, key(s)! $OUTPUT"

	"$KDB" rm -r $WHERE
	succeed_if "could not remove key! $OUTPUT"
}

do_race_test 13 1 13
do_race_test 1 13 13

do_race_test 20 1 20
do_race_test 1 20 20

do_race_test 1 200 200
do_race_test 200 1 200

do_race_test 1 333 333
do_race_test 333 1 333

do_race_test 1 500 500

do_race_test 10 20 200
do_race_test 20 10 200

do_race_test 20 20 400

end_script
