Commits

Kirill Simonov committed 32fa661

Added a build script generating VMs with various database servers.

  • Participants
  • Parent commits dc6f235

Comments (0)

Files changed (16)

 
 .PHONY: default build install develop doc dist windist pypi clean \
 	test train train-routine train-sqlite train-pgsql train-mysql \
-	purge-test lint create create-sqlite create-pgsql create-mysql \
-	drop drop-sqlite drop-pgsql drop-mysql demo-htraf demo-ssi
+	train-oracle train-mssql purge-test lint \
+	create-sqlite create-pgsql create-mysql create-oracle create-mssql \
+	drop-sqlite drop-pgsql drop-mysql drop-oracle drop-mssql \
+	build-all start-pgsql84 start-pgsql90 start-mysql51 start-oracle10g \
+	start-mssql2005 start-mssql2008 stop-pgsql84 stop-pgsql90 stop-mysql51 \
+	stop-oracle10 stop-mssql2005 stop-mssql2008 gdemo-htraf demo-ssi \
+	shell-sqlite shell-pgsql shell-mysql shell-oracle shell-mssql \
+	serve-sqlite serve-pgsql serve-mysql serve-oracle serve-mssql \
+	client-sqlite client-pgsql client-mysql client-oracle client-mssql
 
 
 # Load configuration variables from `Makefile.common`.  Do not edit
 	@echo "Run 'make <target>', where <target> is one of:"
 	@echo
 	@echo "  *** Building and Installation ***"
+	@echo "  update: to update the HTSQL source code"
 	@echo "  build: to build the HTSQL packages"
 	@echo "  install: to install the HTSQL packages"
 	@echo "  develop: to install the HTSQL packages in the development mode"
 	@echo "  *** Regression Testing ***"
 	@echo "  test: to run HTSQL regression tests"
 	@echo "  train: to run all HTSQL tests in the train mode"
-	@echo "  train-routine: to run tests for htsql-ctl tool in the train mode"
-	@echo "  train-sqlite: to run SQLite-specific tests in the train mode"
-	@echo "  train-pgsql: to run PostgreSQL-specific tests in the train mode"
-	@echo "  train-mysql: to run MySQL-specific tests in the train mode"
+	@echo "  train-<suite>: to run a specific test suite in the train mode"
+	@echo "    where <suite> is one of:"
+	@echo "      routine, sqlite, pgsql, mysql, oracle, mssql"
 	@echo "  purge-test: to purge stale test output data"
+	@echo "	 create-<db>: to install the test database for a specific database"
+	@echo "  drop-<db>: to delete the test database for a specific database"
+	@echo "    where <db> is one of:"
+	@echo "        sqlite, pgsql, mysql, oracle, mssql"
 	@echo "  lint: detect errors in the source code"
-	@echo "  create: to install the regression databases"
-	@echo "	 create-sqlite: to install the test database for SQLite"
-	@echo "  create-pgsql: to install the test database for PostgreSQL"
-	@echo "  create-mysql: to install the test database for MySQL"
-	@echo "  drop: to drop users and databases deployed by regression tests"
-	@echo "  drop-sqlite: to delete the test database for SQLite"
-	@echo "  drop-pgsql: to delete the test database for PostgreSQL"
-	@echo "  drop-mysql: to delete the test database for MySQL"
+	@echo
+	@echo "  *** Integration Testing ***"
+	@echo "  build-all: to build all test benches"
+	@echo "  start-<bench>: to start the specified test bench"
+	@echo "  stop-<bench>: to stop the specified test bench"
+	@echo "    where <bench> is one of:"
+	@echo "      pgsql84, pgsql90, mysql51, oracle10g, mssql2005, mssql2008"
 	@echo
 	@echo "  *** Shell and Server ***"
-	@echo "  shell-sqlite: to start an HTSQL shell on the SQLite test database"
-	@echo "  shell-pgsql: to start an HTSQL shell on the PostgreSQL test database"
-	@echo "  shell-mysql: to start an HTSQL shell on the MySQL test database"
-	@echo "  serve-sqlite: to start an HTTP server on the SQLite test database"
-	@echo "  serve-pgsql: to start an HTTP server on the PostgreSQL test database"
-	@echo "  serve-mysql: to start an HTTP server on the MySQL test database"
-	@echo "	 client-sqlite: to start a native SQLite shell on the test database"
-	@echo "  client-pgsql: to start a native PostgreSQL shell on the test database"
-	@echo "  client-mysql: to start a native MySQL shell on the test database"
+	@echo "  shell-<db>: to start the HTSQL shell on the specified test database"
+	@echo "  serve-<db>: to start an HTTP server on the specified test database"
+	@echo "  client-<db> to start the native client for the specified test database"
+	@echo "    where <db> is one of:"
+	@echo "      sqlite, pgsql, mysql, oracle, mssql"
 	@echo
 	@echo "  *** Demos and Examples ***"
 	@echo "  demo-htraf: to run the HTRAF demo"
 # Building and installation tasks.
 #
 
+# Update the HTSQL source code.
+update:
+	hg pull
+	hg update
+
 # Build the HTSQL packages.
 build:
 	${PYTHON} setup.py build
 # FIXME: include HTML documentation; `dist_dir` is broken for `--bdist-deb`.
 # Note that `bdist_deb` requires `stdeb` package.
 dist:
-	rm -rf build
+	rm -rf build/dist build/lib.* build/bdist.*
 	${PYTHON} setup.py sdist
 	${PYTHON} setup.py bdist_egg
 	#python setup.py --command-packages=stdeb.command bdist_deb 
 # Register and upload the package to PyPI.
 # FIXME: include HTML documentation.
 pypi:
-	rm -rf build
+	rm -rf build/dist build/lib.* build/bdist.*
 	${PYTHON} setup.py register sdist bdist_egg upload
 
 # Delete the build directory and object files.
 train-mysql:
 	${HTSQL_CTL} regress -i test/regress.yaml --train mysql
 
+# Run Oracle-specific regression tests in the train mode.
+train-oracle:
+	${HTSQL_CTL} regress -i test/regress.yaml --train oracle
+
+# Run MS SQL Server-specific regression tests in the train mode.
+train-mssql:
+	${HTSQL_CTL} regress -i test/regress.yaml --train mssql
+
 # Purge stale output records from HTSQL regression tests.
 purge-test:
 	${HTSQL_CTL} regress -i test/regress.yaml -q --train --purge
 lint:
 	${PYFLAKES} src/htsql src/htsql_pgsql src/htsql_sqlite
 
-# Install the regression databases.
-create:
-	${HTSQL_CTL} regress -i test/regress.yaml -q create-sqlite create-pgsql create-mysql
-
 # Install the regression database for SQLite.
 create-sqlite:
 	${HTSQL_CTL} regress -i test/regress.yaml -q create-sqlite
 create-mysql:
 	${HTSQL_CTL} regress -i test/regress.yaml -q create-mysql
 
