#!/bin/bash
#	This file is deprecated and only used by the old build.steps=test
#	The new multiplatform way to run tests is with   build.steps=testLocal

buildcfg=""
testingDir=$(cd $PWD; pwd); # N200901011234/testing/N200901011234/testing/
buildDir=$(cd $PWD; cd ../../../; pwd)

#this value must be set when using rsh to execute this script, otherwise the script will execute from the user's home directory
cd $testingDir

if [[ -f $buildDir/build.cfg ]]; then
	echo "[runtests] Using $buildDir/build.cfg" 
	buildcfg=$buildDir/build.cfg
elif [[ -f $testingDir/build.cfg ]]; then
	echo "[runtests] Using $testingDir/build.cfg" 
	buildcfg=$testingDir/build.cfg
fi
if [[ ! -f $buildcfg ]]; then
	echo "[runtests] ERROR: $buildcfg does not exist."  
	exit 1;
fi
if [[ ! $buildcfg ]]; then
	echo "[runtests] ERROR: Cannot find build.cfg"  
	exit 1;
fi
 
echo "[runtests] $0 started on: `date +%H\:%M\:%S`";

# environment variables
PATH=.:/bin:/usr/bin:/usr/bin/X11:/usr/local/bin:/usr/X11R6/bin:`pwd`/../linux;export PATH

export USERNAME=`whoami`
echo "[runtests] Run as $USERNAME";
echo "[runtests] With PATH = $PATH";
echo "[runtests] In dir $testingDir";

# fix for org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]
# fix for Failed to invoke suite():org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]
export CVS_RSH=ssh
#ulimit -c unlimited; # set corefile size to unlimited; not allowed on build.eclipse

echo "[runtests] Set JAVA_HIGH_ZIPFDS=500 & LANG=C";
export JAVA_HIGH_ZIPFDS=500
export LANG=C

# configure X server thread for tests; see http://wiki.eclipse.org/Modeling_Project_Releng/Building_Zips_And_Jars#UI_Testing

usedPorts=""; maxPort=40
for port in $(ps aux | egrep '[Xvnc|Xvfb]\ :' | egrep " :[0-9]+" | sed "s/\(\^\|.\+\)\(Xvfb\|Xvnc\) :\([0-9]\+\)\(.\+\|$\)/\3/g" | sort); do
        if [[ $(echo $port | egrep "^:[0-9]+$") ]]; then
                usedPorts=$usedPorts" "${port:1};
                thisPort=${port:1}; (( thisPort -= 0 ));
                if [[ $maxPort -lt $thisPort ]]; then maxPort=$thisPort; fi
                #echo "[$usedPorts], $thisPort, $maxPort"
        fi
done
(( xport = maxPort + 1 ));
echo "Existing DISPLAY ports include: $usedPorts."
echo "Use DISPLAY port :$xport"

