def BuildScriptX86(status, context):
  # Clean out build directories.
  with Step('clobber', status):
    RemoveSconsBuildDirectories()
    RemoveGypBuildDirectories()

  # Unlike their arm counterparts we do not run trusted tests on x86 bots.
  # Trusted tests get plenty of coverage by other bots, e.g. nacl-gcc bots.
  # We make the assumption here that there are no "exotic tests" which
  # are trusted in nature but are somehow depedent on the untrusted TC.
  flags_build = ['skip_trusted_tests=1', 'do_not_run_tests=1']
  flags_run = ['skip_trusted_tests=1']
  smoke_tests = ['small_tests', 'medium_tests']

  with Step('build_all', status):
    SCons(context, parallel=True, args=flags_build)

  # Normal pexe-mode tests
  with Step('smoke_tests', status, halt_on_fail=False):
    SCons(context, parallel=True, args=flags_run + smoke_tests)
  # Large tests cannot be run in parallel
  with Step('large_tests', status, halt_on_fail=False):
    SCons(context, parallel=False, args=flags_run + ['large_tests'])

  # non-pexe-mode tests. Build everything to make sure it all builds in nonpexe
  # mode, but just run the nonpexe_tests
  with Step('build_nonpexe', status):
    SCons(context, parallel=True, args=flags_build + ['pnacl_generate_pexe=0'])
  with Step('nonpexe_tests', status, halt_on_fail=False):
    SCons(context, parallel=True,
          args=flags_run + ['pnacl_generate_pexe=0', 'nonpexe_tests'])

  irt_mode = context['default_scons_mode'] + ['nacl_irt_test']
  smoke_tests_irt = ['small_tests_irt', 'medium_tests_irt']
  # Run some tests with the IRT
  with Step('smoke_tests_irt', status, halt_on_fail=False):
    SCons(context, parallel=True, mode=irt_mode,
          args=flags_run + smoke_tests_irt)

  # Test sandboxed translation
  with Step('smoke_tests_sandboxed_translator', status):
    SCons(context, parallel=True, mode=irt_mode,
          args=flags_run + ['use_sandboxed_translator=1'] + smoke_tests_irt)
  with Step('smoke_tests_sandboxed_fast', status):
    SCons(context, parallel=True, mode=irt_mode,
          args=flags_run + ['use_sandboxed_translator=1', 'translate_fast=1']
          + smoke_tests_irt)

  # Translator memory consumption regression test
  with Step('large_code_test', status):
    SCons(context, parallel=True, mode=irt_mode,
          args=flags_run + ['use_sandboxed_translator=1', 'large_code'])