-# Drop any users and databases deployed by the regression tests.
-drop:
-	${HTSQL_CTL} regress -i test/regress.yaml -q drop-sqlite drop-pgsql drop-mysql
+# Install the regression database for Oracle.
+create-oracle:
+	${HTSQL_CTL} regress -i test/regress.yaml -q create-oracle
+
+# Install the regression database for MS SQL Server.
+create-mssql:
+	${HTSQL_CTL} regress -i test/regress.yaml -q create-mssql
 
 # Drop the regression database for SQLite
 drop-sqlite:
 drop-pgsql:
 	${HTSQL_CTL} regress -i test/regress.yaml -q drop-pgsql
 
-# Drop the regression database for PostgreSQL.
+# Drop the regression database for MySQL.
 drop-mysql:
 	${HTSQL_CTL} regress -i test/regress.yaml -q drop-mysql
 
+# Drop the regression database for Oracle.
+drop-oracle:
+	${HTSQL_CTL} regress -i test/regress.yaml -q drop-oracle
+
+# Drop the regression database for MS SQL Server.
+drop-mssql:
+	${HTSQL_CTL} regress -i test/regress.yaml -q drop-mssql
+
 
 #
 # Shell and server tasks.
 shell-mysql:
 	${HTSQL_CTL} shell ${MYSQL_URI}
 
+# Start an HTSQL shell on the Oracle regression database.
+shell-oracle:
+	${HTSQL_CTL} shell ${ORACLE_URI}
+
+# Start an HTSQL shell on the MS SQL Server regression database.
+shell-mssql:
+	${HTSQL_CTL} shell ${MSSQL_URI}
+
 # Start an HTTP/HTSQL server on the SQLite regression database.
 serve-sqlite:
 	${HTSQL_CTL} serve ${SQLITE_URI} ${HTSQL_HOST} ${HTSQL_PORT}
 serve-mysql:
 	${HTSQL_CTL} serve ${MYSQL_URI} ${HTSQL_HOST} ${HTSQL_PORT}
 
+# Start an HTTP/HTSQL server on the Oracle regression database.
+serve-oracle:
+	${HTSQL_CTL} serve ${ORACLE_URI} ${HTSQL_HOST} ${HTSQL_PORT}
+
+# Start an HTTP/HTSQL server on the MS SQL Server regression database.
+serve-mssql:
+	${HTSQL_CTL} serve ${MSSQL_URI} ${HTSQL_HOST} ${HTSQL_PORT}
+
 # Start a native client on the SQLite regression database.
 client-sqlite:
 	${SQLITE_CLIENT}
 client-mysql:
 	${MYSQL_CLIENT}
 
+# Start a native client on the Oracle regression database.
+client-oracle:
+	${ORACLE_CLIENT}
+
+# Start a native client on the MS SQL Server regression database.
+client-mssql:
+	${MSSQL_CLIENT}
+
+
+#
+# Integration testing.
+#
+
+# Build all the test benches.
+build-all:
+	./test/buildbot/bb.sh build
+
+# Start the test bench for PostgreSQL 8.4
+start-pgsql84:
+	./test/buildbot/bb.sh start pgsql84
+
+# Start the test bench for PostgreSQL 9.0
+start-pgsql90:
+	./test/buildbot/bb.sh start pgsql90
+
+# Start the test bench for MySQL 5.1
+start-mysql51:
+	./test/buildbot/bb.sh start mysql51
+
+# Start the test bench for Oracle 10g
+start-oracle10g:
+	./test/buildbot/bb.sh start oracle10g
+
+# Start the test bench for MS SQL Server 2005
+start-mssql2005:
+	./test/buildbot/bb.sh start mssql2005
+
+# Start the test bench for MS SQL Server 2008
+start-mssql2008:
+	./test/buildbot/bb.sh start mssql2008
+
 
 #
 # Demos and examples.
 PGSQL_USERNAME?=htsql_regress
 PGSQL_PASSWORD?=secret
 PGSQL_DATABASE?=htsql_regress
-
-PGSQL_START?=
-PGSQL_STOP?=
+PGSQL_NATIVE?=psql
 
 PGSQL_ADDRESS1?=$(if ${PGSQL_USERNAME},${PGSQL_USERNAME}$(if ${PGSQL_PASSWORD},:${PGSQL_PASSWORD})@)
 PGSQL_ADDRESS2?=$(if ${PGSQL_HOST},${PGSQL_HOST}$(if ${PGSQL_PORT},:${PGSQL_PORT}))
 PGSQL_ADDRESS?=${PGSQL_ADDRESS1}${PGSQL_ADDRESS2}
 PGSQL_URI?=pgsql://${PGSQL_ADDRESS}/${PGSQL_DATABASE}
 
-PGSQL_CLIENT?=psql \
+PGSQL_CLIENT?=${PSQL_NATIVE} \
 	$(if ${PGSQL_HOST},-h ${PGSQL_HOST}) \
 	$(if ${PGSQL_PORT}, -p ${PGSQL_PORT}) \
 	$(if ${PGSQL_USERNAME},-U ${PGSQL_USERNAME}) \
 MYSQL_USERNAME?=htsql_regress
 MYSQL_PASSWORD?=secret
 MYSQL_DATABASE?=htsql_regress
-
-MYSQL_START?=
-MYSQL_STOP?=
+MYSQL_NATIVE?=mysql
 
 MYSQL_ADDRESS1?=$(if ${MYSQL_USERNAME},${MYSQL_USERNAME}$(if ${MYSQL_PASSWORD},:${MYSQL_PASSWORD})@)
 MYSQL_ADDRESS2?=$(if ${MYSQL_HOST},${MYSQL_HOST}$(if ${MYSQL_PORT},:${MYSQL_PORT}))
 MYSQL_ADDRESS?=${MYSQL_ADDRESS1}${MYSQL_ADDRESS2}
 MYSQL_URI?=mysql://${MYSQL_ADDRESS}/${MYSQL_DATABASE}
 
-MYSQL_CLIENT?=mysql \
+MYSQL_CLIENT?=${MYSQL_NATIVE} \
 	$(if ${MYSQL_HOST},-h ${MYSQL_HOST}) \
 	$(if ${MYSQL_PORT}, -P ${MYSQL_PORT}) \
 	$(if ${MYSQL_USERNAME},-u ${MYSQL_USERNAME}) \
 	$(if ${MYSQL_PASSWORD},-p${MYSQL_PASSWORD}) \
 	${MYSQL_DATABASE}
 