xCmd=""
xvncExists=$(which Xvnc); xvncExists=${xvncExists##*no Xvnc *}
if [ $xvncExists ]; then 
	xCmd="Xvnc :${xport} -geometry 1024x768 -depth 24 -ac"
else
	xvfbExists=$(which Xvfb); xvfbExists=${xvfbExists##*no Xvfb *}
		if [ $xvfbExists ]; then
  			xCmd="Xvfb :${xport} -screen 0 1024x768x24 -ac"
	else
		echo "[runtests] WARNING! This script requires Xvfb or Xvnc. "
		echo "[runtests] Without some way to run tests in a different display port, UI tests will run in front of you and you may accidentally interact with them."
	fi
fi

if [[ $xCmd ]]; then 
	echo "[runtests] Using X server: '${xCmd}'"
	${xCmd} &
	export DISPLAY=localhost:${xport}.0
	xhost +
else
	echo "[runtests] Warning! UI tests will run in the current UI display port (usually :0). Please avoid accidentally interacting with them."
fi	

relengCommonScriptsDir=$(grep relengCommonScriptsDir $buildcfg | egrep -v "^#" | head -1 | sed -e "s/relengCommonScriptsDir=//")
writableBuildRoot=$($relengCommonScriptsDir/readProperty.sh $buildcfg writableBuildRoot)
downloadsDir=$($relengCommonScriptsDir/readProperty.sh $buildcfg downloadsDir writableBuildRoot=$writableBuildRoot)
relengBaseBuilderDir=$($relengCommonScriptsDir/readProperty.sh $buildcfg relengBaseBuilderDir)
relengBuilderDir=$($relengCommonScriptsDir/readProperty.sh $buildcfg relengBuilderDir)
relengCommonBuilderDir=$($relengCommonScriptsDir/readProperty.sh $buildcfg relengCommonBuilderDir)

# TODO: should we use a default? or only pull from build.cfg?
#if [[ ! $JAVA_HOME ]]; then
	echo -n "[runtests] Get JAVA_HOME from build.cfg ... "
	JAVA14_HOME=$($relengCommonScriptsDir/readProperty.sh $buildcfg JAVA14_HOME)
	JAVA50_HOME=$($relengCommonScriptsDir/readProperty.sh $buildcfg JAVA50_HOME)
	JAVA60_HOME=$($relengCommonScriptsDir/readProperty.sh $buildcfg JAVA60_HOME)
	JAVA_HOME=$($relengCommonScriptsDir/readProperty.sh $buildcfg JAVA_HOME JAVA14_HOME=$JAVA14_HOME JAVA50_HOME=$JAVA50_HOME JAVA60_HOME=$JAVA60_HOME)
	echo $JAVA_HOME
	echo ""
	$JAVA_HOME/bin/java -version
	echo ""
#fi

Xflags="";
Dflags="";
vmargs=""

# default target to run in org.eclipse.$subprojectName.releng/builder/tests/test.xml
antTestTarget=all

# process command line arguments
while [ $# -gt 0 ]
do
	case "$1" in
		-vmExecutable) vmExecutable="$2"; shift;;
		-consolelog)   consolelog="$2";   shift;;
		-X*) Xflags=$Xflags\ $1;;
		-D*) Dflags=$Dflags\ $1;;
		-vmargs)
			while [ $# -gt 0 ]; do
				vmargs="$vmargs "$1
				shift
			done;; 
	esac
	shift
done

############################# BEGIN RUN TESTS #############################

# operating system, windowing system and architecture variables
# for *nix systems, os, ws and arch values must be specified
os=linux
ws=gtk
arch=x86

if [[ $(uname -p 2>/dev/null) ]]; then
	arch=`uname -p`
else
	arch=`uname -m`
fi

# Massage arch for uname differences
case $arch in
	powerpc|'Power Macintosh')
		os=macosx; ws=carbon; arch=ppc;;
	i[0-9]*86)
		arch=x86;;
	ia64)
		arch=ia64;;
	ppc)
		arch=ppc;;
	ppc64)
		arch=ppc;;
	x86_64)
		arch=x86_64;;
	*)
		arch=x86; echo >&2 "[runtests] Unknown architecture:  $(uname -pm); assume arch=$arch";;
esac

Dflags=$Dflags" "-Dplatform=${os}.${ws}

# default value to determine if eclipse should be reinstalled between running of tests
installmode="clean"

workspaceDir="$testingDir/eclipse/workspace"

# Replace the boot eclipse (The eclipse used to run the main test.xml, this will start another eclipse later)
if [ -d $testingDir/eclipse ] ; then
	rm -rf $testingDir/eclipse
fi

echo "[runtests] Currently in `pwd`:"

function noDefinedEclipseBaseMessage ()
{
		echo "Error!:" 
		echo "Tests cannot continue without a defined Eclipse base."
		echo "----------"
		echo "You must specify either"
		echo "	dependencyURLs=http://download.eclipse.org/eclipse/downloads/drops/R-3.5-200906111540/eclipse-SDK-3.5-linux-gtk.tar.gz"
		echo "	(or equivalent platform, RCP, etc.)"
		echo "or"
		echo "	repositoryURLs=http://download.eclipse.org/eclipse/updates/3.5.x/"
		echo "	featureIDsToInstall=org.eclipse.sdk"
		echo "	(or equivalent update site repos + features/plugins to install);" 
	 	echo "   use featureIDsToInstall, pluginIDsToInstall and/or IUsToInstall)"
		exit 1;
}	

