summaryrefslogtreecommitdiffstats
path: root/taskcluster/scripts/tester
diff options
context:
space:
mode:
Diffstat (limited to 'taskcluster/scripts/tester')
-rw-r--r--taskcluster/scripts/tester/harness-test-linux.sh40
-rwxr-xr-xtaskcluster/scripts/tester/run-wizard170
-rw-r--r--taskcluster/scripts/tester/test-b2g.sh118
-rw-r--r--taskcluster/scripts/tester/test-macosx.sh77
-rw-r--r--taskcluster/scripts/tester/test-ubuntu.sh188
5 files changed, 593 insertions, 0 deletions
diff --git a/taskcluster/scripts/tester/harness-test-linux.sh b/taskcluster/scripts/tester/harness-test-linux.sh
new file mode 100644
index 000000000..b38ffa124
--- /dev/null
+++ b/taskcluster/scripts/tester/harness-test-linux.sh
@@ -0,0 +1,40 @@
+#! /bin/bash -vex
+
+set -x -e
+
+echo "running as" $(id)
+
+####
+# Taskcluster friendly wrapper for running a script in
+# testing/mozharness/scripts in a source checkout (no build).
+# Example use: Python-only harness unit tests
+####
+
+: WORKSPACE ${WORKSPACE:=/home/worker/workspace}
+: SRC_ROOT ${SRC_ROOT:=$WORKSPACE/build/src}
+# These paths should be relative to $SRC_ROOT
+: MOZHARNESS_SCRIPT ${MOZHARNESS_SCRIPT}
+: MOZHARNESS_CONFIG ${MOZHARNESS_CONFIG}
+: mozharness args "${@}"
+
+set -v
+cd $WORKSPACE
+
+fail() {
+ echo # make sure error message is on a new line
+ echo "[harness-test-linux.sh:error]" "${@}"
+ exit 1
+}
+
+if [[ -z ${MOZHARNESS_SCRIPT} ]]; then fail "MOZHARNESS_SCRIPT is not set"; fi
+
+# support multiple, space delimited, config files
+config_cmds=""
+for cfg in $MOZHARNESS_CONFIG; do
+ config_cmds="${config_cmds} --config-file ${SRC_ROOT}/${cfg}"
+done
+
+python2.7 $SRC_ROOT/${MOZHARNESS_SCRIPT} ${config_cmds} "${@}"
+
+
+
diff --git a/taskcluster/scripts/tester/run-wizard b/taskcluster/scripts/tester/run-wizard
new file mode 100755
index 000000000..5dafb0b62
--- /dev/null
+++ b/taskcluster/scripts/tester/run-wizard
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this,
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from __future__ import print_function, unicode_literals
+
+import datetime
+import os
+import subprocess
+import sys
+import time
+from textwrap import wrap
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+
+def call(cmd, **kwargs):
+ print(" ".join(cmd))
+ return subprocess.call(cmd, **kwargs)
+
+
+def wait_for_run_mozharness(timeout=30):
+ starttime = datetime.datetime.now()
+ while datetime.datetime.now() - starttime < datetime.timedelta(seconds=timeout):
+ if os.path.isfile(os.path.join(here, 'run-mozharness')):
+ break
+ time.sleep(0.2)
+ else:
+ print("Timed out after %d seconds waiting for the 'run-mozharness' binary" % timeout)
+ return 1
+
+
+def resume():
+ wait_for_run_mozharness()
+ call(['run-mozharness'])
+
+
+def setup():
+ """Run the mozharness script without the 'run-tests' action.
+
+ This will do all the necessary setup steps like creating a virtualenv and
+ downloading the tests and firefox binary. But it stops before running the
+ tests.
+ """
+ wait_for_run_mozharness()
+ status = call(['run-mozharness', '--no-run-tests'])
+
+ if status:
+ # something went wrong
+ return status
+
+ build_dir = os.path.expanduser(os.path.join('~', 'workspace', 'build'))
+ mach_src = os.path.join(build_dir, 'tests', 'mach')
+ mach_dest = os.path.expanduser(os.path.join('~', 'bin', 'mach'))
+
+ if os.path.exists(mach_dest):
+ os.remove(mach_dest)
+ os.symlink(mach_src, mach_dest)
+
+ activate = os.path.join(build_dir, 'venv', 'bin', 'activate')
+ if os.path.isfile(activate):
+ # TODO Support other shells
+ bashrc = os.path.expanduser(os.path.join('~', '.bashrc'))
+ with open(bashrc, 'ab') as f:
+ f.write(". {}".format(activate))
+
+ print("""
+Mozharness has finished downloading the build and tests to:
+{}
+
+A limited mach environment has also been set up and added to the $PATH, but
+it may be missing the command you need. To see a list of commands, run:
+ $ mach help
+""".lstrip().format(build_dir))
+
+
+def clone():
+ """Clone the correct gecko repository and update to the proper revision."""
+ base_repo = os.environ['GECKO_HEAD_REPOSITORY']
+ dest = os.path.expanduser(os.path.join('~', 'gecko'))
+
+ # Specify method to checkout a revision. This defaults to revisions as
+ # SHA-1 strings, but also supports symbolic revisions like `tip` via the
+ # branch flag.
+ if os.environ.get('GECKO_HEAD_REV'):
+ revision_flag = b'--revision'
+ revision = os.environ['GECKO_HEAD_REV']
+ elif os.environ.get('GECKO_HEAD_REF'):
+ revision_flag = b'--branch'
+ revision = os.environ['GECKO_HEAD_REF']
+ else:
+ print('revision is not specified for checkout')
+ return 1
+
+ # TODO Bug 1301382 - pin hg.mozilla.org fingerprint.
+ call([
+ b'/usr/bin/hg', b'robustcheckout',
+ b'--sharebase', os.environ['HG_STORE_PATH'],
+ b'--purge',
+ b'--upstream', b'https://hg.mozilla.org/mozilla-unified',
+ revision_flag, revision,
+ base_repo, dest
+ ])
+ print("Finished cloning to {} at revision {}.".format(dest, revision))
+
+
+def exit():
+ pass
+
+
+OPTIONS = [
+ ('Resume task', resume,
+ "Resume the original task without modification. This can be useful for "
+ "passively monitoring it from another shell."),
+ ('Setup task', setup,
+ "Setup the task (download the application and tests) but don't run the "
+ "tests just yet. The tests can be run with a custom configuration later. "
+ "This will provide a mach environment (experimental)."),
+ ('Clone gecko', clone,
+ "Perform a clone of gecko using the task's repo and update it to the "
+ "task's revision."),
+ ('Exit', exit, "Exit this wizard and return to the shell.")
+]
+
+
+def _fmt_options():
+ max_line_len = 60
+ max_name_len = max(len(o[0]) for o in OPTIONS)
+
+ # TODO Pad will be off if there are more than 9 options.
+ pad = ' ' * (max_name_len+6)
+
+ msg = []
+ for i, (name, _, desc) in enumerate(OPTIONS):
+ desc = wrap(desc, width=max_line_len)
+ desc = [desc[0]] + [pad + l for l in desc[1:]]
+
+ optstr = '{}) {} - {}\n'.format(
+ i+1, name.ljust(max_name_len), '\n'.join(desc))
+ msg.append(optstr)
+ msg.append("Select one of the above options: ")
+ return '\n'.join(msg)
+
+
+def wizard():
+ print("This wizard can help you get started with some common debugging "
+ "workflows.\nWhat would you like to do?\n")
+ print(_fmt_options(), end="")
+ choice = None
+ while True:
+ choice = raw_input().decode('utf8')
+ try:
+ choice = int(choice)-1
+ if 0 <= choice < len(OPTIONS):
+ break
+ except ValueError:
+ pass
+
+ print("Must provide an integer from 1-{}:".format(len(OPTIONS)))
+
+ func = OPTIONS[choice][1]
+ ret = func()
+
+ print("Use the 'run-wizard' command to start this wizard again.")
+ return ret
+
+
+if __name__ == '__main__':
+ sys.exit(wizard())
diff --git a/taskcluster/scripts/tester/test-b2g.sh b/taskcluster/scripts/tester/test-b2g.sh
new file mode 100644
index 000000000..43a54f93a
--- /dev/null
+++ b/taskcluster/scripts/tester/test-b2g.sh
@@ -0,0 +1,118 @@
+#! /bin/bash -xe
+
+set -x -e
+
+echo "running as" $(id)
+
+####
+# Taskcluster friendly wrapper for performing fx desktop tests via mozharness.
+####
+
+# Inputs, with defaults
+
+: MOZHARNESS_URL ${MOZHARNESS_URL}
+: MOZHARNESS_SCRIPT ${MOZHARNESS_SCRIPT}
+: MOZHARNESS_CONFIG ${MOZHARNESS_CONFIG}
+: NEED_XVFB ${NEED_XVFB:=true}
+: NEED_PULSEAUDIO ${NEED_PULSEAUDIO:=false}
+: NEED_PULL_GAIA ${NEED_PULL_GAIA:=false}
+: SKIP_MOZHARNESS_RUN ${SKIP_MOZHARNESS_RUN:=false}
+: WORKSPACE ${WORKSPACE:=/home/worker/workspace}
+: mozharness args "${@}"
+
+set -v
+cd $WORKSPACE
+
+# test required parameters are supplied
+if [[ -z ${MOZHARNESS_URL} ]]; then exit 1; fi
+if [[ -z ${MOZHARNESS_SCRIPT} ]]; then exit 1; fi
+if [[ -z ${MOZHARNESS_CONFIG} ]]; then exit 1; fi
+
+mkdir -p ~/artifacts/public
+
+cleanup() {
+ if [ -n "$xvfb_pid" ]; then
+ kill $xvfb_pid || true
+ fi
+}
+trap cleanup EXIT INT
+
+# Unzip the mozharness ZIP file created by the build task
+curl --fail -o mozharness.zip --retry 10 -L $MOZHARNESS_URL
+rm -rf mozharness
+unzip -q mozharness.zip
+rm mozharness.zip
+
+if ! [ -d mozharness ]; then
+ echo "mozharness zip did not contain mozharness/"
+ exit 1
+fi
+
+# start up the pulseaudio daemon. Note that it's important this occur
+# before the Xvfb startup.
+if $NEED_PULSEAUDIO; then
+ pulseaudio --fail --daemonize --start
+ pactl load-module module-null-sink
+fi
+
+# run XVfb in the background, if necessary
+if $NEED_XVFB; then
+ Xvfb :0 -nolisten tcp -screen 0 1600x1200x24 \
+ > ~/artifacts/public/xvfb.log 2>&1 &
+ export DISPLAY=:0
+ xvfb_pid=$!
+ # Only error code 255 matters, because it signifies that no
+ # display could be opened. As long as we can open the display
+ # tests should work. We'll retry a few times with a sleep before
+ # failing.
+ retry_count=0
+ max_retries=2
+ xvfb_test=0
+ until [ $retry_count -gt $max_retries ]; do
+ xvinfo || xvfb_test=$?
+ if [ $xvfb_test != 255 ]; then
+ retry_count=$(($max_retries + 1))
+ else
+ retry_count=$(($retry_count + 1))
+ echo "Failed to start Xvfb, retry: $retry_count"
+ sleep 2
+ fi done
+ if [ $xvfb_test == 255 ]; then exit 255; fi
+fi
+
+gaia_cmds=""
+if $NEED_PULL_GAIA; then
+ # test required parameters are supplied
+ if [[ -z ${GAIA_BASE_REPOSITORY} ]]; then exit 1; fi
+ if [[ -z ${GAIA_HEAD_REPOSITORY} ]]; then exit 1; fi
+ if [[ -z ${GAIA_REV} ]]; then exit 1; fi
+ if [[ -z ${GAIA_REF} ]]; then exit 1; fi
+
+ tc-vcs checkout \
+ ${WORKSPACE}/gaia \
+ ${GAIA_BASE_REPOSITORY} \
+ ${GAIA_HEAD_REPOSITORY} \
+ ${GAIA_REV} \
+ ${GAIA_REF}
+
+ gaia_cmds="--gaia-dir=${WORKSPACE}"
+fi
+
+# support multiple, space delimited, config files
+config_cmds=""
+for cfg in $MOZHARNESS_CONFIG; do
+ config_cmds="${config_cmds} --config-file ${cfg}"
+done
+
+if [ ${SKIP_MOZHARNESS_RUN} == true ]; then
+ # Skipping Mozharness is to allow the developer start the window manager
+ # properly and letting them change the execution of Mozharness without
+ # exiting the container
+ echo "We skipped running Mozharness."
+ echo "Make sure you export DISPLAY=:0 before calling Mozharness."
+ echo "Don't forget to call it with 'sudo -E -u worker'."
+else
+ # run the given mozharness script and configs, but pass the rest of the
+ # arguments in from our own invocation
+ python2.7 $WORKSPACE/${MOZHARNESS_SCRIPT} ${config_cmds} ${gaia_cmds} "${@}"
+fi
diff --git a/taskcluster/scripts/tester/test-macosx.sh b/taskcluster/scripts/tester/test-macosx.sh
new file mode 100644
index 000000000..8c2b758fb
--- /dev/null
+++ b/taskcluster/scripts/tester/test-macosx.sh
@@ -0,0 +1,77 @@
+#! /bin/bash -xe
+
+set -x -e
+
+echo "running as" $(id)
+
+####
+# Taskcluster friendly wrapper for performing fx Mac OSX tests via mozharness.
+####
+
+# Inputs, with defaults
+
+: MOZHARNESS_URL ${MOZHARNESS_URL}
+: MOZHARNESS_SCRIPT ${MOZHARNESS_SCRIPT}
+: MOZHARNESS_CONFIG ${MOZHARNESS_CONFIG}
+
+WORKSPACE=$HOME
+cd $WORKSPACE
+
+rm -rf artifacts
+mkdir artifacts
+
+# test required parameters are supplied
+if [[ -z ${MOZHARNESS_URL} ]]; then fail "MOZHARNESS_URL is not set"; fi
+if [[ -z ${MOZHARNESS_SCRIPT} ]]; then fail "MOZHARNESS_SCRIPT is not set"; fi
+if [[ -z ${MOZHARNESS_CONFIG} ]]; then fail "MOZHARNESS_CONFIG is not set"; fi
+
+# Download mozharness with exponential backoff
+# curl already applies exponential backoff, but not for all
+# failed cases, apparently, as we keep getting failed downloads
+# with 404 code.
+download_mozharness() {
+ local max_attempts=10
+ local timeout=1
+ local attempt=0
+
+ echo "Downloading mozharness"
+
+ while [[ $attempt < $max_attempts ]]; do
+ if curl --fail -o mozharness.zip --retry 10 -L $MOZHARNESS_URL; then
+ rm -rf mozharness
+ if unzip -q mozharness.zip; then
+ return 0
+ fi
+ echo "error unzipping mozharness.zip" >&2
+ else
+ echo "failed to download mozharness zip" >&2
+ fi
+ echo "Download failed, retrying in $timeout seconds..." >&2
+ sleep $timeout
+ timeout=$((timeout*2))
+ attempt=$((attempt+1))
+ done
+
+ fail "Failed to download and unzip mozharness"
+}
+
+download_mozharness
+rm mozharness.zip
+
+# For telemetry purposes, the build process wants information about the
+# source it is running; tc-vcs obscures this a little, but we can provide
+# it directly.
+export MOZ_SOURCE_REPO="${GECKO_HEAD_REPOSITORY}"
+export MOZ_SOURCE_CHANGESET="${GECKO_HEAD_REV}"
+
+# support multiple, space delimited, config files
+config_cmds=""
+for cfg in $MOZHARNESS_CONFIG; do
+ config_cmds="${config_cmds} --config-file ${cfg}"
+done
+
+rm -rf build logs properties target.dmg
+
+# run the given mozharness script and configs, but pass the rest of the
+# arguments in from our own invocation
+python2.7 $WORKSPACE/mozharness/scripts/${MOZHARNESS_SCRIPT} ${config_cmds} "${@}"
diff --git a/taskcluster/scripts/tester/test-ubuntu.sh b/taskcluster/scripts/tester/test-ubuntu.sh
new file mode 100644
index 000000000..0c2ccc702
--- /dev/null
+++ b/taskcluster/scripts/tester/test-ubuntu.sh
@@ -0,0 +1,188 @@
+#! /bin/bash -xe
+
+set -x -e
+
+echo "running as" $(id)
+
+# Detect release version.
+. /etc/lsb-release
+if [ "${DISTRIB_RELEASE}" == "12.04" ]; then
+ UBUNTU_1204=1
+elif [ "${DISTRIB_RELEASE}" == "16.04" ]; then
+ UBUNTU_1604=1
+fi
+
+. /home/worker/scripts/xvfb.sh
+
+####
+# Taskcluster friendly wrapper for performing fx desktop tests via mozharness.
+####
+
+# Inputs, with defaults
+
+: MOZHARNESS_PATH ${MOZHARNESS_PATH}
+: MOZHARNESS_URL ${MOZHARNESS_URL}
+: MOZHARNESS_SCRIPT ${MOZHARNESS_SCRIPT}
+: MOZHARNESS_CONFIG ${MOZHARNESS_CONFIG}
+: NEED_XVFB ${NEED_XVFB:=true}
+: NEED_WINDOW_MANAGER ${NEED_WINDOW_MANAGER:=false}
+: NEED_PULSEAUDIO ${NEED_PULSEAUDIO:=false}
+: START_VNC ${START_VNC:=false}
+: TASKCLUSTER_INTERACTIVE ${TASKCLUSTER_INTERACTIVE:=false}
+: WORKSPACE ${WORKSPACE:=/home/worker/workspace}
+: mozharness args "${@}"
+
+set -v
+cd $WORKSPACE
+
+fail() {
+ echo # make sure error message is on a new line
+ echo "[test-linux.sh:error]" "${@}"
+ exit 1
+}
+
+maybe_start_pulse() {
+ if $NEED_PULSEAUDIO; then
+ pulseaudio --fail --daemonize --start
+ pactl load-module module-null-sink
+ fi
+}
+
+# test required parameters are supplied
+if [ -z "${MOZHARNESS_PATH}" -a -z "${MOZHARNESS_URL}" ]; then
+ fail "MOZHARNESS_PATH or MOZHARNESS_URL must be defined";
+fi
+
+if [[ -z ${MOZHARNESS_SCRIPT} ]]; then fail "MOZHARNESS_SCRIPT is not set"; fi
+if [[ -z ${MOZHARNESS_CONFIG} ]]; then fail "MOZHARNESS_CONFIG is not set"; fi
+
+mkdir -p ~/artifacts/public
+
+cleanup() {
+ local rv=$?
+ if [[ -s /home/worker/.xsession-errors ]]; then
+ # To share X issues
+ cp /home/worker/.xsession-errors ~/artifacts/public/xsession-errors.log
+ fi
+ cleanup_xvfb
+ exit $rv
+}
+trap cleanup EXIT INT
+
+# Download mozharness with exponential backoff
+# curl already applies exponential backoff, but not for all
+# failed cases, apparently, as we keep getting failed downloads
+# with 404 code.
+download_mozharness() {
+ local max_attempts=10
+ local timeout=1
+ local attempt=0
+
+ echo "Downloading mozharness"
+
+ while [[ $attempt < $max_attempts ]]; do
+ if curl --fail -o mozharness.zip --retry 10 -L $MOZHARNESS_URL; then
+ rm -rf mozharness
+ if unzip -q mozharness.zip; then
+ return 0
+ fi
+ echo "error unzipping mozharness.zip" >&2
+ else
+ echo "failed to download mozharness zip" >&2
+ fi
+ echo "Download failed, retrying in $timeout seconds..." >&2
+ sleep $timeout
+ timeout=$((timeout*2))
+ attempt=$((attempt+1))
+ done
+
+ fail "Failed to download and unzip mozharness"
+}
+
+# Download mozharness if we're told to.
+if [ ${MOZHARNESS_URL} ]; then
+ download_mozharness
+ rm mozharness.zip
+
+ if ! [ -d mozharness ]; then
+ fail "mozharness zip did not contain mozharness/"
+ fi
+
+ MOZHARNESS_PATH=`pwd`/mozharness
+fi
+
+# pulseaudio daemon must be started before xvfb on Ubuntu 12.04.
+if [ "${UBUNTU_1204}" ]; then
+ maybe_start_pulse
+fi
+
+# run XVfb in the background, if necessary
+if $NEED_XVFB; then
+ start_xvfb '1600x1200x24' 0
+fi
+
+if $START_VNC; then
+ x11vnc > ~/artifacts/public/x11vnc.log 2>&1 &
+fi
+
+if $NEED_WINDOW_MANAGER; then
+ # This is read by xsession to select the window manager
+ echo DESKTOP_SESSION=ubuntu > /home/worker/.xsessionrc
+
+ # note that doing anything with this display before running Xsession will cause sadness (like,
+ # crashes in compiz). Make sure that X has enough time to start
+ sleep 15
+ # DISPLAY has already been set above
+ # XXX: it would be ideal to add a semaphore logic to make sure that the
+ # window manager is ready
+ /etc/X11/Xsession 2>&1 &
+
+ # Turn off the screen saver and screen locking
+ gsettings set org.gnome.desktop.screensaver idle-activation-enabled false
+ gsettings set org.gnome.desktop.screensaver lock-enabled false
+ gsettings set org.gnome.desktop.screensaver lock-delay 3600
+ # Disable the screen saver
+ xset s off s reset
+
+ if [ "${UBUNTU_1604}" ]; then
+ # start compiz for our window manager
+ compiz 2>&1 &
+ #TODO: how to determine if compiz starts correctly?
+ fi
+fi
+
+if [ "${UBUNTU_1604}" ]; then
+ maybe_start_pulse
+fi
+
+# For telemetry purposes, the build process wants information about the
+# source it is running; tc-vcs obscures this a little, but we can provide
+# it directly.
+export MOZ_SOURCE_REPO="${GECKO_HEAD_REPOSITORY}"
+export MOZ_SOURCE_CHANGESET="${GECKO_HEAD_REV}"
+
+# support multiple, space delimited, config files
+config_cmds=""
+for cfg in $MOZHARNESS_CONFIG; do
+ config_cmds="${config_cmds} --config-file ${MOZHARNESS_PATH}/configs/${cfg}"
+done
+
+mozharness_bin="/home/worker/bin/run-mozharness"
+
+# Save the computed mozharness command to a binary which is useful
+# for interactive mode.
+echo -e "#!/usr/bin/env bash
+# Some mozharness scripts assume base_work_dir is in
+# the current working directory, see bug 1279237
+cd $WORKSPACE
+cmd=\"python2.7 ${MOZHARNESS_PATH}/scripts/${MOZHARNESS_SCRIPT} ${config_cmds} ${@} \${@}\"
+echo \"Running: \${cmd}\"
+exec \${cmd}" > ${mozharness_bin}
+chmod +x ${mozharness_bin}
+
+# In interactive mode, the user will be prompted with options for what to do.
+if ! $TASKCLUSTER_INTERACTIVE; then
+ # run the given mozharness script and configs, but pass the rest of the
+ # arguments in from our own invocation
+ ${mozharness_bin};
+fi