+
+#
+# Regression database for Oracle
+#
+
+ORACLE_ADMIN_USERNAME?=system
+ORACLE_ADMIN_PASSWORD?=
+ORACLE_HOST?=
+ORACLE_PORT?=
+ORACLE_USERNAME?=htsql_regress
+ORACLE_PASSWORD?=secret
+ORACLE_SID?=htsql_regress
+ORACLE_NATIVE?=sqlplus
+
+ORACLE_ADDRESS1?=$(if ${ORACLE_USERNAME},${ORACLE_USERNAME}$(if ${ORACLE_PASSWORD},:${ORACLE_PASSWORD})@)
+ORACLE_ADDRESS2?=$(if ${ORACLE_HOST},${ORACLE_HOST}$(if ${ORACLE_PORT},:${ORACLE_PORT}))
+ORACLE_ADDRESS?=${ORACLE_ADDRESS1}${ORACLE_ADDRESS2}
+ORACLE_URI?=oracle://${ORACLE_ADDRESS}/${ORACLE_SID}
+
+ORACLE_CONNECT1?=$(if ${ORACLE_USERNAME},${ORACLE_USERNAME}$(if ${ORACLE_PASSWORD},/${ORACLE_PASSWORD})@)
+ORACLE_CONNECT2?=$(if ${ORACLE_HOST},${ORACLE_HOST}$(if ${ORACLE_PORT},:${ORACLE_PORT}))
+ORACLE_CONNECT?=${ORACLE_CONNECT1}${ORACLE_CONNECT2}
+ORACLE_CLIENT?=${ORACLE_NATIVE} -L ${ORACLE_CONNECT}
+
+
+#
+# Regression database for MS SQL Server
+#
+
+MSSQL_ADMIN_USERNAME?=sa
+MSSQL_ADMIN_PASSWORD?=
+MSSQL_HOST?=
+MSSQL_PORT?=
+MSSQL_USERNAME?=htsql_regress
+MSSQL_PASSWORD?=secret
+MSSQL_DATABASE?=htsql_regress
+MSSQL_NATIVE?=tsql
+
+MSSQL_ADDRESS1?=$(if ${MSSQL_USERNAME},${MSSQL_USERNAME}$(if ${MSSQL_PASSWORD},:${MSSQL_PASSWORD})@)
+MSSQL_ADDRESS2?=$(if ${MSSQL_HOST},${MSSQL_HOST}$(if ${MSSQL_PORT},:${MSSQL_PORT}))
+MSSQL_ADDRESS?=${MSSQL_ADDRESS1}${MSSQL_ADDRESS2}
+MSSQL_URI?=mysql://${MSSQL_ADDRESS}/${MSSQL_DATABASE}
+
+MSSQL_CLIENT?=${MSSQL_NATIVE} \
+	$(if ${MSSQL_HOST},-H ${MSSQL_HOST}) \
+	$(if ${MSSQL_PORT}, -p ${MSSQL_PORT}) \
+	$(if ${MSSQL_USERNAME},-U ${MSSQL_USERNAME}) \
+	$(if ${MSSQL_PASSWORD},-P ${MSSQL_PASSWORD}) \
+	-D ${MSSQL_DATABASE}
+
+
+#
+# BuildBot parameters
+#
+
+BUILDBOT_ROOT?=build/bb
+BUILDBOT_DEBUG?=false
+
+
 # Export the parameters as environment variables.
 export PYTHON HTSQL_CTL SQLITE_DIRECTORY SQLITE_DATABASE SQLITE_URI \
 	PGSQL_ADMIN_USERNAME PGSQL_ADMIN_PASSWORD PGSQL_HOST PGSQL_PORT \
-	PGSQL_USERNAME PGSQL_PASSWORD PGSQL_DATABASE PGSQL_START PGSQL_STOP \
-	PGSQL_URI MYSQL_ADMIN_USERNAME MYSQL_ADMIN_PASSWORD MYSQL_HOST MYSQL_PORT \
-	MYSQL_USERNAME MYSQL_PASSWORD MYSQL_DATABASE MYSQL_START MYSQL_STOP \
-	MYSQL_URI
+	PGSQL_USERNAME PGSQL_PASSWORD PGSQL_DATABASE PGSQL_URI \
+	MYSQL_ADMIN_USERNAME MYSQL_ADMIN_PASSWORD MYSQL_HOST MYSQL_PORT \
+	MYSQL_USERNAME MYSQL_PASSWORD MYSQL_DATABASE MYSQL_URI \
+	ORACLE_ADMIN_USERNAME ORACLE_ADMIN_PASSWORD ORACLE_HOST ORACLE_PORT \
+	ORACLE_USERNAME ORACLE_PASSWORD ORACLE_SID ORACLE_URI \
+	MSSQL_ADMIN_USERNAME MSSQL_ADMIN_PASSWORD MSSQL_HOST MSSQL_PORT \
+	MSSQL_USERNAME MSSQL_PASSWORD MSSQL_DATABASE MSSQL_URI \
+	BUILDBOT_ROOT BUILDBOT_DEBUG
 
 

test/buildbot/bb.sh