示例#2
0
def BuildScript(status, context):
    inside_toolchain = context['inside_toolchain']

    # Clean out build directories.
    with Step('clobber', status):
        RemoveSconsBuildDirectories()
        RemoveGypBuildDirectories()

    with Step('cleanup_temp', status):
        # Picking out drive letter on which the build is happening so we can use
        # it for the temp directory.
        if context.Windows():
            build_drive = os.path.splitdrive(os.path.abspath(__file__))[0]
            tmp_dir = os.path.join(build_drive, os.path.sep + 'temp')
            context.SetEnv('TEMP', tmp_dir)
            context.SetEnv('TMP', tmp_dir)
        else:
            tmp_dir = '/tmp'
        print 'Making sure %s exists...' % tmp_dir
        EnsureDirectoryExists(tmp_dir)
        print 'Cleaning up the contents of %s...' % tmp_dir
        # Only delete files and directories like:
        # a) C:\temp\83C4.tmp
        # b) /tmp/.org.chromium.Chromium.EQrEzl
        file_name_re = re.compile(
            r'[\\/]([0-9a-fA-F]+\.tmp|\.org\.chrom\w+\.Chrom\w+\..+)$')
        file_name_filter = lambda fn: file_name_re.search(fn) is not None
        TryToCleanContents(tmp_dir, file_name_filter)

        # Mac has an additional temporary directory; clean it up.
        # TODO(bradnelson): Fix Mac Chromium so that these temp files are created
        #     with open() + unlink() so that they will not get left behind.
        if context.Mac():
            subprocess.call(
                "find /var/folders -name '.org.chromium.*' -exec rm -rfv '{}' ';'",
                shell=True)
            subprocess.call(
                "find /var/folders -name '.com.google.Chrome*' -exec rm -rfv '{}' ';'",
                shell=True)

    # Skip over hooks when run inside the toolchain build because
    # download_toolchains would overwrite the toolchain build.
    if inside_toolchain:
        with Step('gyp_generate_only', status):
            CommandGypGenerate(context)
    else:
        with Step('gclient_runhooks', status):
            CommandGclientRunhooks(context)

    if context['clang']:
        with Step('update_clang', status):
            Command(context, cmd=['../tools/clang/scripts/update.sh'])

    # Just build both bitages of validator and test for --validator mode.
    if context['validator']:
        with Step('build ncval-x86-32', status):
            SCons(context, platform='x86-32', parallel=True, args=['ncval'])
        with Step('build ncval-x86-64', status):
            SCons(context, platform='x86-64', parallel=True, args=['ncval'])

        with Step('build ragel_validator-32', status):
            SCons(context,
                  platform='x86-32',
                  parallel=True,
                  args=['ncval_new'])
        with Step('build ragel_validator-64', status):
            SCons(context,
                  platform='x86-64',
                  parallel=True,
                  args=['ncval_new'])

        with Step('predownload validator corpus', status):
            Command(context,
                    cmd=[
                        sys.executable,
                        'tests/abi_corpus/validator_regression_test.py',
                        '--download-only'
                    ])

        with Step('validator_regression_test current x86-32',
                  status,
                  halt_on_fail=False):
            ValidatorTest(context, 'x86-32',
                          'scons-out/opt-linux-x86-32/staging/ncval')
        with Step('validator_regression_test current x86-64',
                  status,
                  halt_on_fail=False):
            ValidatorTest(context, 'x86-64',
                          'scons-out/opt-linux-x86-64/staging/ncval')

        with Step('validator_regression_test ragel x86-32',
                  status,
                  halt_on_fail=False):
            ValidatorTest(context, 'x86-32',
                          'scons-out/opt-linux-x86-32/staging/ncval_new')
        with Step('validator_regression_test ragel x86-64',
                  status,
                  halt_on_fail=False):
            ValidatorTest(context, 'x86-64',
                          'scons-out/opt-linux-x86-64/staging/ncval_new')

        with Step('validator_diff32_tests', status, halt_on_fail=False):
            SCons(context, platform='x86-32', args=['validator_diff_tests'])
        with Step('validator_diff64_tests', status, halt_on_fail=False):
            SCons(context, platform='x86-64', args=['validator_diff_tests'])
        return

    # Run checkdeps script to vet #includes.
    with Step('checkdeps', status):
        Command(context, cmd=[sys.executable, 'tools/checkdeps/checkdeps.py'])

    # Make sure our Gyp build is working.
    if not context['no_gyp']:
        with Step('gyp_compile', status):
            CommandGypBuild(context)

    # On a subset of Linux builds, build Breakpad tools for testing.
    if context['use_breakpad_tools']:
        with Step('breakpad configure', status):
            Command(context, cmd=['mkdir', '-p', 'breakpad-out'])
            Command(
                context,
                cwd='breakpad-out',
                cmd=['bash', '../../breakpad/configure',
                     'CXXFLAGS=-I../..'])  # For third_party/lss
        with Step('breakpad make', status):
            Command(context,
                    cmd=['make', '-j%d' % context['max_jobs']],
                    cwd='breakpad-out')

    # The main compile step.
    with Step('scons_compile', status):
        SCons(context, parallel=True, args=[])

    if context['coverage']:
        with Step('collect_coverage', status, halt_on_fail=True):
            SCons(context, args=['coverage'])
        with Step('summarize_coverage', status, halt_on_fail=False):
            SummarizeCoverage(context)
        slave_type = os.environ.get('BUILDBOT_SLAVE_TYPE')
        if slave_type != 'Trybot' and slave_type is not None:
            with Step('archive_coverage', status, halt_on_fail=True):
                ArchiveCoverage(context)
        return

    ### BEGIN tests ###
    with Step('small_tests', status, halt_on_fail=False):
        SCons(context, args=['small_tests'])
    with Step('medium_tests', status, halt_on_fail=False):
        SCons(context, args=['medium_tests'])
    with Step('large_tests', status, halt_on_fail=False):
        SCons(context, args=['large_tests'])

    with Step('compile IRT tests', status):
        SCons(context, parallel=True, mode=['nacl_irt_test'])

    with Step('small_tests under IRT', status, halt_on_fail=False):
        SCons(context,
              mode=context['default_scons_mode'] + ['nacl_irt_test'],
              args=['small_tests_irt'])
    with Step('medium_tests under IRT', status, halt_on_fail=False):
        SCons(context,
              mode=context['default_scons_mode'] + ['nacl_irt_test'],
              args=['medium_tests_irt'])

    ### END tests ###

    if not context['no_gyp']:
        # Build with ragel-based validator using GYP.
        gyp_defines_save = context.GetEnv('GYP_DEFINES')
        context.SetEnv('GYP_DEFINES',
                       ' '.join([gyp_defines_save, 'nacl_validator_ragel=0']))
        with Step('gyp_compile_noragel', status):
            # Clobber GYP build to recompile necessary files with new preprocessor macro
            # definitions.  It is done because some build systems (such as GNU Make,
            # MSBuild etc.) do not consider compiler arguments as a dependency.
            RemoveGypBuildDirectories()
            CommandGypGenerate(context)
            CommandGypBuild(context)
        context.SetEnv('GYP_DEFINES', gyp_defines_save)

    # Build with ragel-based validator using scons.
    with Step('scons_compile_noragel', status):
        SCons(context, parallel=True, args=['validator_ragel=0'])

    # Smoke tests for the R-DFA validator.
    with Step('validator_noragel_tests', status):
        args = [
            'validator_ragel=0',
            'small_tests',
            'medium_tests',
            'large_tests',
        ]
        # Add nacl_irt_test mode to be able to run run_hello_world_test_irt that
        # tests validation of the IRT.
        SCons(context,
              mode=context['default_scons_mode'] + ['nacl_irt_test'],
              args=args)
