On Sat, 27 Oct 2007, Francois Gouget wrote:
[...]
> There are other options to specify which version of winetest.exe to
> grab, to set the timeout on the tests execution, etc.
>
> Things still on the todo list:
> * the script also grabs the winetest.exe signature and attempts to
> verify it. But I don't know where to find the corresponding public key
> (651FD487) so I don't know if this really works.
Hmm, as pointed out by Detlef, there a link on Paul's home page pointing
to his public key and the required key is in there. Then it's just a
matter of telling gpg to use it which I have now done and the signature
checking code seems to work as intended.
> * the script gets the 'latest' winetest.exe version by default, but
> when there are compilation problems I guess this may stay stuck at the
> same revision for some time. So it would be nice if the script could
> know which version it's getting so it could skip the tests if that
> version is too old, or has already been tested.
The script can now use a local cache containing the already downloaded
files, and can be told to skip the tests if it finds that a file has not
changed since the last time it has been used in a given vm+snapshot
combination.
In fact I've been able to verify that it works in real life since
winetest has not been updated since last monday :-(
Compilation problems?
I've attached the latest version of the script.
--
Francois Gouget <[EMAIL PROTECTED]> http://fgouget.free.fr/
Hiroshima '45 - Czernobyl '86 - Windows '95
#!/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