+#!/bin/sh
+
+
+if [ "$BUILDBOT_DEBUG" = true ]; then
+    set -e
+    set -x
+fi
+
+LINUX_BENCHES="pgsql84 pgsql90 mysql51 oracle10g"
+WINDOWS_BENCHES="mssql2005 mssql2008"
+BENCHES="$LINUX_BENCHES $WINDOWS_BENCHES"
+
+IMG=$BUILDBOT_ROOT/img
+CTL=$BUILDBOT_ROOT/ctl
+TMP=$BUILDBOT_ROOT/tmp
+
+LINUX_ISO_URL=http://cdimage.debian.org/debian-cd/6.0.0/i386/iso-cd/debian-6.0.0-i386-netinst.iso
+LINUX_ISO=`basename $LINUX_ISO_URL`
+
+WGET_URL=http://downloads.sourceforge.net/gnuwin32/wget-1.11.4-1-setup.exe
+WGET=`basename $WGET_URL`
+
+WINDOWS_ISO_FILES="
+    en_win_srv_2003_r2_standard_with_sp2_cd1_x13-04790.iso
+    en_windows_xp_professional_with_service_pack_3_x86_cd_x14-80428.iso
+"
+
+VM_TYPE=
+
+DATA_ROOT=test/buildbot/data
+
+FMT=qcow2
+SZ=8G
+MEM=512
+
+STATE=ready
+
+
+prepare() {
+    echo "Checking prerequisites..."
+
+    if [ -z "$BUILDBOT_ROOT" ]; then
+        echo "ERROR: \$BUILDBOT_ROOT variable is not set!"
+        exit 2
+    fi
+
+    mkdir -p $BUILDBOT_ROOT $IMG $CTL $TMP
+
+    for cmd in ssh ssh-keygen scp wget 7z md5sum mkisofs socat kvm kvm-img; do
+        if [ -z `which $cmd` ]; then
+            echo "ERROR: command not found: $cmd"
+            exit 2
+        fi
+    done
+
+    echo "Checking prerequisites: DONE"
+}
+
+
+vm_create() {
+    local VM="$1"
+
+	kvm-img create -f $FMT $IMG/$VM.$FMT $SZ >/dev/null
+}
+
+
+vm_launch() {
+    local VM="$1"
+    local OPTS="$2"
+
+    case $VM_TYPE in
+    linux)
+        local NIC_MODEL=virtio
+        local VGA_TYPE=vmware;;
+    windows)
+        local NIC_MODEL=rtl8139
+        local VGA_TYPE=cirrus;;
+    esac
+
+    case $BUILDBOT_DEBUG in
+    true)
+        local VNC="";;
+    *)
+        local VNC="-vnc none";;
+    esac
+
+    kvm -name $VM -m $MEM -monitor unix:$CTL/$VM,server,nowait  \
+        -drive file=$IMG/$VM.$FMT,cache=writeback               \
+        -net nic,model=$NIC_MODEL -net user -vga $VGA_TYPE $VNC \
+        $OPTS
+}
+
+
+vm_ctl() {
+    local VM="$1"
+    local CMD="$2"
+
+    echo "$CMD" | socat stdin unix-connect:$CTL/$VM
+}
+
+
+vm_wait() {
+    local VM="$1"
+
+    while echo '' | socat stdin unix-connect:$CTL/$VM >/dev/null 2>&1; do
+        sleep 3
+    done
+}
+
+
+vm_forward() {
+    local VM="$1"
+    local PORTS="$2"
+
+    vm_ctl $VM "hostfwd_add tcp:127.0.0.1$PORTS"
+}
+
+
+vm_unforward() {
+    local VM="$1"
+    local PORTS="$2"
+
+    vm_ctl $VM "hostfwd_remove tcp:$PORTS"
+}
+
+
+vm_exec() {
+    local VM="$1"
+    local CMD="$2"
+
+    case $VM_TYPE in
+    linux)
+        local SSH_USER=root;;
+    windows)
+        local SSH_USER=Administrator;;
+    esac
+
+    vm_forward $VM :10022-:22
+    vm_ctl $VM "hostfwd_add tcp:127.0.0.1:10022-:22"
+    ssh -p 10022 -i $CTL/identity                   \
+        -o 'NoHostAuthenticationForLocalhost yes'   \
+        $SSH_USER@localhost "$CMD" >/dev/null 2>&1
+    vm_unforward $VM :10022-:22
+}
+
+
+vm_cp() {
+    local VM="$1"
+    local FROM="$2"
+    local TO="$3"
+
+    case $VM_TYPE in
+    linux)
+        local SSH_USER=root;;
+    windows)
+        local SSH_USER=Administrator;;
+    esac
+
+    vm_forward $VM :10022-:22
+    scp -P 10022 -i $CTL/identity                   \
+        -o 'NoHostAuthenticationForLocalhost yes'   \
+        "$FROM" $SSH_USER@localhost:"$TO" >/dev/null 2>&1
+    vm_unforward $VM :10022-:22
+}
+
+
+build_linux_vm() {
+    local VM_TYPE=linux
+
+    if [ -f "$IMG/linux-vm.$FMT" ]; then
+        echo "Building a Linux VM: already exists"
+        return
+    fi
+
+    echo "Building a Linux VM..."
+
+    if [ ! -f "$TMP/$LINUX_ISO" ]; then
+        wget -q $LINUX_ISO_URL -O $TMP/$LINUX_ISO
+    fi
+
+    if [ ! -f "$CTL/identity" ]; then
+        ssh-keygen -q -N "" -f $CTL/identity
+    fi
+
+    7z x $TMP/$LINUX_ISO -o$TMP/linux-vm-iso >/dev/null
+
+    cp $DATA_ROOT/linux-isolinux.cfg $TMP/linux-vm-iso/isolinux/isolinux.cfg
+    cp $DATA_ROOT/linux-preseed.cfg $TMP/linux-vm-iso/preseed.cfg
+    cp $DATA_ROOT/linux-install.sh $TMP/linux-vm-iso/install.sh
+    cp $CTL/identity.pub $TMP/linux-vm-iso/identity.pub
+
+    cd $TMP/linux-vm-iso
+    md5sum `find ! -name "md5sum.txt" ! -path "./isolinux/*" -follow -type f` > md5sum.txt
+    cd $OLDPWD
+
+    mkisofs -o $TMP/linux-vm.iso                                    \
+        -q -r -J -no-emul-boot -boot-load-size 4 -boot-info-table	\
+        -b isolinux/isolinux.bin -c isolinux/boot.cat               \
+        $TMP/linux-vm-iso
+
+    rm -rf $TMP/linux-vm-iso
+
+    vm_create linux-vm
+    vm_launch linux-vm "-cdrom $TMP/linux-vm.iso -boot d"
+
+    rm $TMP/linux-vm.iso
+
+    echo "Building a Linux VM: DONE"
+}
+
+
+build_linux_bench() {
+    local NAME="$1"
+    local VM="$NAME-vm"
+
+    local VM_TYPE=linux
+
+    if [ -f "$IMG/$VM.$FMT" ]; then
+        echo "Building a test bench '$NAME': already exists"
+        return
+    fi
+
+    echo "Building a test bench '$NAME'..."
+
+    cp $IMG/linux-vm.$FMT $IMG/$VM.$FMT
+
+	vm_launch $VM "-daemonize"
+    sleep 60
+
+    vm_cp $VM $DATA_ROOT/$NAME-update.sh /root/update.sh
+    vm_exec $VM "/root/update.sh"
+    vm_exec $VM "rm /root/update.sh"
+    vm_exec $VM "poweroff"
+    vm_wait $VM
+
+	vm_launch $VM "-daemonize"
+    sleep 60
+    vm_ctl $VM "savevm $STATE"
+    vm_ctl $VM "quit"
+    vm_wait $VM
+
+    echo "Building a test bench '$NAME': DONE"
+}
+
+
+build_windows_vm() {
+    local VM_TYPE=windows
+
+    if [ -f "$IMG/windows-vm.$FMT" ]; then
+        echo "Building a MS Windows VM: already exists"
+        return
+    fi
+
+    echo "Building a MS Windows VM..."
+
+    if [ -z "$WINDOWS_ISO_PATH" ]; then
+        for ISO_FILE in $WINDOWS_ISO_FILES; do
+            local ISO_PATH=`locate $ISO_FILE | head -n 1`
+            if [ -n "$ISO_PATH" -a -f "$ISO_PATH" ]; then
+                WINDOWS_ISO_PATH=$ISO_PATH
+                break
+            fi
+        done
+    fi
+
+    if [ -z "$WINDOWS_ISO_PATH" -o ! -f "$WINDOWS_ISO_PATH" ]; then
+        echo "ERROR: \$WINDOWS_ISO_PATH variable is not set or not a file"
+        exit 2
+    fi
+
+    if [ -z "$WINDOWS_KEY_PATH" ]; then
+        WINDOWS_KEY_PATH=`dirname "$WINDOWS_ISO_PATH"`/`basename "$WINDOWS_ISO_PATH" .iso`.key
+    fi
+
+    if [ -z "$WINDOWS_KEY_PATH" -o ! -f "$WINDOWS_KEY_PATH" ]; then
+        echo "ERROR: \$WINDOWS_KEY_PATH variable is not set or not a file"
+        exit 2
+    fi
+
+    WINDOWS_KEY=`cat "$WINDOWS_KEY_PATH" | head -n 1`
+
+    if [ ! -f "$TMP/$WGET" ]; then
+        wget -q $WGET_URL -O $TMP/$WGET
+    fi
+
+    if [ ! -f "$CTL/identity" ]; then
+        ssh-keygen -q -N "" -f $CTL/identity
+    fi
+
+    7z x "$WINDOWS_ISO_PATH" -o$TMP/windows-vm-iso >/dev/null
+
+    cp $DATA_ROOT/windows-winnt.sif $TMP/windows-vm-iso/I386/WINNT.SIF
+    sed -i -e "s/#####-#####-#####-#####-#####/$WINDOWS_KEY/" $TMP/windows-vm-iso/I386/WINNT.SIF
+    mkdir -p $TMP/windows-vm-iso/'$OEM$'/'$1'/INSTALL
+    cp $TMP/$WGET $TMP/windows-vm-iso/'$OEM$'/'$1'/INSTALL
+    cp $CTL/identity.pub $TMP/windows-vm-iso/'$OEM$'/'$1'/INSTALL
+    cp $DATA_ROOT/windows-install.cmd $TMP/windows-vm-iso/'$OEM$'/'$1'/INSTALL/INSTALL.CMD
+
+	mkisofs -o $TMP/windows-vm.iso -q -iso-level 2 -J -l -D -N      \
+        -joliet-long -relaxed-filenames -no-emul-boot               \
+        -boot-load-size 4 -b '[BOOT]/Bootable_NoEmulation.img'      \
+        $TMP/windows-vm-iso >/dev/null 2>&1
+
+    rm -rf $TMP/windows-vm-iso
+
+    vm_create windows-vm
+    vm_launch windows-vm "-cdrom $TMP/windows-vm.iso -boot d"
+
+    rm $TMP/windows-vm.iso
+
+    echo "Building a MS Windows VM: DONE"
+}
+
+
+build_windows_bench() {
+    local NAME="$1"
+    local VM="$NAME-vm"
+
+    local VM_TYPE=windows
+
+    if [ -f "$IMG/$VM.$FMT" ]; then
+        echo "Building a test bench '$NAME': already exists"
+        return
+    fi
+
+    echo "Building a test bench '$NAME'..."
+
+    cp $IMG/windows-vm.$FMT $IMG/$VM.$FMT
+
+	vm_launch $VM "-daemonize"
+    sleep 120
+
+    vm_cp $VM $DATA_ROOT/$NAME-update.cmd /cygdrive/c/INSTALL/UPDATE.CMD
+    vm_exec $VM "reg add 'HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce' /v $VM /t REG_SZ /d 'C:\INSTALL\UPDATE.CMD' /f"
+    vm_exec $VM "shutdown /r /t 0 /f"
+    vm_wait $VM
+
+	vm_launch $VM "-daemonize"
+    sleep 120
+    vm_ctl $VM "savevm $STATE"
+    vm_ctl $VM "quit"
+    vm_wait $VM
+
+    echo "Building a test bench '$NAME': DONE"
+}
+
+
+start_linux_bench() {
+    local NAME="$1"
+    local PORTS="$2"
+    local VM="$NAME-vm"
+
+    local VM_TYPE=linux
+
+    echo "Starting a test bench '$NAME'..."
+
+	vm_launch $VM "-daemonize -loadvm $STATE"
+    vm_forward $VM $PORTS
+    sleep 5
+
+    echo "Forwarding ports $PORTS"
+    echo "Starting a test bench '$NAME': DONE"
+}
+
+
+start_windows_bench() {
+    local NAME="$1"
+    local PORTS="$2"
+    local VM="$NAME-vm"
+
+    local VM_TYPE=windows
+
+    echo "Starting a test bench '$NAME'..."
+
+	vm_launch $VM "-daemonize -loadvm $STATE"
+    vm_forward $VM $PORTS
+    sleep 60
+
+    echo "Forwarding ports $PORTS"
+    echo "Starting a test bench '$NAME': DONE"
+}
+
+
+stop_bench() {
+    local NAME="$1"
+    local VM="$NAME-vm"
+
+    echo "Stopping a test bench '$NAME'..."
+
+    vm_ctl $VM "quit"
+    vm_wait $VM
+
+    echo "Stopping a test bench '$NAME': DONE"
+}
+
+
+usage() {
+    echo "Usage:"
+    echo "  $0 build [<bench>...]"
+    echo "  $0 start [<bench>...]"
+    echo "  $0 stop [<bench>...]"
+    echo "where <bench> is one of:"
+    echo "  $BENCHES"
+    exit 2
+}
+
+
+failure() {
+    echo "Fatal error, killing any stray KVM processes and existing..."
+    killall -q kvm
+    exit 2
+}
+
+
+found() {
+    local VALUE="$1"
+    local SET="$2"
+
+    for ELEMENT in $SET; do
+        if [ "$VALUE" = "$ELEMENT" ]; then
+            return 0
+        fi
+    done
+
+    return 1
+}
+
+
+not_found() {
+    if found "$1" "$2"; then
+        return 1
+    else
+        return 0
+    fi
+}
+
+
+do_build() {
+    local LIST="$1"
+
+    prepare
+
+    for BENCH in $LINUX_BENCHES; do
+        if found $BENCH "$LIST"; then
+            build_linux_vm
+            build_linux_bench $BENCH
+        fi
+    done
+
+    for BENCH in $WINDOWS_BENCHES; do
+        if found $BENCH "$LIST"; then
+            build_windows_vm
+            build_windows_bench $BENCH
+        fi
+    done
+}
+
+
+do_start() {
+    local LIST="$1"
+
+    prepare
+
+    if found py25 "$LIST"; then
+        start_linux_bench py25 :10022-:22
+    fi
+
+    if found py26 "$LIST"; then
+        start_linux_bench py26 :10022-:22
+    fi
+
+    if found pgsql84 "$LIST"; then
+        start_linux_bench pgsql84 :15432-:5432
+    fi
+
+    if found pgsql90 "$LIST"; then
+        start_linux_bench pgsql90 :15432-:5432
+    fi
+
+    if found mysql51 "$LIST"; then
+        start_linux_bench mysql51 :13306-:3306
+    fi
+
+    if found oracle10g "$LIST"; then
+        start_linux_bench oracle10g :11521-:1521
+    fi
+
+    if found mssql2005 "$LIST"; then
+        start_windows_bench mssql2005 :11433-:1433
+    fi
+
+    if found mssql2008 "$LIST"; then
+        start_windows_bench mssql2008 :11433-:1433
+    fi
+}
+
+
+do_stop() {
+    local LIST="$1"
+
+    prepare
+
+    for BENCH in $BENCHES; do
+        if found $BENCH "$LIST"; then
+            stop_bench $BENCH
+        fi
+    done
+}
+
+
+main() {
+    if [ "$#" -eq "0" ]; then
+        usage
+    fi
+
+    local SUBROUTINE=$1
+    shift
+    local ARGUMENTS="$@"
+
+    if [ -z "$ARGUMENTS" ]; then
+        ARGUMENTS="$BENCHES"
+    fi
+
+    for ARG in $ARGUMENTS; do
+        if not_found $ARG "$BENCHES"; then
+            echo "ERROR: invalid argument: $ARG"
+            echo
+            usage
+        fi
+    done
+
+    case $SUBROUTINE in
+
+    build)
+        do_build "$ARGUMENTS"
+        return;;
+
+    start)
+        do_start "$ARGUMENTS"
+        return;;
+
+    stop)
+        do_stop "$ARGUMENTS"
+        return;;
+
+    *)
+        echo "ERROR: invalid subroutine: $SUBROUTINE"
+        echo
+        usage;;
+
+    esac
+}
+
+main "$@"
+exit
+