示例#3
0
def BuildScriptX86(status, context):
    # Clean out build directories.
    with Step('clobber', status):
        RemoveSconsBuildDirectories()
        RemoveGypBuildDirectories()

    # Unlike their arm counterparts we do not run trusted tests on x86 bots.
    # Trusted tests get plenty of coverage by other bots, e.g. nacl-gcc bots.
    # We make the assumption here that there are no "exotic tests" which
    # are trusted in nature but are somehow depedent on the untrusted TC.
    flags_build = ['skip_trusted_tests=1', 'do_not_run_tests=1']
    flags_run = ['skip_trusted_tests=1']
    smoke_tests = ['small_tests', 'medium_tests']

    with Step('build_all', status):
        SCons(context, parallel=True, args=flags_build)

    # Normal pexe-mode tests
    with Step('smoke_tests', status, halt_on_fail=False):
        SCons(context, parallel=True, args=flags_run + smoke_tests)
    # Large tests cannot be run in parallel
    with Step('large_tests', status, halt_on_fail=False):
        SCons(context, parallel=False, args=flags_run + ['large_tests'])

    # non-pexe-mode tests. Build everything to make sure it all builds in nonpexe
    # mode, but just run the nonpexe_tests
    with Step('build_nonpexe', status):
        SCons(context,
              parallel=True,
              args=flags_build + ['pnacl_generate_pexe=0'])
    with Step('nonpexe_tests', status, halt_on_fail=False):
        SCons(context,
              parallel=True,
              args=flags_run + ['pnacl_generate_pexe=0', 'nonpexe_tests'])

    irt_mode = context['default_scons_mode'] + ['nacl_irt_test']
    smoke_tests_irt = ['small_tests_irt', 'medium_tests_irt']
    # Run some tests with the IRT
    with Step('smoke_tests_irt', status, halt_on_fail=False):
        SCons(context,
              parallel=True,
              mode=irt_mode,
              args=flags_run + smoke_tests_irt)

    # Test sandboxed translation
    if not context.Windows():
        # TODO(dschuff): The standalone sandboxed translator driver does not have
        # the batch script wrappers, so it can't run on Windows. Either add them to
        # the translator package or make SCons use the pnacl_newlib drivers except
        # on the ARM bots where we don't have the pnacl_newlib drivers.
        with Step('smoke_tests_sandboxed_translator',
                  status,
                  halt_on_fail=False):
            SCons(context,
                  parallel=True,
                  mode=irt_mode,
                  args=flags_run + ['use_sandboxed_translator=1'] +
                  smoke_tests_irt)
        with Step('smoke_tests_sandboxed_fast', status, halt_on_fail=False):
            SCons(context,
                  parallel=True,
                  mode=irt_mode,
                  args=flags_run +
                  ['use_sandboxed_translator=1', 'translate_fast=1'] +
                  smoke_tests_irt)

        # Translator memory consumption regression test
        with Step('large_code_test', status, halt_on_fail=False):
            SCons(context,
                  parallel=True,
                  mode=irt_mode,
                  args=flags_run +
                  ['use_sandboxed_translator=1', 'large_code'])

    # Test Non-SFI Mode.
    # The only architectures that the PNaCl toolchain supports Non-SFI
    # versions of are currently x86-32 and ARM, and ARM testing is covered
    # by buildbot_pnacl.sh rather than this Python script.
    if context.Linux() and context['default_scons_platform'] == 'x86-32':
        with Step('nonsfi_tests', status, halt_on_fail=False):
            # TODO(mseaborn): Enable more tests here when they pass.
            SCons(context,
                  parallel=True,
                  mode=irt_mode,
                  args=flags_run +
                  ['nonsfi_nacl=1', 'run_hello_world_test_irt'])