eclipseBaseFile=$($relengCommonScriptsDir/readProperty.sh $buildcfg eclipse.base.file)
if [[ $eclipseBaseFile ]]; then
	echo "[runtests] Eclipse Base is $downloadsDir/$eclipseBaseFile"
	eclipseBase=$downloadsDir/$eclipseBaseFile
	if   [[ ! ${eclipseBase##*.zip} ]];    then # zip
		unzip -qq -o $eclipseBase -d $testingDir
	elif [[ ! ${eclipseBase##*.tar.gz} ]]; then # tar.gz
		tar -xzf $eclipseBase -C $testingDir
	elif [[ ! ${eclipseBase##*.tar.Z} ]];  then # tar.Z
		tar -xZf $eclipseBase -C $testingDir
	else
		echo "[runtests] ERROR: Eclipse Base $eclipseBaseFile is an UNKNOWN file type. Failure.";
		exit 1;
	fi
else
	# if no eclipseBaseFile, try to provision using repositoryURLs and either featureIDsToInstall or pluginIDsToInstall
	repositoryURLs=$($relengCommonScriptsDir/readProperty.sh $buildcfg repositoryURLs) 
	featureIDsToInstall=$($relengCommonScriptsDir/readProperty.sh $buildcfg featureIDsToInstall) 
	pluginIDsToInstall=$($relengCommonScriptsDir/readProperty.sh $buildcfg pluginIDsToInstall)
	IUsToInstall=$($relengCommonScriptsDir/readProperty.sh $buildcfg IUsToInstall)
	if [[ ! $repositoryURLs ]]; then
		noDefinedEclipseBaseMessage;
	elif [[ ! $featureIDsToInstall ]] && [[ ! $pluginIDsToInstall ]] && [[ ! $IUsToInstall ]]; then 
		noDefinedEclipseBaseMessage;
	fi
fi

J2SE15flags="";
J2SE16flags="";
# TODO: if a 1.5 JDK and want source/target = 1.5, leave these in
# TODO: if source/target = 1.4, remove these!
if [ ${JAVA_HOME##*1.5*}"" = "" -o ${JAVA_HOME##*15*}"" = "" -o ${JAVA_HOME##*5.0*}"" = "" -o ${JAVA_HOME##*50*}"" = "" ]; then
	# set J2SE-1.5 properties (-Dflags)
	bootclasspath="."; for f in $(find ${JAVA_HOME}/jre/lib ${JAVA_HOME}/lib ${JAVA_HOME}/../Classes -name "*.jar" 2>/dev/null); do bootclasspath=$bootclasspath":"$f; done # echo $bootclasspath
	J2SE15flags=$J2SE15flags" -DJ2SE-1.5=$bootclasspath"
	J2SE15flags=$J2SE15flags" -DbundleBootClasspath=$bootclasspath"
	J2SE15flags=$J2SE15flags" -DjavacSource=1.5"
	J2SE15flags=$J2SE15flags" -DjavacTarget=1.5"
	J2SE15flags=$J2SE15flags" -DbundleJavacSource=1.5"
	J2SE15flags=$J2SE15flags" -DbundleJavacTarget=1.5"
fi
if [ ${JAVA_HOME##*1.6*}"" = "" -o ${JAVA_HOME##*16*}"" = "" -o ${JAVA_HOME##*6.0*}"" = "" -o ${JAVA_HOME##*60*}"" = "" ]; then
	# set J2SE-1.6 properties (-Dflags)
	bootclasspath="."; for f in $(find ${JAVA_HOME}/jre/lib ${JAVA_HOME}/lib ${JAVA_HOME}/../Classes -name "*.jar" 2>/dev/null); do bootclasspath=$bootclasspath":"$f; done # echo $bootclasspath
	J2SE16flags=$J2SE16flags" -DJ2SE-1.6=$bootclasspath"
	J2SE16flags=$J2SE16flags" -DbundleBootClasspath=$bootclasspath"
	J2SE16flags=$J2SE16flags" -DjavacSource=1.6"
	J2SE16flags=$J2SE16flags" -DjavacTarget=1.6"
	J2SE16flags=$J2SE16flags" -DbundleJavacSource=1.6"
	J2SE16flags=$J2SE16flags" -DbundleJavacTarget=1.6"
fi

# different ways to get the launcher and Main class
if [[ -f $testingDir/eclipse/startup.jar ]]; then
  cpAndMain="eclipse/startup.jar org.eclipse.core.launcher.Main"; # up to M4_33
elif [[ -f $testingDir/eclipse/plugins/org.eclipse.equinox.launcher.jar ]]; then
  cpAndMain="$testingDir/eclipse/plugins/org.eclipse.equinox.launcher.jar org.eclipse.equinox.launcher.Main"; # M5_33
else
  cpAndMain=`find $testingDir/eclipse/ -name "org.eclipse.equinox.launcher_*.jar" | sort | head -1`" org.eclipse.equinox.launcher.Main"
fi

# fallback to basebuilder if no launcher jar found (support platform provisioning from repos, not SDK zips)
if [[ ${cpAndMain/.jar/} == ${cpAndMain} ]]; then
	if [[ -f $relengBaseBuilderDir/plugins/org.eclipse.equinox.launcher.jar ]]; then
	  cpAndMain="$relengBaseBuilderDir/plugins/org.eclipse.equinox.launcher.jar org.eclipse.equinox.launcher.Main"
	fi
fi

# fail if not found
if [[ ${cpAndMain/.jar/} == ${cpAndMain} ]]; then
	echo "Error!"
	echo "Tests cannot continue without a valid Eclipse launcher jar!"
	exit 1;
fi

vmargsCmd=""; 
if [[ $vmargs ]]; then 
	vmargsCmd="-vmargs $vmargs"
	if [[ $Xflags ]]; then
		vmargsCmd="$vmargsCmd $Xflags"
	fi
elif [[ $Xflags ]]; then
	vmargsCmd="-vmargs $Xflags"
fi

# copy org.eclipse.build.tools plugin into dropins so that releng.basebuilder ant tasks 
# (eg., in buildTools.jar!org.eclipse.releng.UnpackUpdateJars :: unpackUpdateJars) can be resolved
mkdir -p $testingDir/eclipse/dropins/eclipse/plugins/
cp -r ${relengBaseBuilderDir}/plugins/org.eclipse.build.tools $testingDir/eclipse/dropins/eclipse/plugins/

# run tests
echo "[runtests] [`date +%H\:%M\:%S`] Launching Eclipse (installmode = $installmode with -enableassertions turned on) ..."
$relengCommonScriptsDir/executeCommand.sh "$JAVA_HOME/bin/java $Xflags -enableassertions -cp $cpAndMain -ws $ws -os $os -arch $arch \
  -application org.eclipse.ant.core.antRunner -data $workspaceDir -f ${relengCommonBuilderDir}/builder/tests/test.xml $antTestTarget \
  $Dflags -Dws=$ws -Dos=$os -Darch=$arch -D$installmode=true -Dbuildcfg=${buildcfg} -DdownloadsDir=${downloadsDir} -DtestingDir=${testingDir} \
  -DrelengBaseBuilderDir=${relengBaseBuilderDir} -DrelengCommonBuilderDir=${relengCommonBuilderDir} -DrelengBuilderDir=${relengBuilderDir} \
  $J2SE15flags $J2SE16flags \
$properties -logger org.apache.tools.ant.DefaultLogger $vmargsCmd" 2>&1 | tee $consolelog # or, instead of teeing w/ "| tee", redirect w/ ">"
echo "[runtests] [`date +%H\:%M\:%S`] Eclipse test run completed. "

# xwd -silent -display :${xport} -root -out /tmp/snap.xwd; # save a snapshot

############################# END RUN TESTS #############################

# drop X server process threads used by tests
if [[ -r /tmp/.X${xport}-lock ]]; then kill `cat /tmp/.X${xport}-lock`; fi
if [[ -f /tmp/.X${xport}-lock ]]; then rm -fr /tmp/.X${xport}-lock; fi

if [[ ! -d $PWD/results ]]; then
	echo "[runtests] No test results found in $PWD/results!";
	#echo "[runtests] To debug what happened, run a debug build and set the -noclean flag true."
	echo "[runtests] Creating 'noclean' file to prevent cleanup after build completes."
	echo "1" > $PWD/../../../noclean;
else
# if the build failed for some reason, don't clean up!
xmls=`find $PWD/results/xml -name "*.xml"`;
testsPassed="maybe";
for xml in $xmls; do
	if [[ $testsPassed ]]; then
		testsPassed=$(cat $xml | grep "<testsuite " | grep " errors=\"0\"" | grep " failures=\"0\"");
		if [[ ! $testsPassed ]]; then
			echo "[runtests] Found test failure(s) in $xml: "
			echo "  "$(cat $xml | grep "<testsuite ");
			#echo "[runtests] To debug what happened, run a debug build and set the -noclean flag true."
			echo "[runtests] Creating 'noclean' file to prevent cleanup after build completes."
			echo "1" > $PWD/../../../noclean;
			break;
		fi
	fi
done
fi;

echo "[runtests] ${0##*/} done: `date +%H\:%M\:%S`"