test/buildbot/data/linux-install.sh

+#/bin/sh
+
+# Post-installation script for the Lunux VM.
+
+# Add the public key to /root/.ssh/authorized_keys.
+mkdir /root/.ssh
+chmod go-rwx /root/.ssh
+cp identity.pub /root/.ssh/authorized_keys
+

test/buildbot/data/linux-isolinux.cfg

+# This is a configuration file for the ISOLINUX boot loader.
+# See http://syslinux.zytor.com/ for general information on ISOLINUX.
+# See http://www.debian.org/releases/stable/i386/apbs02.html.en#preseed-bootparms
+# for information on using boot parameters to preseed questions.
+
+default linux
+label linux
+say Installing Debian GNU/Linux...
+kernel /install.386/vmlinuz
+append vga=normal initrd=/install.386/initrd.gz debian-installer/locale=en_US.UTF-8 console-keymaps-at/keymap=us preseed/file=/cdrom/preseed.cfg -- quiet
+

test/buildbot/data/linux-preseed.cfg

+# This is an answer file for the Debian installer.
+# See http://www.debian.org/releases/stable/i386/apb.html.en
+# for the general documentation on preseeding.
+# See http://www.debian.org/releases/stable/example-preseed.txt
+# for an example of a preseed file.
+
+# Set the locale (noop, must be set as a boot parameter).
+d-i debian-installer/locale string en_US.UTF-8
+
+# Choose the keyboard configuration (noop, must be set as a boot parameter).
+d-i console-keymaps-at/keymap select us
+
+# Set the hostname and the domain.
+d-i netcfg/get_hostname string linux-vm
+d-i netcfg/get_domain string
+
+# Select the time zone (we might want to use UTC here).
+d-i time/zone string US/Eastern
+
+# Choose regular partitioning, no LVM or encryption.
+d-i partman-auto/method string regular
+
+# We need to provide a custom partitioning recipe because the Oracle server
+# (and the client) requires a larger swap than provided by default.
+# So we allocate 2G for the swap (twice as much as required by Oracle)
+# and give the rest for the root filesystem.
+#
+# For general description of the recipe format, see
+# partman-auto-recipe.txt in the debian-installer package.
+d-i partman-auto/expert_recipe string   \
+    fs-recipe :                         \
+        1024 65536 65536 ext3           \
+            $primary{ }                 \
+            $bootable{ }                \
+            method{ format }            \
+            format{ }                   \
+            use_filesystem{ }           \
+            filesystem{ ext3 }          \
+            mountpoint{ / }             \
+        .                               \
+        2048 2048 2048 linux-swap       \
+            method{ swap }              \
+            format{ }                   \
+        .
+
+# Confirm the partitioning.
+d-i partman-partitioning/confirm_write_new_label boolean true
+d-i partman/choose_partition select finish
+d-i partman/confirm boolean true
+d-i partman/confirm_nooverwrite boolean true
+
+# Set the root password: root.
+d-i passwd/root-password password root
+d-i passwd/root-password-again password root
+
+# Do not create a regular user.
+d-i passwd/make-user boolean false
+
+# Select APT mirror and proxy settings.
+d-i mirror/country string US
+d-i mirror/http/mirror select ftp.us.debian.org
+d-i mirror/http/proxy string
+
+# Add an extra repository for Debian backports.
+d-i apt-setup/local0/repository string http://backports.debian.org/debian-backports squeeze-backports main
+
+# Package selection: standard.
+tasksel tasksel/first multiselect standard
+
+# Additional packages to install.
+d-i pkgsel/include string openssh-server build-essential
+
+# Indicate how to upgrade packages after debootstrap.
+d-i pkgsel/upgrade select safe-upgrade
+
+# Do not participate in the popularity contest.
+popularity-contest popularity-contest/participate boolean false
+
+# Install the boot loader to the MBR.
+d-i grub-installer/only_debian boolean true
+
+# Execute the post-installation script in the chrooted environment.
+d-i preseed/late_command string         \
+    cp /cdrom/install.sh /target/;      \
+    cp /cdrom/identity.pub /target/;    \
+    in-target /install.sh;              \
+    rm /target/install.sh /target/identity.pub
+
+# Skip the reboot warning.
+d-i finish-install/reboot_in_progress note
+
+# Power off the machine after the installation is complete.
+d-i debian-installer/exit/poweroff boolean true
+