示例#4
0
def BuildScript(status, context):
    inside_toolchain = context['inside_toolchain']

    # Clean out build directories.
    with Step('clobber', status):
        RemoveSconsBuildDirectories()
        RemoveGypBuildDirectories()

    with Step('cleanup_temp', status):
        # Picking out drive letter on which the build is happening so we can use
        # it for the temp directory.
        if context.Windows():
            build_drive = os.path.splitdrive(os.path.abspath(__file__))[0]
            tmp_dir = os.path.join(build_drive, os.path.sep + 'temp')
            context.SetEnv('TEMP', tmp_dir)
            context.SetEnv('TMP', tmp_dir)
        else:
            tmp_dir = '/tmp'
        print 'Making sure %s exists...' % tmp_dir
        EnsureDirectoryExists(tmp_dir)
        print 'Cleaning up the contents of %s...' % tmp_dir
        # Only delete files and directories like:
        #   */nacl_tmp/*
        # TODO(bradnelson): Drop this after a bit.
        # Also drop files and directories like these to cleanup current state:
        #   */nacl_tmp*
        #   */nacl*
        #   83C4.tmp
        #   .org.chromium.Chromium.EQrEzl
        #   tmp_platform*
        #   tmp_mmap*
        #   tmp_pwrite*
        #   tmp_syscalls*
        #   workdir*
        #   nacl_chrome_download_*
        #   browserprofile_*
        #   tmp*
        file_name_re = re.compile(r'[\\/\A]('
                                  r'tmp_nacl[\\/].+|'
                                  r'tmp_nacl.+|'
                                  r'nacl.+|'
                                  r'[0-9a-fA-F]+\.tmp|'
                                  r'\.org\.chrom\w+\.Chrom\w+\.[^\\/]+|'
                                  r'tmp_platform[^\\/]+|'
                                  r'tmp_mmap[^\\/]+|'
                                  r'tmp_pwrite[^\\/]+|'
                                  r'tmp_syscalls[^\\/]+|'
                                  r'workdir[^\\/]+|'
                                  r'nacl_chrome_download_[^\\/]+|'
                                  r'browserprofile_[^\\/]+|'
                                  r'tmp[^\\/]+'
                                  r')$')
        file_name_filter = lambda fn: file_name_re.search(fn) is not None

        # Clean nacl_tmp/* separately, so we get a list of leaks.
        nacl_tmp = os.path.join(tmp_dir, 'nacl_tmp')
        if os.path.exists(nacl_tmp):
            for bot in os.listdir(nacl_tmp):
                bot_path = os.path.join(nacl_tmp, bot)
                print 'Cleaning prior build temp dir: %s' % bot_path
                sys.stdout.flush()
                if os.path.isdir(bot_path):
                    for d in os.listdir(bot_path):
                        path = os.path.join(bot_path, d)
                        print 'Removing leftover: %s' % path
                        sys.stdout.flush()
                        RemovePath(path)
                    os.rmdir(bot_path)
                else:
                    print 'Removing rogue file: %s' % bot_path
                    RemovePath(bot_path)
            os.rmdir(nacl_tmp)
        # Clean /tmp so we get a list of what's accumulating.
        TryToCleanContents(tmp_dir, file_name_filter)

        # Recreate TEMP, as it may have been clobbered.
        if 'TEMP' in os.environ and not os.path.exists(os.environ['TEMP']):
            os.makedirs(os.environ['TEMP'])

        # Mac has an additional temporary directory; clean it up.
        # TODO(bradnelson): Fix Mac Chromium so that these temp files are created
        #     with open() + unlink() so that they will not get left behind.
        if context.Mac():
            subprocess.call(
                "find /var/folders -name '.org.chromium.*' -exec rm -rfv '{}' ';'",
                shell=True)
            subprocess.call(
                "find /var/folders -name '.com.google.Chrome*' -exec rm -rfv '{}' ';'",
                shell=True)

    # Always update Clang.  On Linux and Mac, it's the default for the GN build.
    # It's also used for the Linux Breakpad build. On Windows, we do a second
    # Clang GN build.
    with Step('update_clang', status):
        Command(context,
                cmd=[sys.executable, '../tools/clang/scripts/update.py'])

    # Make sure our GN build is working.
    using_gn = DoGNBuild(status, context)
    using_gn_clang = False
    if (context.Windows() and not context['clang']
            and context['arch'] in ('32', '64')):
        # On Windows, do a second GN build with is_clang=true.
        using_gn_clang = DoGNBuild(status, context, True)

    if context.Windows() and context['arch'] == '64':
        # On Windows, do a second pair of GN builds for 32-bit.  The 32-bit
        # bots can't do GN builds at all, because the toolchains GN uses don't
        # support 32-bit hosts.  The 32-bit binaries built here cannot be
        # tested on a 64-bit host, but compile time issues can be caught.
        DoGNBuild(status, context, False, '32')
        if not context['clang']:
            DoGNBuild(status, context, True, '32')

    # Just build both bitages of validator and test for --validator mode.
    if context['validator']:
        with Step('build ragel_validator-32', status):
            SCons(context,
                  platform='x86-32',
                  parallel=True,
                  args=['ncval_new'])
        with Step('build ragel_validator-64', status):
            SCons(context,
                  platform='x86-64',
                  parallel=True,
                  args=['ncval_new'])

        # Check validator trie proofs on both 32 + 64 bits.
        with Step('check validator proofs', status):
            SCons(context,
                  platform='x86-64',
                  parallel=False,
                  args=['dfachecktries'])

        with Step('predownload validator corpus', status):
            Command(context,
                    cmd=[
                        sys.executable,
                        'tests/abi_corpus/validator_regression_test.py',
                        '--download-only'
                    ])

        with Step('validator_regression_test ragel x86-32',
                  status,
                  halt_on_fail=False):
            ValidatorTest(context, 'x86-32',
                          'scons-out/opt-linux-x86-32/staging/ncval_new')
        with Step('validator_regression_test ragel x86-64',
                  status,
                  halt_on_fail=False):
            ValidatorTest(context, 'x86-64',
                          'scons-out/opt-linux-x86-64/staging/ncval_new')

        return

    # Run checkdeps script to vet #includes.
    with Step('checkdeps', status):
        Command(context, cmd=[sys.executable, 'tools/checkdeps/checkdeps.py'])

    # On a subset of Linux builds, build Breakpad tools for testing.
    if context['use_breakpad_tools']:
        with Step('breakpad configure', status):
            Command(context, cmd=['mkdir', '-p', 'breakpad-out'])

            # Breakpad requires C++11, so use clang and the sysroot rather than
            # hoping that the host toolchain will provide support.
            configure_args = []
            if context.Linux():
                cc = 'CC=../../third_party/llvm-build/Release+Asserts/bin/clang'
                cxx = 'CXX=../../third_party/llvm-build/Release+Asserts/bin/clang++'
                flags = ''
                if context['arch'] == '32':
                    flags += ' -m32'
                    sysroot_arch = 'i386'
                else:
                    flags += ' -m64'
                    sysroot_arch = 'amd64'
                flags += (
                    ' --sysroot=../../build/linux/debian_jessie_%s-sysroot' %
                    sysroot_arch)
                configure_args += [cc + flags, cxx + flags]
                configure_args += ['CXXFLAGS=-I../..']  # For third_party/lss
            Command(context,
                    cwd='breakpad-out',
                    cmd=['bash', '../../breakpad/configure'] + configure_args)

        with Step('breakpad make', status):
            Command(
                context,
                cmd=[
                    'make',
                    '-j%d' % context['max_jobs'],
                    # This avoids a broken dependency on
                    # src/third_party/lss files within the breakpad
                    # source directory.  We are not putting lss
                    # there, but using the -I switch above to
                    # find the lss in ../third_party instead.
                    'includelss_HEADERS=',
                ],
                cwd='breakpad-out')

    # The main compile step.
    with Step('scons_compile', status):
        SCons(context, parallel=True, args=[])

    if context['coverage']:
        with Step('collect_coverage', status, halt_on_fail=True):
            SCons(context, args=['coverage'])
        with Step('summarize_coverage', status, halt_on_fail=False):
            SummarizeCoverage(context)
        slave_type = os.environ.get('BUILDBOT_SLAVE_TYPE')
        if slave_type != 'Trybot' and slave_type is not None:
            with Step('archive_coverage', status, halt_on_fail=True):
                ArchiveCoverage(context)
        return

    # Android bots don't run tests for now.
    if context['android']:
        return

    ### BEGIN tests ###
    if not context['use_glibc']:
        # Bypassing the IRT with glibc is not a supported case,
        # and in fact does not work at all with the new glibc.
        with Step('small_tests', status, halt_on_fail=False):
            SCons(context, args=['small_tests'])
        with Step('medium_tests', status, halt_on_fail=False):
            SCons(context, args=['medium_tests'])
        with Step('large_tests', status, halt_on_fail=False):
            SCons(context, args=['large_tests'])

    with Step('compile IRT tests', status):
        SCons(context, parallel=True, mode=['nacl_irt_test'])

    with Step('small_tests under IRT', status, halt_on_fail=False):
        SCons(context,
              mode=context['default_scons_mode'] + ['nacl_irt_test'],
              args=['small_tests_irt'])
    with Step('medium_tests under IRT', status, halt_on_fail=False):
        SCons(context,
              mode=context['default_scons_mode'] + ['nacl_irt_test'],
              args=['medium_tests_irt'])
    with Step('large_tests under IRT', status, halt_on_fail=False):
        SCons(context,
              mode=context['default_scons_mode'] + ['nacl_irt_test'],
              args=['large_tests_irt'])
    ### END tests ###

    ### BEGIN GN tests ###
    DoGNTest(status, context, using_gn, 'gn_', ' (GN)')
    DoGNTest(status, context, using_gn_clang, 'gn_clang_', '(GN, Clang)')
