summaryrefslogtreecommitdiff
path: root/js/src/devtools/automation
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /js/src/devtools/automation
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/devtools/automation')
-rw-r--r--js/src/devtools/automation/arm64-jstests-slow.txt51
-rwxr-xr-xjs/src/devtools/automation/autospider.py406
-rwxr-xr-xjs/src/devtools/automation/autospider.sh3
-rw-r--r--js/src/devtools/automation/cgc-jittest-timeouts.txt47
-rw-r--r--js/src/devtools/automation/cgc-jstests-slow.txt62
-rw-r--r--js/src/devtools/automation/macbuildenv.sh14
-rw-r--r--js/src/devtools/automation/variants/arm-sim6
-rw-r--r--js/src/devtools/automation/variants/arm-sim-osx6
-rw-r--r--js/src/devtools/automation/variants/arm64-sim10
-rw-r--r--js/src/devtools/automation/variants/asan9
-rw-r--r--js/src/devtools/automation/variants/compacting14
-rw-r--r--js/src/devtools/automation/variants/dtrace5
-rw-r--r--js/src/devtools/automation/variants/msan13
-rw-r--r--js/src/devtools/automation/variants/nonunified10
-rw-r--r--js/src/devtools/automation/variants/plain7
-rw-r--r--js/src/devtools/automation/variants/plaindebug7
-rw-r--r--js/src/devtools/automation/variants/rootanalysis9
-rw-r--r--js/src/devtools/automation/variants/tsan13
-rw-r--r--js/src/devtools/automation/variants/warnaserr4
-rw-r--r--js/src/devtools/automation/variants/warnaserrdebug4
-rw-r--r--js/src/devtools/automation/winbuildenv.sh36
21 files changed, 736 insertions, 0 deletions
diff --git a/js/src/devtools/automation/arm64-jstests-slow.txt b/js/src/devtools/automation/arm64-jstests-slow.txt
new file mode 100644
index 0000000000..118097cdb8
--- /dev/null
+++ b/js/src/devtools/automation/arm64-jstests-slow.txt
@@ -0,0 +1,51 @@
+ecma/Date/15.9.5.10-2.js
+ecma/Date/15.9.5.11-2.js
+ecma/Date/15.9.5.12-2.js
+ecma/Date/15.9.5.8.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-01-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-02-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-03-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-04-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-05-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-06-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-07-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-08-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-09-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-10-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-11-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-12-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-13-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-14-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-15-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-16-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-17-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-18-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-19-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-20-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-21-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-22-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-23-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-24-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-25-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-26-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-27-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-30-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-31-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-32-of-32.js
+ecma_5/Object/15.2.3.6-middle-redefinition-1-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-2-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-3-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-4-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-5-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-6-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-7-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-8-of-8.js
+ecma_5/Object/15.2.3.6-redefinition-1-of-4.js
+ecma_5/Object/15.2.3.6-redefinition-2-of-4.js
+ecma_5/Object/15.2.3.6-redefinition-3-of-4.js
+ecma_5/Object/15.2.3.6-redefinition-4-of-4.js
+ecma_6/Comprehensions/sudoku.js
+js1_8_5/extensions/clone-complex-object.js
+js1_8_5/reflect-parse/classes.js
+js1_8_5/reflect-parse/destructuring-variable-declarations.js
+js1_8_5/regress/no-array-comprehension-length-limit.js
diff --git a/js/src/devtools/automation/autospider.py b/js/src/devtools/automation/autospider.py
new file mode 100755
index 0000000000..030d8c98d7
--- /dev/null
+++ b/js/src/devtools/automation/autospider.py
@@ -0,0 +1,406 @@
+#!/usr/bin/env python
+
+import argparse
+import json
+import logging
+import re
+import os
+import platform
+import posixpath
+import shutil
+import subprocess
+import sys
+
+from collections import Counter, namedtuple
+from os import environ as env
+from subprocess import Popen
+from threading import Timer
+
+Dirs = namedtuple('Dirs', ['scripts', 'js_src', 'source', 'tooltool'])
+
+
+def directories(pathmodule, cwd, fixup=lambda s: s):
+ scripts = pathmodule.join(fixup(cwd), fixup(pathmodule.dirname(__file__)))
+ js_src = pathmodule.abspath(pathmodule.join(scripts, "..", ".."))
+ source = pathmodule.abspath(pathmodule.join(js_src, "..", ".."))
+ tooltool = pathmodule.abspath(env.get('TOOLTOOL_CHECKOUT',
+ pathmodule.join(source, "..")))
+ return Dirs(scripts, js_src, source, tooltool)
+
+# Some scripts will be called with sh, which cannot use backslashed
+# paths. So for direct subprocess.* invocation, use normal paths from
+# DIR, but when running under the shell, use POSIX style paths.
+DIR = directories(os.path, os.getcwd())
+PDIR = directories(posixpath, os.environ["PWD"],
+ fixup=lambda s: re.sub(r'^(\w):', r'/\1', s))
+
+parser = argparse.ArgumentParser(
+ description='Run a spidermonkey shell build job')
+parser.add_argument('--dep', action='store_true',
+ help='do not clobber the objdir before building')
+parser.add_argument('--platform', '-p', type=str, metavar='PLATFORM',
+ default='', help='build platform, including a suffix ("-debug" or "") used by buildbot to override the variant\'s "debug" setting. The platform can be used to specify 32 vs 64 bits.')
+parser.add_argument('--timeout', '-t', type=int, metavar='TIMEOUT',
+ default=10800,
+ help='kill job after TIMEOUT seconds')
+parser.add_argument('--objdir', type=str, metavar='DIR',
+ default=env.get('OBJDIR', 'obj-spider'),
+ help='object directory')
+group = parser.add_mutually_exclusive_group()
+group.add_argument('--optimize', action='store_true',
+ help='generate an optimized build. Overrides variant setting.')
+group.add_argument('--no-optimize', action='store_false',
+ dest='optimize',
+ help='generate a non-optimized build. Overrides variant setting.')
+group.set_defaults(optimize=None)
+group = parser.add_mutually_exclusive_group()
+group.add_argument('--debug', action='store_true',
+ help='generate a debug build. Overrides variant setting.')
+group.add_argument('--no-debug', action='store_false',
+ dest='debug',
+ help='generate a non-debug build. Overrides variant setting.')
+group.set_defaults(debug=None)
+parser.add_argument('--run-tests', '--tests', type=str, metavar='TESTSUITE',
+ default='',
+ help="comma-separated set of test suites to add to the variant's default set")
+parser.add_argument('--skip-tests', '--skip', type=str, metavar='TESTSUITE',
+ default='',
+ help="comma-separated set of test suites to remove from the variant's default set")
+parser.add_argument('--build-only', '--build',
+ dest='skip_tests', action='store_const', const='all',
+ help="only do a build, do not run any tests")
+parser.add_argument('--nobuild', action='store_true',
+ help='Do not do a build. Rerun tests on existing build.')
+parser.add_argument('variant', type=str,
+ help='type of job requested, see variants/ subdir')
+args = parser.parse_args()
+
+
+def set_vars_from_script(script, vars):
+ '''Run a shell script, then dump out chosen environment variables. The build
+ system uses shell scripts to do some configuration that we need to
+ borrow. On Windows, the script itself must output the variable settings
+ (in the form "export FOO=<value>"), since otherwise there will be
+ problems with mismatched Windows/POSIX formats.
+ '''
+ script_text = 'source %s' % script
+ if platform.system() == 'Windows':
+ parse_state = 'parsing exports'
+ else:
+ script_text += '; echo VAR SETTINGS:; '
+ script_text += '; '.join('echo $' + var for var in vars)
+ parse_state = 'scanning'
+ stdout = subprocess.check_output(['sh', '-x', '-c', script_text])
+ tograb = vars[:]
+ originals = {}
+ for line in stdout.splitlines():
+ if parse_state == 'scanning':
+ if line == 'VAR SETTINGS:':
+ parse_state = 'grabbing'
+ elif parse_state == 'grabbing':
+ var = tograb.pop(0)
+ env[var] = line
+ elif parse_state == 'parsing exports':
+ m = re.match(r'export (\w+)=(.*)', line)
+ if m:
+ var, value = m.groups()
+ if var in tograb:
+ env[var] = value
+ print("Setting %s = %s" % (var, value))
+ if var.startswith("ORIGINAL_"):
+ originals[var[9:]] = value
+
+ # An added wrinkle: on Windows developer systems, the sourced script will
+ # blow away current settings for eg LIBS, to point to the ones that would
+ # be installed via automation. So we will append the original settings. (On
+ # an automation system, the original settings will be empty or point to
+ # nonexistent stuff.)
+ if platform.system() == 'Windows':
+ for var in vars:
+ if var in originals and len(originals[var]) > 0:
+ env[var] = "%s;%s" % (env[var], originals[var])
+
+
+def ensure_dir_exists(name, clobber=True):
+ if clobber:
+ shutil.rmtree(name, ignore_errors=True)
+ try:
+ os.mkdir(name)
+ except OSError:
+ if clobber:
+ raise
+
+with open(os.path.join(DIR.scripts, "variants", args.variant)) as fh:
+ variant = json.load(fh)
+
+if args.variant == 'nonunified':
+ # Rewrite js/src/**/moz.build to replace UNIFIED_SOURCES to SOURCES.
+ # Note that this modifies the current checkout.
+ for dirpath, dirnames, filenames in os.walk(DIR.js_src):
+ if 'moz.build' in filenames:
+ subprocess.check_call(['sed', '-i', 's/UNIFIED_SOURCES/SOURCES/',
+ os.path.join(dirpath, 'moz.build')])
+
+OBJDIR = os.path.join(DIR.source, args.objdir)
+OUTDIR = os.path.join(OBJDIR, "out")
+POBJDIR = posixpath.join(PDIR.source, args.objdir)
+AUTOMATION = env.get('AUTOMATION', False)
+MAKE = env.get('MAKE', 'make')
+MAKEFLAGS = env.get('MAKEFLAGS', '-j6')
+UNAME_M = subprocess.check_output(['uname', '-m']).strip()
+
+CONFIGURE_ARGS = variant['configure-args']
+
+opt = args.optimize
+if opt is None:
+ opt = variant.get('optimize')
+if opt is not None:
+ CONFIGURE_ARGS += (" --enable-optimize" if opt else " --disable-optimize")
+
+opt = args.debug
+if opt is None and args.platform:
+ # Override variant['debug'].
+ opt = ('-debug' in args.platform)
+if opt is None:
+ opt = variant.get('debug')
+if opt is not None:
+ CONFIGURE_ARGS += (" --enable-debug" if opt else " --disable-debug")
+
+# Any jobs that wish to produce additional output can save them into the upload
+# directory if there is such a thing, falling back to OBJDIR.
+env.setdefault('MOZ_UPLOAD_DIR', OBJDIR)
+ensure_dir_exists(env['MOZ_UPLOAD_DIR'], clobber=False)
+
+# Some of the variants request a particular word size (eg ARM simulators).
+word_bits = variant.get('bits')
+
+# On Linux and Windows, we build 32- and 64-bit versions on a 64 bit
+# host, so the caller has to specify what is desired.
+if word_bits is None and args.platform:
+ platform_arch = args.platform.split('-')[0]
+ if platform_arch in ('win32', 'linux'):
+ word_bits = 32
+ elif platform_arch in ('win64', 'linux64'):
+ word_bits = 64
+
+# Fall back to the word size of the host.
+if word_bits is None:
+ word_bits = 64 if UNAME_M == 'x86_64' else 32
+
+if 'compiler' in variant:
+ compiler = variant['compiler']
+elif platform.system() == 'Darwin':
+ compiler = 'clang'
+elif platform.system() == 'Windows':
+ compiler = 'cl'
+else:
+ compiler = 'gcc'
+
+cxx = {'clang': 'clang++', 'gcc': 'g++', 'cl': 'cl'}.get(compiler)
+
+compiler_dir = env.get('GCCDIR', os.path.join(DIR.tooltool, compiler))
+if os.path.exists(os.path.join(compiler_dir, 'bin', compiler)):
+ env.setdefault('CC', os.path.join(compiler_dir, 'bin', compiler))
+ env.setdefault('CXX', os.path.join(compiler_dir, 'bin', cxx))
+ platlib = 'lib64' if word_bits == 64 else 'lib'
+ env.setdefault('LD_LIBRARY_PATH', os.path.join(compiler_dir, platlib))
+else:
+ env.setdefault('CC', compiler)
+ env.setdefault('CXX', cxx)
+
+if platform.system() == 'Darwin':
+ os.environ['SOURCE'] = DIR.source
+ set_vars_from_script(os.path.join(DIR.scripts, 'macbuildenv.sh'),
+ ['CC', 'CXX'])
+elif platform.system() == 'Windows':
+ MAKE = env.get('MAKE', 'mozmake')
+ os.environ['SOURCE'] = DIR.source
+ if word_bits == 64:
+ os.environ['USE_64BIT'] = '1'
+ set_vars_from_script(posixpath.join(PDIR.scripts, 'winbuildenv.sh'),
+ ['PATH', 'INCLUDE', 'LIB', 'LIBPATH', 'CC', 'CXX',
+ 'WINDOWSSDKDIR'])
+
+# Compiler flags, based on word length
+if word_bits == 32:
+ if compiler == 'clang':
+ env['CC'] = '{CC} -arch i386'.format(**env)
+ env['CXX'] = '{CXX} -arch i386'.format(**env)
+ elif compiler == 'gcc':
+ env['CC'] = '{CC} -m32'.format(**env)
+ env['CXX'] = '{CXX} -m32'.format(**env)
+ env['AR'] = 'ar'
+
+# Configure flags, based on word length and cross-compilation
+if word_bits == 32:
+ if platform.system() == 'Windows':
+ CONFIGURE_ARGS += ' --target=i686-pc-mingw32 --host=i686-pc-mingw32'
+ elif platform.system() == 'Linux':
+ if UNAME_M != 'arm':
+ CONFIGURE_ARGS += ' --target=i686-pc-linux --host=i686-pc-linux'
+else:
+ if platform.system() == 'Windows':
+ CONFIGURE_ARGS += ' --target=x86_64-pc-mingw32 --host=x86_64-pc-mingw32'
+
+# Timeouts.
+ACTIVE_PROCESSES = set()
+
+
+def killall():
+ for proc in ACTIVE_PROCESSES:
+ proc.kill()
+ ACTIVE_PROCESSES.clear()
+
+timer = Timer(args.timeout, killall)
+timer.daemon = True
+timer.start()
+
+ensure_dir_exists(OBJDIR, clobber=not args.dep and not args.nobuild)
+ensure_dir_exists(OUTDIR)
+
+
+def run_command(command, check=False, **kwargs):
+ proc = Popen(command, cwd=OBJDIR, **kwargs)
+ ACTIVE_PROCESSES.add(proc)
+ stdout, stderr = None, None
+ try:
+ stdout, stderr = proc.communicate()
+ finally:
+ ACTIVE_PROCESSES.discard(proc)
+ status = proc.wait()
+ if check and status != 0:
+ raise subprocess.CalledProcessError(status, command, output=stderr)
+ return stdout, stderr, status
+
+# Add in environment variable settings for this variant. Normally used to
+# modify the flags passed to the shell or to set the GC zeal mode.
+for k, v in variant.get('env', {}).items():
+ env[k] = v.format(
+ DIR=DIR.scripts,
+ TOOLTOOL_CHECKOUT=DIR.tooltool,
+ MOZ_UPLOAD_DIR=env['MOZ_UPLOAD_DIR'],
+ OUTDIR=OUTDIR,
+ )
+
+if not args.nobuild:
+ CONFIGURE_ARGS += ' --enable-nspr-build'
+ CONFIGURE_ARGS += ' --prefix={OBJDIR}/dist'.format(OBJDIR=POBJDIR)
+
+ # Generate a configure script from configure.in.
+ configure = os.path.join(DIR.js_src, 'configure')
+ if not os.path.exists(configure):
+ shutil.copyfile(configure + ".in", configure)
+ os.chmod(configure, 0755)
+
+ # Run configure; make
+ run_command(['sh', '-c', posixpath.join(PDIR.js_src, 'configure') + ' ' + CONFIGURE_ARGS], check=True)
+ run_command('%s -s -w %s' % (MAKE, MAKEFLAGS), shell=True, check=True)
+
+COMMAND_PREFIX = []
+# On Linux, disable ASLR to make shell builds a bit more reproducible.
+if subprocess.call("type setarch >/dev/null 2>&1", shell=True) == 0:
+ COMMAND_PREFIX.extend(['setarch', UNAME_M, '-R'])
+
+
+def run_test_command(command, **kwargs):
+ _, _, status = run_command(COMMAND_PREFIX + command, check=False, **kwargs)
+ return status
+
+test_suites = set(['jstests', 'jittest', 'jsapitests', 'checks'])
+
+
+def normalize_tests(tests):
+ if 'all' in tests:
+ return test_suites
+ return tests
+
+# Need a platform name to use as a key in variant files.
+if args.platform:
+ variant_platform = args.platform.split("-")[0]
+elif platform.system() == 'Windows':
+ variant_platform = 'win64' if word_bits == 64 else 'win32'
+elif platform.system() == 'Linux':
+ variant_platform = 'linux64' if word_bits == 64 else 'linux'
+elif platform.system() == 'Darwin':
+ variant_platform = 'macosx64'
+else:
+ variant_platform = 'other'
+
+# Skip any tests that are not run on this platform (or the 'all' platform).
+test_suites -= set(normalize_tests(variant.get('skip-tests', {}).get(variant_platform, [])))
+test_suites -= set(normalize_tests(variant.get('skip-tests', {}).get('all', [])))
+
+# Add in additional tests for this platform (or the 'all' platform).
+test_suites |= set(normalize_tests(variant.get('extra-tests', {}).get(variant_platform, [])))
+test_suites |= set(normalize_tests(variant.get('extra-tests', {}).get('all', [])))
+
+# Now adjust the variant's default test list with command-line arguments.
+test_suites |= set(normalize_tests(args.run_tests.split(",")))
+test_suites -= set(normalize_tests(args.skip_tests.split(",")))
+
+# Always run all enabled tests, even if earlier ones failed. But return the
+# first failed status.
+results = []
+
+# 'checks' is a superset of 'check-style'.
+if 'checks' in test_suites:
+ results.append(run_test_command([MAKE, 'check']))
+elif 'check-style' in test_suites:
+ results.append(run_test_command([MAKE, 'check-style']))
+
+if 'jittest' in test_suites:
+ results.append(run_test_command([MAKE, 'check-jit-test']))
+if 'jsapitests' in test_suites:
+ jsapi_test_binary = os.path.join(OBJDIR, 'dist', 'bin', 'jsapi-tests')
+ results.append(run_test_command([jsapi_test_binary]))
+if 'jstests' in test_suites:
+ results.append(run_test_command([MAKE, 'check-jstests']))
+
+# FIXME bug 1291449: This would be unnecessary if we could run msan with -mllvm
+# -msan-keep-going, but in clang 3.8 it causes a hang during compilation.
+if variant.get('ignore-test-failures'):
+ print("Ignoring test results %s" % (results,))
+ results = [0]
+
+if args.variant in ('tsan', 'msan'):
+ files = filter(lambda f: f.startswith("sanitize_log."), os.listdir(OUTDIR))
+ fullfiles = [os.path.join(OUTDIR, f) for f in files]
+
+ # Summarize results
+ sites = Counter()
+ for filename in fullfiles:
+ with open(os.path.join(OUTDIR, filename), 'rb') as fh:
+ for line in fh:
+ m = re.match(r'^SUMMARY: \w+Sanitizer: (?:data race|use-of-uninitialized-value) (.*)',
+ line.strip())
+ if m:
+ # Some reports include file:line:column, some just
+ # file:line. Just in case it's nondeterministic, we will
+ # canonicalize to just the line number.
+ site = re.sub(r'^(\S+?:\d+)(:\d+)* ', r'\1 ', m.group(1))
+ sites[site] += 1
+
+ # Write a summary file and display it to stdout.
+ summary_filename = os.path.join(env['MOZ_UPLOAD_DIR'], "%s_summary.txt" % args.variant)
+ with open(summary_filename, 'wb') as outfh:
+ for location, count in sites.most_common():
+ print >> outfh, "%d %s" % (count, location)
+ print(open(summary_filename, 'rb').read())
+
+ if 'max-errors' in variant:
+ print("Found %d errors out of %d allowed" % (len(sites), variant['max-errors']))
+ if len(sites) > variant['max-errors']:
+ results.append(1)
+
+ # Gather individual results into a tarball. Note that these are
+ # distinguished only by pid of the JS process running within each test, so
+ # given the 16-bit limitation of pids, it's totally possible that some of
+ # these files will be lost due to being overwritten.
+ command = ['tar', '-C', OUTDIR, '-zcf',
+ os.path.join(env['MOZ_UPLOAD_DIR'], '%s.tar.gz' % args.variant)]
+ command += files
+ subprocess.call(command)
+
+for st in results:
+ if st != 0:
+ sys.exit(st)
diff --git a/js/src/devtools/automation/autospider.sh b/js/src/devtools/automation/autospider.sh
new file mode 100755
index 0000000000..f6e302bf60
--- /dev/null
+++ b/js/src/devtools/automation/autospider.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+exec python2.7 "$(dirname $0)/autospider.py" "$@"
diff --git a/js/src/devtools/automation/cgc-jittest-timeouts.txt b/js/src/devtools/automation/cgc-jittest-timeouts.txt
new file mode 100644
index 0000000000..84e29f8931
--- /dev/null
+++ b/js/src/devtools/automation/cgc-jittest-timeouts.txt
@@ -0,0 +1,47 @@
+SIMD/nursery-overflow.js
+asm.js/testParallelCompile.js
+auto-regress/bug653395.js
+auto-regress/bug654392.js
+auto-regress/bug675251.js
+auto-regress/bug729797.js
+baseline/bug847446.js
+baseline/bug852175.js
+basic/bug632964-regexp.js
+basic/bug656261.js
+basic/bug677957-2.js
+basic/bug753283.js
+basic/bug867946.js
+basic/testAtomize.js
+basic/testBug614653.js
+basic/testBug686274.js
+basic/testManyVars.js
+basic/testTypedArrayInit.js
+debug/DebuggeeWouldRun-01.js
+debug/DebuggeeWouldRun-02.js
+gc/bug-1014972.js
+gc/bug-1246593.js
+gc/bug-906236.js
+gc/bug-906241.js
+ion/bug1197769.js
+ion/bug779245.js
+ion/bug787921.js
+ion/bug977966.js
+ion/close-iterators-1.js
+parallel/alloc-many-objs.js
+parallel/alloc-too-many-objs.js
+parser/bug-1263881-1.js
+parser/bug-1263881-2.js
+parser/bug-1263881-3.js
+parser/modifier-yield-without-operand-2.js
+saved-stacks/bug-1006876-too-much-recursion.js
+self-test/assertDeepEq.js
+sunspider/check-string-unpack-code.js
+v8-v5/check-earley-boyer.js
+v8-v5/check-raytrace.js
+v8-v5/check-regexp.js
+v8-v5/check-splay.js
+wasm/spec/f32.wast.js
+wasm/spec/f32_cmp.wast.js
+wasm/spec/f64.wast.js
+wasm/spec/f64_cmp.wast.js
+wasm/spec/float_exprs.wast.js
diff --git a/js/src/devtools/automation/cgc-jstests-slow.txt b/js/src/devtools/automation/cgc-jstests-slow.txt
new file mode 100644
index 0000000000..814ad338e5
--- /dev/null
+++ b/js/src/devtools/automation/cgc-jstests-slow.txt
@@ -0,0 +1,62 @@
+ecma_5/Object/15.2.3.6-dictionary-redefinition-01-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-02-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-03-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-04-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-05-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-06-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-07-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-08-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-09-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-10-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-11-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-12-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-13-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-14-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-15-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-16-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-17-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-18-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-19-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-20-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-21-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-22-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-23-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-24-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-25-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-26-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-27-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-28-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-29-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-30-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-31-of-32.js
+ecma_5/Object/15.2.3.6-dictionary-redefinition-32-of-32.js
+ecma_5/Object/15.2.3.6-middle-redefinition-1-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-2-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-3-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-4-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-5-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-6-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-7-of-8.js
+ecma_5/Object/15.2.3.6-middle-redefinition-8-of-8.js
+ecma_5/Object/15.2.3.6-redefinition-1-of-4.js
+ecma_5/Object/15.2.3.6-redefinition-2-of-4.js
+ecma_5/Object/15.2.3.6-redefinition-3-of-4.js
+ecma_5/Object/15.2.3.6-redefinition-4-of-4.js
+ecma_6/String/normalize-generateddata-part0.js
+ecma_6/String/normalize-generateddata-part1-not-listed.js
+ecma_6/String/normalize-generateddata-part1.js
+ecma_6/String/normalize-generateddata-part2.js
+ecma_6/String/normalize-generateddata-part3.js
+js1_5/GC/regress-203278-2.js
+js1_5/GC/regress-203278-3.js
+js1_5/GC/regress-278725.js
+js1_5/Regress/regress-312588.js
+js1_5/Regress/regress-321971.js
+js1_5/Regress/regress-360969-01.js
+js1_5/Regress/regress-360969-02.js
+js1_5/Regress/regress-360969-03.js
+js1_5/Regress/regress-360969-04.js
+js1_5/Regress/regress-360969-05.js
+js1_5/Regress/regress-360969-06.js
+js1_8_5/extensions/clone-complex-object.js
+js1_8_5/extensions/clone-object-deep.js
diff --git a/js/src/devtools/automation/macbuildenv.sh b/js/src/devtools/automation/macbuildenv.sh
new file mode 100644
index 0000000000..df0f57fdba
--- /dev/null
+++ b/js/src/devtools/automation/macbuildenv.sh
@@ -0,0 +1,14 @@
+# We will be sourcing mozconfig files, which end up calling mk_add_options and
+# ac_add_options with various settings. We only need the variable settings they
+# create along the way.
+mk_add_options() {
+ : do nothing
+}
+ac_add_options() {
+ : do nothing
+}
+
+topsrcdir="$SOURCE"
+
+# Setup CC and CXX variables
+. $topsrcdir/build/macosx/mozconfig.common
diff --git a/js/src/devtools/automation/variants/arm-sim b/js/src/devtools/automation/variants/arm-sim
new file mode 100644
index 0000000000..20963b235a
--- /dev/null
+++ b/js/src/devtools/automation/variants/arm-sim
@@ -0,0 +1,6 @@
+{
+ "configure-args": "--enable-stdcxx-compat --enable-simulator=arm --target=i686-pc-linux --host=i686-pc-linux",
+ "optimize": true,
+ "debug": true,
+ "bits": 32
+}
diff --git a/js/src/devtools/automation/variants/arm-sim-osx b/js/src/devtools/automation/variants/arm-sim-osx
new file mode 100644
index 0000000000..af193fc16f
--- /dev/null
+++ b/js/src/devtools/automation/variants/arm-sim-osx
@@ -0,0 +1,6 @@
+{
+ "configure-args": "--enable-stdcxx-compat --enable-simulator=arm --target=i686-apple-darwin10.0.0 --host=i686-apple-darwin10.0.0",
+ "optimize": true,
+ "debug": true,
+ "bits": 32
+}
diff --git a/js/src/devtools/automation/variants/arm64-sim b/js/src/devtools/automation/variants/arm64-sim
new file mode 100644
index 0000000000..6874f441cf
--- /dev/null
+++ b/js/src/devtools/automation/variants/arm64-sim
@@ -0,0 +1,10 @@
+{
+ "configure-args": "--enable-stdcxx-compat --enable-simulator=arm64",
+ "optimize": true,
+ "debug": true,
+ "env": {
+ "JSTESTS_EXTRA_ARGS": "--exclude-file={DIR}/arm64-jstests-slow.txt",
+ "JITTEST_EXTRA_ARGS": "--jitflags=none --args=--baseline-eager -x ion/ -x asm.js/"
+ },
+ "bits": 64
+}
diff --git a/js/src/devtools/automation/variants/asan b/js/src/devtools/automation/variants/asan
new file mode 100644
index 0000000000..1c791eb504
--- /dev/null
+++ b/js/src/devtools/automation/variants/asan
@@ -0,0 +1,9 @@
+{
+ "configure-args": "--enable-debug-symbols='-gline-tables-only' --disable-jemalloc --enable-address-sanitizer",
+ "optimize": true,
+ "debug": false,
+ "compiler": "clang",
+ "env": {
+ "LLVM_SYMBOLIZER": "{TOOLTOOL_CHECKOUT}/clang/bin/llvm-symbolizer"
+ }
+}
diff --git a/js/src/devtools/automation/variants/compacting b/js/src/devtools/automation/variants/compacting
new file mode 100644
index 0000000000..cd1891bfe4
--- /dev/null
+++ b/js/src/devtools/automation/variants/compacting
@@ -0,0 +1,14 @@
+{
+ "configure-args": "--enable-stdcxx-compat --enable-ctypes",
+ "optimize": true,
+ "debug": true,
+ "env": {
+ "JS_GC_ZEAL": "Compact",
+ "JITTEST_EXTRA_ARGS": "--jitflags=debug --ignore-timeouts={DIR}/cgc-jittest-timeouts.txt",
+ "JSTESTS_EXTRA_ARGS": "--exclude-file={DIR}/cgc-jstests-slow.txt"
+ },
+ "skip-tests": {
+ "win32": ["jstests"],
+ "win64": ["jstests"]
+ }
+}
diff --git a/js/src/devtools/automation/variants/dtrace b/js/src/devtools/automation/variants/dtrace
new file mode 100644
index 0000000000..4633de2e2d
--- /dev/null
+++ b/js/src/devtools/automation/variants/dtrace
@@ -0,0 +1,5 @@
+{
+ "configure-args": "--enable-dtrace --enable-debug-symbols",
+ "optimize": true,
+ "debug": true,
+}
diff --git a/js/src/devtools/automation/variants/msan b/js/src/devtools/automation/variants/msan
new file mode 100644
index 0000000000..ccf2c75f28
--- /dev/null
+++ b/js/src/devtools/automation/variants/msan
@@ -0,0 +1,13 @@
+{
+ "configure-args": "--enable-debug-symbols='-gline-tables-only' --disable-jemalloc --enable-memory-sanitizer",
+ "optimize": true,
+ "debug": false,
+ "compiler": "clang",
+ "env": {
+ "JITTEST_EXTRA_ARGS": "--jitflags=interp --ignore-timeouts={DIR}/cgc-jittest-timeouts.txt",
+ "JSTESTS_EXTRA_ARGS": "--jitflags=interp --exclude-file={DIR}/cgc-jstests-slow.txt",
+ "MSAN_OPTIONS": "external_symbolizer_path={TOOLTOOL_CHECKOUT}/clang/bin/llvm-symbolizer:log_path={OUTDIR}/sanitize_log"
+ },
+ "ignore-test-failures": "true",
+ "max-errors": 2
+}
diff --git a/js/src/devtools/automation/variants/nonunified b/js/src/devtools/automation/variants/nonunified
new file mode 100644
index 0000000000..306c00ea83
--- /dev/null
+++ b/js/src/devtools/automation/variants/nonunified
@@ -0,0 +1,10 @@
+{
+ "configure-args": "--enable-warnings-as-errors",
+ "debug": true,
+ "skip-tests": {
+ "all": ["jstests", "jittest", "checks"]
+ },
+ "extra-tests": {
+ "all": ["check-style"]
+ }
+}
diff --git a/js/src/devtools/automation/variants/plain b/js/src/devtools/automation/variants/plain
new file mode 100644
index 0000000000..ab954074d4
--- /dev/null
+++ b/js/src/devtools/automation/variants/plain
@@ -0,0 +1,7 @@
+{
+ "configure-args": "",
+ "optimize": true,
+ "env": {
+ "JSTESTS_EXTRA_ARGS": "--jitflags=all"
+ }
+}
diff --git a/js/src/devtools/automation/variants/plaindebug b/js/src/devtools/automation/variants/plaindebug
new file mode 100644
index 0000000000..e98a3cdbd0
--- /dev/null
+++ b/js/src/devtools/automation/variants/plaindebug
@@ -0,0 +1,7 @@
+{
+ "configure-args": "",
+ "debug": true,
+ "env": {
+ "JSTESTS_EXTRA_ARGS": "--jitflags=debug"
+ }
+}
diff --git a/js/src/devtools/automation/variants/rootanalysis b/js/src/devtools/automation/variants/rootanalysis
new file mode 100644
index 0000000000..c5ed4dfcd1
--- /dev/null
+++ b/js/src/devtools/automation/variants/rootanalysis
@@ -0,0 +1,9 @@
+{
+ "configure-args": "--enable-stdcxx-compat --enable-ctypes",
+ "optimize": true,
+ "debug": true,
+ "env": {
+ "JS_GC_ZEAL": "GenerationalGC",
+ "JSTESTS_EXTRA_ARGS": "--jitflags=debug"
+ }
+}
diff --git a/js/src/devtools/automation/variants/tsan b/js/src/devtools/automation/variants/tsan
new file mode 100644
index 0000000000..f831a5b041
--- /dev/null
+++ b/js/src/devtools/automation/variants/tsan
@@ -0,0 +1,13 @@
+{
+ "configure-args": "--enable-debug-symbols='-gline-tables-only' --disable-jemalloc --enable-thread-sanitizer",
+ "optimize": true,
+ "debug": false,
+ "compiler": "clang",
+ "env": {
+ "LLVM_SYMBOLIZER": "{TOOLTOOL_CHECKOUT}/clang/bin/llvm-symbolizer",
+ "JITTEST_EXTRA_ARGS": "--jitflags=debug --ignore-timeouts={DIR}/cgc-jittest-timeouts.txt",
+ "JSTESTS_EXTRA_ARGS": "--exclude-file={DIR}/cgc-jstests-slow.txt",
+ "TSAN_OPTIONS": "log_path={OUTDIR}/sanitize_log"
+ },
+ "max-errors": 14
+}
diff --git a/js/src/devtools/automation/variants/warnaserr b/js/src/devtools/automation/variants/warnaserr
new file mode 100644
index 0000000000..a5f4e0e7ce
--- /dev/null
+++ b/js/src/devtools/automation/variants/warnaserr
@@ -0,0 +1,4 @@
+{
+ "configure-args": "--enable-warnings-as-errors",
+ "optimize": true
+}
diff --git a/js/src/devtools/automation/variants/warnaserrdebug b/js/src/devtools/automation/variants/warnaserrdebug
new file mode 100644
index 0000000000..ca1f14fef1
--- /dev/null
+++ b/js/src/devtools/automation/variants/warnaserrdebug
@@ -0,0 +1,4 @@
+{
+ "configure-args": "--enable-warnings-as-errors",
+ "debug": true
+}
diff --git a/js/src/devtools/automation/winbuildenv.sh b/js/src/devtools/automation/winbuildenv.sh
new file mode 100644
index 0000000000..f9d862ac45
--- /dev/null
+++ b/js/src/devtools/automation/winbuildenv.sh
@@ -0,0 +1,36 @@
+# We will be sourcing mozconfig files, which end up calling mk_add_options with
+# various settings. We only need the variable settings they create along the
+# way. Print them out, to be sucked up when running this file.
+mk_add_options() {
+ echo "$@"
+}
+
+topsrcdir="$SOURCE"
+
+# Tooltool installs in parent of topsrcdir for spidermonkey builds.
+# Resolve that path since the mozconfigs assume tooltool installs in
+# topsrcdir.
+VSPATH="$(cd ${topsrcdir}/.. && pwd)/vs2015u3"
+
+# When running on a developer machine, several variables will already
+# have the right settings and we will need to keep them since the
+# Windows mozconfigs overwrite them.
+echo "export ORIGINAL_INCLUDE=$INCLUDE"
+echo "export ORIGINAL_LIB=$LIB"
+echo "export ORIGINAL_LIBPATH=$LIBPATH"
+
+if [ -n "$USE_64BIT" ]; then
+ . $topsrcdir/build/win64/mozconfig.vs-latest
+else
+ . $topsrcdir/build/win32/mozconfig.vs-latest
+fi
+
+# PATH also needs to point to mozmake.exe, which can come from either
+# newer mozilla-build or tooltool.
+if ! which mozmake 2>/dev/null; then
+ export PATH="$PATH:$SOURCE/.."
+ if ! which mozmake 2>/dev/null; then
+ TT_SERVER=${TT_SERVER:-https://api.pub.build.mozilla.org/tooltool/}
+ ( cd $SOURCE/..; ./scripts/scripts/tooltool/tooltool_wrapper.sh $SOURCE/browser/config/tooltool-manifests/${platform:-win32}/releng.manifest $TT_SERVER setup.sh c:/mozilla-build/python27/python.exe C:/mozilla-build/tooltool.py )
+ fi
+fi