test/buildbot/data/mssql2005-update.cmd

+@echo off
+cd %systemdrive%\INSTALL
+
+rem Post-installation script for the mssql2005 VM.
+
+rem For instructions on installing MS SQL Server 2005 Express Edition, see
+rem http://www.microsoft.com/downloads/details.aspx?familyid=220549b5-0b07-4448-8848-dcc397514b41&displaylang=en
+rem SQL Server 2005 requires Service Pack 1 when installing on
+rem Windows Server 2003, or Service Pack 2 when installing on
+rem Windows XP.  The other prerequisite is .NET Framework 2.0.
+
+set PATH=%PATH%;"%programfiles%\GnuWin32\bin"
+set PATH=%PATH%;"%programfiles%\7-Zip"
+
+
+rem Supress the prompt for CD2.
+reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\R2Setup" /v cd2chain /t REG_DWORD /d 0 /f
+
+
+rem Download and install .NET Framework 2.0.
+wget -q http://download.microsoft.com/download/5/6/7/567758a3-759e-473e-bf8f-52154438565a/dotnetfx.exe
+rem dotnetfx /C /T:%systemdrive%/INSTALL/dotnetfx
+7z x dotnetfx.exe -odotnetfx
+cd dotnetfx
+install /q
+cd ..
+
+rem Download and install SQL Server 2005 Express Edition.
+wget -q http://download.microsoft.com/download/f/1/0/f10c4f60-630e-4153-bd53-c3010e4c513b/SQLEXPR.EXE
+rem SQLEXPR.EXE /x:%systemdrive%/INSTALL/SQLEXPR
+7z x SQLEXPR.EXE -oSQLEXPR
+cd SQLEXPR
+setup /qn ADDLOCAL=ALL SECURITYMODE=SQL SAPWD=tot8OmDeufi DISABLENETWORKPROTOCOLS=0
+cd ..
+
+rem Change the password for the SQL Server administrator account.
+set PATH=%PATH%;"%programfiles%\Microsoft SQL Server\90\Tools\binn"
+sqlcmd -S \SQLEXPRESS -Q "ALTER LOGIN sa WITH PASSWORD='admin', CHECK_POLICY=OFF"
+
+rem Enable TCP access to the SQL Server.
+reg add "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer\SuperSocketNetLib\Tcp\IP1" /v Enabled /t REG_DWORD /d 1 /f
+reg add "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer\SuperSocketNetLib\Tcp\IP1" /v TcpPort /t REG_SZ /d 1433 /f
+reg add "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer\SuperSocketNetLib\Tcp\IP2" /v Enabled /t REG_DWORD /d 1 /f
+reg add "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer\SuperSocketNetLib\Tcp\IP2" /v TcpPort /t REG_SZ /d 1433 /f
+reg add "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer\SuperSocketNetLib\Tcp\IPAll" /v TcpPort /t REG_SZ /d 1433 /f
+
+rem Shut down.
+shutdown /s /t 0 /f
+

