#!/bin/sh # Copyright (C) 2007 Francois Gouget # # 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.1 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 library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA name0=`basename "$0"` verbose="" base_url="http://www.astro.gla.ac.uk/users/paulm/WRT/CrossBuilt" vmware="/usr/local/opt/vmware/bin" if [ -z "$DISPLAY" ] then DISPLAY=":0.0" export DISPLAY fi verbose() { if [ -n "$verbose" ] then echo "$@" fi } vm_is_busy() { vm="$1" test -f "$vm.WRITELOCK" return $? } vm_is_running() { # For VM matching purposes, only keep the last two elements of the path # to avoid trouble with symbolic links vm_match=`dirname "$opt_vm"` vm_match=`basename "$vm_match"`/`basename "$opt_vm"` vm_match=`echo "$vm_match" | sed -e 's/\([^a-zA-Z0-9_ /]\)/[\1]/g'` "$vmware/vmrun" list | egrep "$vm_match" >/dev/null return $? } cached_wget() { url="$1" dst="$2" cache="$3" if [ -n "$cache" ] then filename=`basename "$url"` ( cd "$cache" && wget -N "$url" && cp -pr "$filename" "$dst" ) else wget -O "$dst" "$url" fi } ### Main opt_vm="" opt_tag_prefix="" opt_tag="" opt_cache="" opt_version="" opt_check_sig="" opt_submit="" opt_timeout="" opt_autorun="" opt_snapshot="" opt_cddevice="" opt_usage="" while [ $# -gt 0 ] do arg="$1" shift case "$arg" in --tag-prefix) if [ -n "$opt_tag_prefix" ] then echo "$name0:error: --tag-prefix can only be used once" >&2 opt_usage="2" break elif [ $# -eq 0 ] then echo "$name0:error: missing argument for the --tag-prefix option" >&2 opt_usage="2" break else opt_tag_prefix="$1" shift fi ;; --tag) if [ -n "$opt_tag" ] then echo "$name0:error: --tag can only be used once" >&2 opt_usage="2" break elif [ $# -eq 0 ] then echo "$name0:error: missing argument for the --tag option" >&2 opt_usage="2" break else opt_tag="$1" shift fi ;; --cache) if [ -n "$opt_cache" ] then echo "$name0:error: --cache can only be used once" >&2 opt_usage="2" break elif [ $# -eq 0 ] then echo "$name0:error: missing argument for the --cache option" >&2 opt_usage="2" break else opt_cache="$1" shift fi ;; --skip-old) opt_skip_old="1" ;; --no-skip-old) opt_skip_old="0" ;; --version) if [ -n "$opt_version" ] then echo "$name0:error: --version can only be used once" >&2 opt_usage="2" break elif [ $# -eq 0 ] then echo "$name0:error: missing argument for the --version option" >&2 opt_usage="2" break else opt_version="$1" shift fi ;; --check-sig) opt_check_sig="1" ;; --no-check-sig) opt_check_sig="0" ;; --submit) opt_submit="1" ;; --no-submit) opt_submit="0" ;; --timeout) if [ -n "$opt_timeout" ] then echo "$name0:error: --timeout can only be used once" >&2 opt_usage="2" break elif [ $# -eq 0 ] then echo "$name0:error: missing argument for the --timeout option" >&2 opt_usage="2" break elif echo "$1" | egrep '^[0-9][0-9]*$' >/dev/null then opt_timeout="$1" shift else echo "$name0:error: the timeout value must be a decimal number" >&2 opt_usage="2" break fi ;; --autorun) opt_autorun="1" ;; --no-autorun) opt_autorun="0" ;; --snapshot) if [ -n "$opt_snapshot" ] then echo "$name0:error: --snapshot can only be used once" >&2 opt_usage="2" break elif [ $# -eq 0 ] then echo "$name0:error: missing argument for the --snapshot option" >&2 opt_usage="2" break else opt_snapshot="$1" shift fi ;; --cddevice) if [ -n "$opt_cddevice" ] then echo "$name0:error: --cddevice can only be used once" >&2 opt_usage="2" break elif [ $# -eq 0 ] then echo "$name0:error: missing argument for the --cddevice option" >&2 opt_usage="2" break else opt_cddevice="$1" shift fi ;; --verbose) verbose="1" ;; --help|-help|-h|-?) opt_usage="0" break ;; *) if [ -z "$opt_vm" ] then opt_vm="$arg" else echo "$name0:error: unknown option '$arg'" >&2 opt_usage="2" break fi esac done if [ -z "$opt_usage" ] then if [ -n "$opt_tag_prefix" -a -n "$opt_tag" ] then echo "$name0:error: --tag-prefix and --tag are incompatible" >&2 opt_usage="2" elif [ -z "$opt_tag_prefix" ] then opt_tag_prefix="vmware" fi if [ -z "$opt_vm" ] then echo "$name0:error: you must specify a VM path" >&2 opt_usage="2" elif [ -z "$opt_tag" ] then opt_tag="$opt_tag_prefix-"`basename "$opt_vm" | sed -e 's/\.[cv][fm][gx]$//' -e 's/ //g'` fi [ -n "$opt_skip_old" ] || opt_skip_old="0" if [ -n "$opt_cache" -a ! -d "$opt_cache" ] then echo "$name0:error: --cache must point to a directory" >&2 opt_usage="2" elif [ -z "$opt_cache" -a "$opt_skip_old" != "0" ] then echo "$name0:error: --skip-old can only be used with --cache" >&2 opt_usage="2" fi [ -n "$opt_version" ] || opt_version="latest" if [ -z "$opt_snapshot" ] then opt_snapshot="winetest" fi [ -n "$opt_autorun" ] || opt_autorun="1" if [ "$opt_autorun" = "0" -a -n "$opt_submit" ] then echo "$name0:error: --(no-)submit can only be used with the --autorun option" >&2 opt_usage="2" fi [ -n "$opt_submit" ] || opt_submit="1" if [ "$opt_submit" = "0" -a -z "$opt_timeout" ] then opt_timeout="0" fi if [ "$opt_submit" = "0" -a "$opt_skip_old" != "0" ] then echo "$name0:error: --no-submit and --skip-old are incompatible" >&2 opt_usage="2" fi [ -n "$opt_timeout" ] || opt_timeout="30" [ -n "$opt_cddevice" ] || opt_cddevice="ide1:0" fi if [ -n "$opt_usage" ] then if [ "$opt_usage" != "0" ] then echo "$name0:error: try '$name0 --help' for more information" >&2 exit $opt_usage fi echo "Usage: $name0 [--version VERSION] [--cache DIR [--skip-old]] [--check-sig]" echo " [--tag-prefix PREFIX] [--tag TAG] [--submit|--no-submit]" echo " [--autorun|--no-autorun] [--cddevice DEVICE]" echo " [--timeout TIMEOUT] [--snapshot SNAPSHOT] /path/to/vm.vmx" echo " [--verbose] [--help]" echo echo "Downloads the latest winetest.exe, and runs it in a VMware virtual machine by" echo "putting it on a virtual CD. The state of the virtual machine is left" echo "undisturbed." echo echo "Options:" echo " --version VERSION Specifies which version of winetest.exe to download." echo " By default this is 'latest'." echo " --cache DIR Specifies where to cache the downloaded binaries. This" echo " is useful when running a test multiple times in" echo " different virtual machines." echo " --skip-old Exit without running the test if the test has not" echo " changed and has already been run in this virtual" echo " machine+snapshot combination." echo " --check-sig Specifies that winetest.exe should not be run if its" echo " signature cannot be checked. By default, the tests are" echo " only aborted if winetest.exe does not match its" echo " signature. If --no-check-sig is used, then the" echo " signature is not checked at all'." echo " --tag-prefix PREFIX Specifies what to prefix to the virtual machine name" echo " with when building the default tag. By default this is" echo " 'vmware'." echo " --tag TAG The tag to use when submitting the results. By default" echo " this is the tag prefix, followed by a dash and the" echo " basename of the virtual machine file." echo " --timeout TIMEOUT Specifies how long, in minutes, to give to winetest.exe" echo " to run. By default this is 30 minutes." echo " --submit Submit the test results to http://test.winehq.org/data/" echo " This is the default. Use --no-submit to not submit the" echo " results, and remove the 30 minutes timeout." echo " --autorun Generate an autorun.inf file so the tests are started" echo " automatically. This is the default. If you use" echo " --no-autorun, then you will need to make your own" echo " arrangements to start the tests from the CD." echo " --cddevice DEVICE The name of the virtual machine's device for the cdrom" echo " drive. By default this is 'ide1:0'." echo " --snapshot SNAPSHOT The snapshot to use to run the tests. By default this" echo " is 'winetest'. Make sure that, in this snapshot, the" echo " cdrom device is connected. If you use the --autorun" echo " option, then autorun should also be enabled." echo " /path/to/vm.vmx This is the path to the virtual machine's vmx or cfg" echo " file." echo " --verbose Print some extra informational messages." echo " --help Show this help message." exit 0 fi ### Check that the VM is usable verbose "Checking the VM..." if vm_is_busy "$opt_vm" then echo "$name0:error: '$opt_vm' is already opened or running." >&2 if [ $opt_timeout -eq 0 ] then echo "$name0:error: Aborting." >&2 exit 1 fi count=`expr $opt_timeout + 2` while vm_is_busy "$opt_vm" do if [ $count -eq 0 ] then echo "$name0:error: '$opt_vm' is still in use. Giving up." >&2 exit 1 fi count=`expr $count - 1` sleep 60 done fi "$vmware/vmrun" listSnapshots "$opt_vm" | egrep "^$opt_snapshot\$" >/dev/null if [ $? -ne 0 ] then echo "$name0:error: the '$opt_snapshot' snapshot does not exist. Aborting" >&2 exit 1 fi ### Grab winetest and prepare the ISO verbose "Downloading winetest.exe..." [ -n "$TMPDIR" ] || TMPDIR="/tmp" tmpdir="$TMPDIR/$name0-$$" if ! mkdir -p "$tmpdir/master" then echo "$name0:error: unable to create the '$tmpdir/master' directory" >&2 exit 1 fi logfile="$tmpdir/$name0.log" cached_wget "$base_url/winetest-$opt_version.exe" "$tmpdir/master/winetest.exe" "$opt_cache" >"$logfile" 2>&1 if [ $? -ne 0 ] then echo "$name0:error: unable to download winetest.exe" >&2 echo cat "$logfile" exit 1 fi if [ -n "$opt_cache" ] then run="$vm $opt_snapshot" runfile="$opt_cache/winetest-$opt_version.exe.runs" egrep "^Server file no newer than local file" "$logfile" >/dev/null if [ $? -ne 0 ] then rm -f "$runfile" fi if [ "$opt_skip_old" = "1" ] && egrep "^$run\$" "$runfile" >/dev/null 2>&1 then verbose "The test has already been run in $run." exit 0 fi fi cached_wget "$base_url/winetest-$opt_version.exe.sig" "$tmpdir/master/winetest.exe.sig" "$opt_cache" >"$logfile" 2>&1 if [ $? -ne 0 -a "$opt_check_sig" != "0" ] then echo "$name0:error: unable to download winetest.exe.sig" >&2 echo cat "$logfile" exit 1 fi ### Check the winetest.exe signature if [ "$opt_check_sig" != "0" ] then verbose "Checking the winetest.exe signature..." type gpg >/dev/null 2>&1 if [ $? -eq 0 ] then gpg --verify "$tmpdir/master/winetest.exe.sig" rc=$? if [ $rc -eq 0 ] then echo "Signature checked." elif [ $rc -eq 1 ] then echo "$name0:error: it looks like winetest.exe has been tampered with. Aborting" >&2 exit 1 elif [ "$opt_check_sig" = "1" ] then echo "$name0:warning: your system does not seem to be set up to check the signature. Aborting." >&2 exit 1 else echo "$name0:warning: your system does not seem to be set up to check the signature. Continuing anyway..." >&2 fi elif [ "$opt_check_sig" = "1" ] then echo "$name0:error: gpg is not installed. Aborting." >&2 exit 1 else echo "$name0:warning: unable to check the winetest.exe signature because gpg is not installed. Continuing anyway..." >&2 fi fi ### Create the CD image verbose "Creating the CD image..." if [ "$opt_autorun" = "1" ] then options="" if [ "$opt_submit" = "0" ] then options="-o c:\\winetest.log" fi cat >"$tmpdir/master/autorun.inf" <<_EOF_ [autorun] open=winetest.exe -q -t $opt_tag $options _EOF_ fi mkisofs -o "$tmpdir/winetest.iso" "$tmpdir/master" >"$logfile" 2>&1 if [ $? -ne 0 ] then echo "$name0:error: unable to create the CD image" >&2 echo cat "$logfile" exit 1 fi ### Prepare the VM tmp_snapshot="$name0-`date +%Y%m%d`" "$vmware/vmrun" listSnapshots "$opt_vm" | egrep "^$tmp_snapshot\$" >/dev/null if [ $? -eq 0 ] then # This is not our snapshot so don't delete it after we're done delete_snapshot=0 else "$vmware/vmrun" snapshot "$opt_vm" "$tmp_snapshot" if [ $? -ne 0 ] then echo "$name0:error: an error occurred while saving the VM's current state" >&2 exit 1 fi delete_snapshot=1 fi "$vmware/vmrun" revertToSnapshot "$opt_vm" "$opt_snapshot" if [ $? -ne 0 ] then echo "$name0:error: an error occurred while switching to the '$opt_snapshot' snapshot" >&2 exit 1 fi ### Run the test verbose "Running the tests..." "$vmware/vmware" -s "$opt_cddevice.fileName=$tmpdir/winetest.iso" \ -s "$opt_cddevice.deviceType=cdrom-image" \ -x -q "$opt_vm" & count=0 while [ $opt_timeout -eq 0 -o $count -lt $opt_timeout ] do sleep 60 if vm_is_running "$opt_vm" then count=`expr $count + 1` else break fi done if [ $opt_timeout -ne 0 -a $count -gt $opt_timeout ] then "$vmware/vmrun" stop "$opt_vm" fi if [ "$opt_skip_old" = "1" ] then echo "$run" >>"$runfile" fi ### Restore the VM and cleanup verbose "Cleaning up..." "$vmware/vmrun" revertToSnapshot "$opt_vm" "$tmp_snapshot" if [ $? -ne 0 ] then echo "$name0:error: an error occurred while restoring the VM's to its initial state ($tmp_snapshot)" >&2 exit 1 fi if [ $delete_snapshot -ne 0 ] then "$vmware/vmrun" deleteSnapshot "$opt_vm" "$tmp_snapshot" fi rm -rf "$tmpdir" exit 0