| # Copyright 2014 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Buildbot recipe definition for the various Crashpad continuous builders. |
| """ |
| |
| import ast |
| import contextlib |
| |
| from recipe_engine.recipe_api import Property |
| |
| DEPS = [ |
| 'recipe_engine/context', |
| 'recipe_engine/file', |
| 'recipe_engine/json', |
| 'recipe_engine/path', |
| 'recipe_engine/platform', |
| 'recipe_engine/properties', |
| 'recipe_engine/python', |
| 'recipe_engine/runtime', |
| 'recipe_engine/step', |
| |
| 'depot_tools/bot_update', |
| 'depot_tools/depot_tools', |
| 'depot_tools/gclient', |
| 'depot_tools/osx_sdk', |
| 'depot_tools/windows_sdk', |
| ] |
| |
| PROPERTIES = { |
| 'buildername': Property(kind=str, help='The builder name', default=None), |
| 'config': Property(kind=str, help='Debug or Release', default='Debug'), |
| 'target_os': |
| Property(kind=str, help='win, mac, linux, or fuchsia', default=None), |
| 'target_cpu': Property(kind=str, help='x64, arm64, or ""', default=''), |
| } |
| |
| FAKE_SWARMING_TEST_SPEC = """\ |
| [ |
| { |
| 'builders': ['crashpad_try_win_dbg'], |
| 'step_name': 'run_tests_on_x86', |
| 'isolate': 'out/Debug/run_tests.isolate', |
| 'args': [ |
| '-d', 'os', 'Windows-7', |
| '-d', 'os', 'x86-32', |
| '-d', 'os', 'Chrome', |
| ], |
| }, |
| ] |
| """ |
| |
| def RunSteps(api, buildername, config, target_os, target_cpu): |
| """Generates the sequence of steps that will be run by the slave.""" |
| api.gclient.set_config('crashpad') |
| |
| env = {} |
| |
| is_fuchsia = is_linux = is_mac = is_win = False |
| if target_os == 'fuchsia': |
| is_fuchsia = True |
| elif target_os == 'linux': |
| is_linux = True |
| elif target_os == 'mac': |
| is_mac = True |
| elif target_os == 'win': |
| is_win = True |
| |
| assert is_fuchsia or is_linux or is_mac or is_win |
| |
| @contextlib.contextmanager |
| def sdk(os, arch='x64'): |
| if os == 'mac': |
| with api.osx_sdk('mac'): |
| yield |
| elif os == 'win': |
| assert arch in ('x86', 'x64') |
| with api.windows_sdk(target_arch=arch): |
| yield |
| else: |
| yield |
| |
| api.gclient.c.target_os = {target_os} |
| |
| is_debug = config == 'Debug' |
| |
| if is_linux: |
| # The Linux build uses the system compiler by default, but bots do not |
| # have a clang installed by default, so use a local copy. Setting this |
| # variable causes DEPS to download a clang cipd package in runhooks. See |
| # also the setting of clang_path below. |
| api.gclient.c.solutions[0].custom_vars['pull_linux_clang'] = True |
| |
| api.bot_update.ensure_checkout() |
| |
| # buildbot sets 'clobber' to the empty string which is falsey, check with |
| # 'in' |
| if 'clobber' in api.properties: |
| api.file.rmtree('out', api.path['checkout'].join('out')) |
| |
| with api.context(env=env): |
| api.gclient.runhooks() |
| |
| dirname = config |
| if is_fuchsia or is_linux or is_mac: |
| gn = api.path['start_dir'].join( |
| 'buildtools', 'mac' if is_mac else 'linux64', 'gn') |
| # Generic GN build. |
| path = api.path['checkout'].join('out', dirname) |
| if target_cpu is "": |
| target_cpu = 'x64' |
| args = ( |
| 'target_os="' + target_os + '" target_cpu="' + target_cpu + '"' + |
| ' is_debug=' + ('true' if is_debug else 'false')) |
| if is_linux: |
| # Point at the local copy of clang and a sysroot that were downloaded by |
| # gclient runhooks. |
| args += ' clang_path="//third_party/linux/clang/linux-amd64"' |
| args += ' target_sysroot="//third_party/linux/sysroot"' |
| |
| # The 14.04 systems do not include a compatible libstdc++ that can deal |
| # with -std=c++14, so force static linkage of libstdc++ from the |
| # sysroot. |
| args += ' link_libstdcpp_statically = true' |
| with api.context(cwd=api.path['checkout']): |
| with sdk(target_os): |
| api.step('generate build files', [gn, 'gen', path, '--args=' + args]) |
| elif is_win: |
| gn = api.path['start_dir'].join('buildtools', 'win', 'gn.exe') |
| # On Windows, we ought to test: |
| # a) x64 OS, x64 handler, x64 client |
| # b) x64 OS, x64 handler, x86 client |
| # c) x64 OS, x86 handler, x86 client |
| # d) x86 OS, x86 handler, x86 client |
| # |
| # d) used to be tested on _x86 bots, but they have been removed. |
| # |
| # Two build directories are generated, one for x86 and one for x64, which |
| # allows testing a), b), and c). As the bot time is dominated by machine |
| # setup and build time, we do not separate these onto separate slaves. |
| # Additionally, they're all on the same physical machine currently, so |
| # there's no upside in parallelism. |
| |
| x86_path = api.path['checkout'].join('out', dirname + '_x86') |
| x64_path = api.path['checkout'].join('out', dirname + '_x64') |
| args = 'target_os="win" is_debug=' + ('true' if is_debug else 'false') |
| with api.context(cwd=api.path['checkout']): |
| with sdk(target_os, 'x86'): |
| api.step('generate build files x86', |
| [gn, 'gen', x86_path, '--args=' + args + ' target_cpu="x86"']) |
| with sdk(target_os, 'x64'): |
| api.step('generate build files x64', |
| [gn, 'gen', x64_path, '--args=' + args + ' target_cpu="x64"']) |
| |
| def run_tests(build_dir, env=None): |
| if is_fuchsia: |
| # QEMU instances are very flaky. Disable test running for now. This used |
| # to (and should) do `build/run_fuchsia_qemu.py start` before, and `... |
| # stop` after calling run_tests.py. |
| # https://bugs.chromium.org/p/crashpad/issues/detail?id=219. |
| return |
| |
| with api.context(env=env): |
| api.python('run tests', |
| api.path['checkout'].join('build', 'run_tests.py'), |
| args=[build_dir], |
| timeout=5*60) |
| |
| ninja = api.depot_tools.ninja_path |
| if is_win: |
| with sdk(target_os, 'x86'): |
| api.step('compile with ninja x86', [ninja, '-C', x86_path]) |
| with sdk(target_os, 'x64'): |
| api.step('compile with ninja x64', [ninja, '-C', x64_path]) |
| run_tests(x86_path) |
| run_tests(x64_path, env={'CRASHPAD_TEST_32_BIT_OUTPUT':x86_path}) |
| else: |
| with sdk(target_os): |
| api.step('compile with ninja', [ninja, '-C', path]) |
| run_tests(path) |
| |
| test_spec_path = api.path['checkout'].join( |
| 'build', 'swarming_test_spec.pyl') |
| if api.path.exists(test_spec_path): |
| file_contents = api.file.read_text('read swarming_test_spec', |
| test_spec_path, test_data=FAKE_SWARMING_TEST_SPEC) |
| |
| try: |
| swarming_test_spec = ast.literal_eval(file_contents) |
| except Exception: # pragma: no cover |
| # TODO(crbug.com/743139) figure out how to handle different kinds of |
| # errors cleanly. |
| api.step.fail() |
| return |
| |
| for spec in swarming_test_spec: |
| if buildername in spec['builders']: |
| api.python( |
| spec['step_name'], |
| api.path['checkout'].join('build', 'run_on_swarming.py'), |
| args=[api.path['checkout'].join(spec['isolate'][2:])] + |
| spec['args']) |
| |
| |
| def GenTests(api): |
| # Only test a single clobber case. |
| test = 'crashpad_mac_dbg' |
| yield(api.test(test + '_clobber') + |
| api.properties.generic(buildername=test, |
| target_os='mac', |
| config='Debug', |
| clobber=True)) |
| |
| tests = [ |
| (test, 'mac', ''), |
| ('crashpad_try_mac_rel', 'mac', ''), |
| ('crashpad_try_win_dbg', 'win', ''), |
| ('crashpad_try_linux_rel', 'linux', ''), |
| ('crashpad_fuchsia_rel', 'fuchsia', ''), |
| ] |
| for t, os, cpu in tests: |
| test = api.test(t) |
| |
| yield ( |
| test + |
| api.runtime(is_luci=True, is_experimental=False) + |
| api.properties.generic(buildername=t, |
| config='Debug' if '_dbg' in t else 'Release', |
| target_os=os, |
| target_cpu=cpu) + |
| api.path.exists(api.path['checkout'].join( |
| 'build', 'swarming_test_spec.pyl')) |
| ) |
| |