test/buildbot/data/mssql2008-update.cmd

+@echo off
+cd %systemdrive%\INSTALL
+
+rem Post-installation script for the mssql2008 VM.
+
+rem For instructions on installing MS SQL Server 2008 R2, see
+rem http://msdn.microsoft.com/en-us/library/ms143219.aspx
+
+rem SQL Server 2005 requires Service Pack 1 when installing on
+rem Windows Server 2003, or Service Pack 2 when installing on
+rem Windows XP.  The other prerequisite is .NET Framework 2.0.
+
+rem Prerequisites: .NET Framework 2.0 SP2, Windows Installer 4.5
+
+set PATH=%PATH%;"%programfiles%\GnuWin32\bin"
+set PATH=%PATH%;"%programfiles%\7-Zip"
+
+rem .NET Framework 2.0 SP2
+wget -q http://download.microsoft.com/download/c/6/e/c6e88215-0178-4c6c-b5f3-158ff77b1f38/NetFx20SP2_x86.exe
+7z x NetFx20SP2_x86.exe -oNetFx20SP2_x86
+cd NetFx20SP2_x86
+setup.exe /q
+cd ..
+
+rem Windows Installer 4.5
+wget -q http://download.microsoft.com/download/2/6/1/261fca42-22c0-4f91-9451-0e0f2e08356d/WindowsServer2003-KB942288-v4-x86.exe
+WindowsServer2003-KB942288-v4-x86.exe /quiet /norestart
+
+rem MS SQL Server 2008 R2 Express
+wget -q http://download.microsoft.com/download/5/1/A/51A153F6-6B08-4F94-A7B2-BA1AD482BC75/SQLEXPR32_x86_ENU.exe
+SQLEXPR32_x86_ENU.exe /Q /IACCEPTSQLSERVERLICENSETERMS /ACTION=install /FEATURES=SQL /INSTANCENAME=MSSQLSERVER /SECURITYMODE=SQL /SAPWD=tot8OmDeufi /SQLSVCACCOUNT="NT AUTHORITY\NETWORK SERVICE" /TCPENABLED=1
+
+set path=%path%;"%programfiles%\Microsoft SQL Server\100\Tools\binn"
+sqlcmd -Q "ALTER LOGIN sa WITH PASSWORD='admin', CHECK_POLICY=OFF"
+
+rem Shut down.
+shutdown /s /t 0 /f
+
+

test/buildbot/data/mysql51-update.sh

+#/bin/sh
+
+# Post-installation script for the mysql51 VM.
+
+# Preset the password for the MySQL root user.
+echo "mysql-server-5.1 mysql-server/root_password password admin" | debconf-set-selections
+echo "mysql-server-5.1 mysql-server/root_password_again password admin" | debconf-set-selections
+
+# Install MySQL 5.1.
+apt-get -y install mysql-server-5.1
+
+# Configure MySQL to listen on all interfaces.
+cat <<END >/etc/mysql/conf.d/bind_address.cnf
+[mysqld]
+bind-address = 0.0.0.0
+END
+
+# Start the server (since it is not started during OS installation).
+/etc/init.d/mysql start
+
+# Grant administrative privileges to the root user regardless of the client
+# hostname.
+cat <<END | mysql -uroot -padmin
+GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY 'admin' WITH GRANT OPTION;
+END
+

test/buildbot/data/oracle10g-update.sh

+#/bin/sh
+
+# Post-installation script for the oracle10g VM.
+
+echo "deb http://oss.oracle.com/debian/ unstable main non-free" >/etc/apt/sources.list.d/oracle.list
+wget -q http://oss.oracle.com/el4/RPM-GPG-KEY-oracle -O- | apt-key add -
+apt-get update
+
+# Install the Oracle 10g Express Edition.
+apt-get -y install oracle-xe-universal
+
+# Fix the problem when the configuration script eats the last
+# character of the password if it is 'n': replace IFS="\n" with IFS=$'\n'.
+sed -i -e s/IFS=\"\\\\n\"/IFS=\$\'\\\\n\'/ /etc/init.d/oracle-xe
+
+# Configure the server; provide the answers for the following questions:
+# The HTTP port for Oracle Application Express: 8080
+# A port for the database listener: 1521
+# The password for the SYS and SYSTEM database accounts: admin
+# Start the server on boot: yes
+/etc/init.d/oracle-xe configure <<END
+8080
+1521
+admin
+admin
+y
+END
+
+# Set Oracle environment variables on login.
+cat <<END >>/root/.bashrc
+
+. /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh
+END
+

