#!/bin/sh

# src/bin/crypto/test.sh
#
# Test driver for crypto.  Initializes a new database cluster and
# test that the data keys are properly encrypted/decrypted.
#
# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California

set -e

: ${MAKE=make}

# Guard against parallel make issues (see comments in pg_regress.c)
unset MAKEFLAGS
unset MAKELEVEL

RAND="$(openssl rand -hex 32)"

# Run a given "initdb" binary and overlay the regression testing
# authentication configuration.
standard_initdb() {
	# To increase coverage of non-standard segment size and group access
	# without increasing test runtime, run these tests with a custom setting.
	# Also, specify "-A trust" explicitly to suppress initdb's warning.
	"$1" -N --wal-segsize 1 -g -A trust -K 256 -c "echo $RAND"
	if [ -n "$TEMP_CONFIG" -a -r "$TEMP_CONFIG" ]
	then
		cat "$TEMP_CONFIG" >> "$PGDATA/postgresql.conf"
	fi
	../../test/regress/pg_regress --config-auth "$PGDATA"
}

# What flavor of host are we on?
# Treat MINGW* (msys1) and MSYS* (msys2) the same.
testhost=`uname -s | sed 's/^MSYS/MINGW/'`

# Establish how the server will listen for connections
case $testhost in
	MINGW*)
		LISTEN_ADDRESSES="localhost"
		PG_REGRESS_SOCKET_DIR=""
		PGHOST=localhost
		;;
	*)
		LISTEN_ADDRESSES=""
		# Select a socket directory.  The algorithm is from the "configure"
		# script; the outcome mimics pg_regress.c:make_temp_sockdir().
		if [ x"$PG_REGRESS_SOCKET_DIR" = x ]; then
			set +e
			dir=`(umask 077 &&
				  mktemp -d /tmp/crypto_check-XXXXXX) 2>/dev/null`
			if [ ! -d "$dir" ]; then
				dir=/tmp/crypto_check-$$-$RANDOM
				(umask 077 && mkdir "$dir")
				if [ ! -d "$dir" ]; then
					echo "could not create socket temporary directory in \"/tmp\""
					exit 1
				fi
			fi
			set -e
			PG_REGRESS_SOCKET_DIR=$dir
			trap 'rm -rf "$PG_REGRESS_SOCKET_DIR"' 0
			trap 'exit 3' 1 2 13 15
		fi
		PGHOST=$PG_REGRESS_SOCKET_DIR
		;;
esac

POSTMASTER_OPTS="-F -c listen_addresses=\"$LISTEN_ADDRESSES\" -k \"$PG_REGRESS_SOCKET_DIR\""
export PGHOST

# don't rely on $PWD here, as old shells don't set it
temp_root=`pwd`/tmp_check
rm -rf "$temp_root"
mkdir "$temp_root"

src=`cd ../../.. && pwd`

# While in normal cases this will already be set up, adding bindir to
# path allows test.sh to be invoked with different versions as
# described in ./TESTING
PATH=$bindir:$PATH
export PATH

BASE_PGDATA="$temp_root/data"
PGDATA="${BASE_PGDATA}"
export PGDATA

logdir=`pwd`/log
rm -rf "$logdir"
mkdir "$logdir"

# Clear out any environment vars that might cause libpq to connect to
# the wrong postmaster (cf pg_regress.c)
#
# Some shells, such as NetBSD's, return non-zero from unset if the variable
# is already unset. Since we are operating under 'set -e', this causes the
# script to fail. To guard against this, set them all to an empty string first.
PGDATABASE="";        unset PGDATABASE
PGUSER="";            unset PGUSER
PGSERVICE="";         unset PGSERVICE
PGSSLMODE="";         unset PGSSLMODE
PGREQUIRESSL="";      unset PGREQUIRESSL
PGCONNECT_TIMEOUT=""; unset PGCONNECT_TIMEOUT
PGHOSTADDR="";        unset PGHOSTADDR

# Select a non-conflicting port number, similarly to pg_regress.c
PG_VERSION_NUM=`grep '#define PG_VERSION_NUM' "$src"/src/include/pg_config.h | awk '{print $3}'`
PGPORT=`expr $PG_VERSION_NUM % 16384 + 49152`
export PGPORT

i=0
while psql -X postgres </dev/null 2>/dev/null
do
	i=`expr $i + 1`
	if [ $i -eq 16 ]
	then
		echo port $PGPORT apparently in use
		exit 1
	fi
	PGPORT=`expr $PGPORT + 1`
	export PGPORT
done

# initdb CFE DEBUG goes to stderr/2
standard_initdb "$bindir"/initdb 2> "$logdir/initdb.log"
"$bindir"/pg_ctl start -l "$logdir/postmaster.log" -o "$POSTMASTER_OPTS" -w
"$bindir"/pg_ctl stop -w

# initdb outputs "generated" and "decrypted" lines, so make them all
# "generated" and merge duplicates
grep 'CFE DEBUG:' "$logdir/initdb.log" | sed 's/generated/decrypted/' | sort | uniq > "$temp_root"/initdb.log
if [ ! -s "$temp_root"/initdb.log ]
then	echo "File $temp_root/initdb.log is empty"
	exit 1
fi

# server log
grep 'CFE DEBUG:' "$logdir/postmaster.log" | sort > "$temp_root"/postmaster.log
if [ ! -s "$temp_root"/postmaster.log ]
then	echo "File $temp_root/postmaster.log is empty"
	exit 1
fi

if diff "$temp_root"/initdb.log "$temp_root"/postmaster.log >/dev/null; then
	echo PASSED
	exit 0
else
	echo "Files $temp_root/initdb.log and $temp_root/postmaster.log differ"
	echo "keys were not identical"
	diff "$temp_root"/initdb.log "$temp_root"/postmaster.log
	exit 1
fi