示例#5
0
def RunSconsTests(status, context):
    # Clean out build directories, unless we have built elsewhere.
    if not context['skip_build']:
        with Step('clobber scons', status):
            RemoveSconsBuildDirectories()

    # Run checkdeps script to vet #includes.
    with Step('checkdeps', status):
        Command(context, cmd=[sys.executable, 'tools/checkdeps/checkdeps.py'])

    arch = context['default_scons_platform']

    flags_subzero = ['use_sz=1']
    flags_build = ['do_not_run_tests=1']
    flags_run = []

    # This file is run 3 different ways for ARM builds. The qemu-only trybot does
    # a normal build-and-run with the emulator just like the x86 bots. The panda
    # build side runs on an x86 machines with skip_run, and then packs up the
    # result and triggers an ARM hardware tester that run with skip_build
    if arch != 'arm':
        # Unlike their arm counterparts we do not run trusted tests on x86 bots.
        # Trusted tests get plenty of coverage by other bots, e.g. nacl-gcc bots.
        # We make the assumption here that there are no "exotic tests" which
        # are trusted in nature but are somehow depedent on the untrusted TC.
        flags_build.append('skip_trusted_tests=1')
        flags_run.append('skip_trusted_tests=1')

    if context['skip_run']:
        flags_run.append('do_not_run_tests=1')
        if arch == 'arm':
            # For ARM hardware bots, force_emulator= disables use of QEMU, which
            # enables building tests which don't work under QEMU.
            flags_build.append('force_emulator=')
            flags_run.append('force_emulator=')
    if context['skip_build']:
        flags_run.extend(['naclsdk_validate=0', 'built_elsewhere=1'])

    if not context['skip_build']:
        # For ARM builders which will trigger hardware testers, run the hello world
        # test with the emulator as a basic sanity check before doing anything else.
        if arch == 'arm' and context['skip_run']:
            with Step('hello_world ' + arch, status):
                SCons(context, parallel=True, args=['run_hello_world_test'])
        with Step('build_all ' + arch, status):
            SCons(context, parallel=True, args=flags_build)
        if arch in ('arm', 'x86-32', 'x86-64'):
            with Step('build_all subzero ' + arch, status):
                SCons(context, parallel=True, args=flags_build + flags_subzero)

    smoke_tests = ['small_tests', 'medium_tests']
    # Normal pexe-mode tests
    with Step('smoke_tests ' + arch, status, halt_on_fail=False):
        SCons(context, parallel=True, args=flags_run + smoke_tests)
    # Large tests cannot be run in parallel
    with Step('large_tests ' + arch, status, halt_on_fail=False):
        SCons(context, parallel=False, args=flags_run + ['large_tests'])
    # Run small_tests, medium_tests, and large_tests with Subzero.
    # TODO(stichnot): Move this to the sandboxed translator section
    # along with the translate_fast flag once pnacl-sz.nexe is ready.
    if arch in ('arm', 'x86-32', 'x86-64'):
        # Normal pexe-mode tests
        with Step('smoke_tests subzero ' + arch, status, halt_on_fail=False):
            SCons(context,
                  parallel=True,
                  args=flags_run + flags_subzero + smoke_tests)
        # Large tests cannot be run in parallel
        with Step('large_tests subzero ' + arch, status, halt_on_fail=False):
            SCons(context,
                  parallel=False,
                  args=flags_run + flags_subzero + ['large_tests'])

    with Step('nonpexe_tests ' + arch, status, halt_on_fail=False):
        SCons(context,
              parallel=True,
              args=flags_run + ['pnacl_generate_pexe=0', 'nonpexe_tests'])

    irt_mode = context['default_scons_mode'] + ['nacl_irt_test']
    # Build all the tests with the IRT
    if not context['skip_build']:
        with Step('build_all_irt ' + arch, status):
            SCons(context, parallel=True, mode=irt_mode, args=flags_build)
    smoke_tests_irt = ['small_tests_irt', 'medium_tests_irt']
    # Run tests with the IRT.
    with Step('smoke_tests_irt ' + arch, status, halt_on_fail=False):
        SCons(context,
              parallel=True,
              mode=irt_mode,
              args=flags_run + smoke_tests_irt)
    with Step('large_tests_irt ' + arch, status, halt_on_fail=False):
        SCons(context,
              parallel=False,
              mode=irt_mode,
              args=flags_run + ['large_tests_irt'])

    # Run some nacl_clang tests. Eventually we will have bots that just run
    # buildbot_standard with nacl_clang and this can be split out.
    context['pnacl'] = False
    context['nacl_clang'] = True
    if not context['skip_build']:
        with Step('build_nacl_clang ' + arch, status, halt_on_fail=False):
            SCons(context, parallel=True, args=flags_build)
    with Step('smoke_tests_nacl_clang ' + arch, status, halt_on_fail=False):
        SCons(context,
              parallel=True,
              args=flags_run + ['small_tests', 'medium_tests'])
    with Step('large_tests_nacl_clang ' + arch, status, halt_on_fail=False):
        SCons(context, parallel=False, args=flags_run + ['large_tests'])
    context['pnacl'] = True
    context['nacl_clang'] = False

    # Test sandboxed translation
    # TODO(dschuff): The standalone sandboxed translator driver does not have
    # the batch script wrappers, so it can't run on Windows. Either add them to
    # the translator package or make SCons use the pnacl_newlib drivers except
    # on the ARM bots where we don't have the pnacl_newlib drivers.
    # TODO(sbc): Enable these tests for mips once we build the version of the
    # translator nexe
    if not context.Windows() and arch != 'mips32':
        flags_run_sbtc = ['use_sandboxed_translator=1']
        sbtc_tests = ['toolchain_tests_irt']
        if arch == 'arm':
            # When splitting the build from the run, translate_in_build_step forces
            # the translation to run on the run side (it usually runs on the build
            # side because that runs with more parallelism)
            if context['skip_build'] or context['skip_run']:
                flags_run_sbtc.append('translate_in_build_step=0')
            else:
                # The ARM sandboxed translator is flaky under qemu, so run a very small
                # set of tests on the qemu-only trybot.
                sbtc_tests = ['run_hello_world_test_irt']
        else:
            sbtc_tests.append('large_code')

        with Step('sandboxed_translator_tests ' + arch,
                  status,
                  halt_on_fail=False):
            SCons(context,
                  parallel=True,
                  mode=irt_mode,
                  args=flags_run + flags_run_sbtc + sbtc_tests)
        with Step('sandboxed_translator_fast_tests ' + arch,
                  status,
                  halt_on_fail=False):
            SCons(context,
                  parallel=True,
                  mode=irt_mode,
                  args=flags_run + flags_run_sbtc + ['translate_fast=1'] +
                  sbtc_tests)

    # Test Non-SFI Mode.
    # The only architectures that the PNaCl toolchain supports Non-SFI
    # versions of are currently x86-32 and ARM.
    # The x86-64 toolchain bot currently also runs these tests from
    # buildbot_pnacl.sh
    if context.Linux() and (arch == 'x86-32' or arch == 'arm'):
        with Step('nonsfi_tests ' + arch, status, halt_on_fail=False):
            SCons(context,
                  parallel=True,
                  mode=irt_mode,
                  args=flags_run +
                  ['nonsfi_nacl=1', 'nonsfi_tests', 'nonsfi_tests_irt'])

        # Build with pnacl_generate_pexe=0 to allow using pnacl-clang with
        # direct-to-native mode. This allows assembly to be used in tests.
        with Step('nonsfi_tests_nopnacl_generate_pexe ' + arch,
                  status,
                  halt_on_fail=False):
            extra_args = [
                'nonsfi_nacl=1', 'pnacl_generate_pexe=0', 'nonsfi_tests',
                'nonsfi_tests_irt'
            ]
            # nonsfi_tests_irt with pnacl_generate_pexe=0 does not pass on x86-32.
            # https://code.google.com/p/nativeclient/issues/detail?id=4093
            if arch == 'x86-32':
                extra_args.remove('nonsfi_tests_irt')
            SCons(context,
                  parallel=True,
                  mode=irt_mode,
                  args=flags_run + extra_args)

        # Test nonsfi_loader linked against host's libc.
        with Step('nonsfi_tests_host_libc ' + arch, status,
                  halt_on_fail=False):
            # Using skip_nonstable_bitcode=1 here disables the tests for
            # zero-cost C++ exception handling, which don't pass for Non-SFI
            # mode yet because we don't build libgcc_eh for Non-SFI mode.
            SCons(context,
                  parallel=True,
                  mode=irt_mode,
                  args=flags_run + [
                      'nonsfi_nacl=1', 'use_newlib_nonsfi_loader=0',
                      'nonsfi_tests', 'nonsfi_tests_irt',
                      'toolchain_tests_irt', 'skip_nonstable_bitcode=1'
                  ])

    # Test unsandboxed mode.
    if (context.Linux() or context.Mac()) and arch == 'x86-32':
        if context.Linux():
            tests = [
                'run_' + test + '_test_irt' for test in [
                    'hello_world', 'irt_futex', 'thread', 'float',
                    'malloc_realloc_calloc_free', 'dup', 'cond_timedwait',
                    'getpid'
                ]
            ]
        else:
            # TODO(mseaborn): Use the same test list as on Linux when the threading
            # tests pass for Mac.
            tests = ['run_hello_world_test_irt']
        with Step('unsandboxed_tests ' + arch, status, halt_on_fail=False):
            SCons(context,
                  parallel=True,
                  mode=irt_mode,
                  args=flags_run + ['pnacl_unsandboxed=1'] + tests)