test/buildbot/data/pgsql84-update.sh

+#/bin/sh
+
+# Post-installation script for the pgsql84 VM.
+
+# Install the PostgreSQL 8.4 server.
+apt-get -y install postgresql-8.4
+
+# Set the password of the user postgres to 'admin'.
+su -c "psql -c \"ALTER ROLE postgres WITH PASSWORD 'admin'\"" postgres
+
+# Configure PostgreSQL to listen on all interfaces.
+cat <<END >>/etc/postgresql/8.4/main/postgresql.conf
+
+# Listen on all available interfaces:
+listen_addresses = '*'
+END
+
+# Configure PostgreSQL to allow login from the external interface.
+cat <<END >>/etc/postgresql/8.4/main/pg_hba.conf
+
+# Allow external network connections:
+host all all 10.0.0.1/8 md5
+END
+

test/buildbot/data/pgsql90-update.sh

+#/bin/sh
+
+# Post-installation script for the pgsql84 VM.
+
+# Install the PostgreSQL 8.4 server.
+apt-get -y -t squeeze-backports install postgresql-9.0
+
+# Set the password of the user postgres to 'admin'.
+su -c "psql -c \"ALTER ROLE postgres WITH PASSWORD 'admin'\"" postgres
+
+# Configure PostgreSQL to listen on all interfaces.
+cat <<END >>/etc/postgresql/9.0/main/postgresql.conf
+
+# Listen on all available interfaces:
+listen_addresses = '*'
+END
+
+# Configure PostgreSQL to allow login from the external interface.
+cat <<END >>/etc/postgresql/9.0/main/pg_hba.conf
+
+# Allow external network connections:
+host all all 10.0.0.1/8 md5
+END
+

test/buildbot/data/py25-update.sh

+#/bin/sh
+
+echo py25-vm >/etc/hostname
+
+apt-get -qq install mercurial >/dev/null
+
+apt-get -qq install python2.5 >/dev/null
+apt-get -qq install python-setuptools >/dev/null
+apt-get -qq install python-yaml >/dev/null
+apt-get -qq install python-pysqlite2 >/dev/null
+apt-get -qq install python-psycopg2 >/dev/null
+apt-get -qq install python-mysqldb >/dev/null
+
+hg -q clone https://bitbucket.org/prometheus/htsql
+

test/buildbot/data/py26-update.sh

+#/bin/sh
+
+echo py25-vm >/etc/hostname
+
+apt-get -qq install mercurial >/dev/null
+
+apt-get -qq install python2.5 >/dev/null
+apt-get -qq install python-setuptools >/dev/null
+apt-get -qq install python-yaml >/dev/null
+apt-get -qq install python-pysqlite2 >/dev/null
+apt-get -qq install python-psycopg2 >/dev/null
+apt-get -qq install python-mysqldb >/dev/null
+
+hg -q clone https://bitbucket.org/prometheus/htsql
+

test/buildbot/data/windows-install.cmd

+@echo off
+cd %systemdrive%\INSTALL
+
+rem Post-installation script for MS Windows.
+
+rem Install Wget.
+wget-1.11.4-1-setup.exe /silent
+
+set PATH=%PATH%;"%programfiles%\GnuWin32\bin"
+
+rem Download and install 7-Zip.
+wget -q http://downloads.sourceforge.net/sevenzip/7z465.exe
+7z465.exe /S
+set PATH=%PATH%;"%programfiles%\7-Zip"
+
+rem Download and install Copssh.
+wget -q http://downloads.sourceforge.net/project/sereds/Copssh/4.0.4/Copssh_4.0.4_Installer.zip
+7z x Copssh_4.0.4_Installer.zip
+Copssh_4.0.4_Installer.exe /S
+set PATH=%PATH%;"%programfiles%\ICW\bin"
+
+rem Add an SSH user.
+copsshadm --command activateuser --user Administrator
+copy identity.pub "%programfiles%\ICW\home\Administrator\.ssh\authorized_keys"
+
+rem Supress the prompt for CD2.
+reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\R2Setup" /v cd2chain /t REG_DWORD /d 0 /f
+
+rem Shut down.
+shutdown /s /t 0 /f
+

test/buildbot/data/windows-winnt.sif

+; This is an answer file for Windows unattended installation.
+; It was tested with MS Windows Server 2003 SP1 and
+; MS Windows XP SP3.
+;
+; See http://technet.microsoft.com/en-us/library/cc785417(WS.10).aspx
+; for the documentation on unattended installation;
+; see http://technet.microsoft.com/en-us/library/cc757642(WS.10).aspx#w2k3tr_unatt_tools_trka
+; for the description of the sections and the settings.
+
+; Run unattended installation from CDROM; choose the partition automatically.
+[Data]
+    AutoPartition = 1
+    MsDosInitiated = 0
+    UnattendedInstall = Yes
+
+; Reformat the drive; copy the OEM directory to the hard drive.
+[Unattended]
+    UnattendMode = FullUnattended
+    OemSkipEula = Yes
+    OemPreinstall = Yes
+    TargetPath = "\WINDOWS"
+    UnattendSwitch = Yes
+    Repartition = Yes
+    WaitForReboot = No
+
+; Select the Administrator password; select the time zone: US/Eastern.
+; Perform auto-logon once to force execution of the post-installation script.
+[GuiUnattended]
+    AdminPassword = "Administrator"
+    EncryptedAdminPassword = No
+    OemSkipRegional = 1
+    TimeZone = 35
+    OemSkipWelcome = 1
+    AutoLogon = Yes
+    AutoLogonCount = 999
+    ServerWelcome = No
+
+; Here the value of the ProductKey parameter has to be replaced
+; with a real product key; the computer name is generated automatically.
+[UserData]
+    ProductKey = "#####-#####-#####-#####-#####"
+    FullName = "WINDOWS-VM"
+    OrgName = "WINDOWS-VM"
+    ComputerName = *
+
+; Regular workgroup settings.
+[Identification]
+    JoinWorkgroup = WORKGROUP
+
+; Regular networking settings.
+[Networking]
+    InstallDefaultComponents = Yes
+
+; Licensing model.
+[LicenseFilePrintData]
+    AutoMode = PerServer
+    AutoUsers = 5
+
+; Confirm changing display settings for Windows XP.
+[Display]
+    AutoConfirm = 1
+
+; Turn off the firewall.
+[WindowsFirewall]
+    Profiles = WindowsFirewall.TurnOffFirewall
+
+[WindowsFirewall.TurnOffFirewall]
+    Mode = 0
+
+; Run the post-installation script on the first logon.
+[GuiRunOnce]
+    "%systemdrive%\INSTALL\INSTALL.CMD"
+