1c1ced77af959d11dd80252ab471e89906ea70f09maruel@chromium.org#!/usr/bin/env python
2a4440c03ca124d27c167bd1f6023c37cb2993e20bradnelson@google.com# Copyright (c) 2012 Google Inc. All rights reserved.
3cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com# Use of this source code is governed by a BSD-style license that can be
4cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com# found in the LICENSE file.
5cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
6cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
7cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com"""Argument-less script to select what to run on the buildbots."""
8cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
9cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
10cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.comimport os
1199cfb2cb7fbbeae7ee01a83a2115503d3ad55638bradnelson@google.comimport shutil
12cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.comimport subprocess
13cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.comimport sys
14cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
15cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
16b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.comif sys.platform in ['win32', 'cygwin']:
17b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com  EXE_SUFFIX = '.exe'
18b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.comelse:
19b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com  EXE_SUFFIX = ''
20b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com
21b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com
22b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.comBUILDBOT_DIR = os.path.dirname(os.path.abspath(__file__))
23b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.comTRUNK_DIR = os.path.dirname(BUILDBOT_DIR)
24b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.comROOT_DIR = os.path.dirname(TRUNK_DIR)
25f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.orgANDROID_DIR = os.path.join(ROOT_DIR, 'android')
26b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.comOUT_DIR = os.path.join(TRUNK_DIR, 'out')
27b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com
28b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com
29f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.orgdef CallSubProcess(*args, **kwargs):
30f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  """Wrapper around subprocess.call which treats errors as build exceptions."""
31f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  retcode = subprocess.call(*args, **kwargs)
32f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  if retcode != 0:
33f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    print '@@@STEP_EXCEPTION@@@'
34f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    sys.exit(1)
35f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org
36f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org
37f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.orgdef PrepareAndroidTree():
38f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  """Prepare an Android tree to run 'android' format tests."""
39f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  if os.environ['BUILDBOT_CLOBBER'] == '1':
40f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    print '@@@BUILD_STEP Clobber Android checkout@@@'
41f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    shutil.rmtree(ANDROID_DIR)
42f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org
43f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  # The release of Android we use is static, so there's no need to do anything
44f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  # if the directory already exists.
45f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  if os.path.isdir(ANDROID_DIR):
46f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    return
47f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org
48f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  print '@@@BUILD_STEP Initialize Android checkout@@@'
49f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  os.mkdir(ANDROID_DIR)
50f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  CallSubProcess(['git', 'config', '--global', 'user.name', 'trybot'])
51f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  CallSubProcess(['git', 'config', '--global',
52f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org                  'user.email', 'chrome-bot@google.com'])
53f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  CallSubProcess(['git', 'config', '--global', 'color.ui', 'false'])
54f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  CallSubProcess(
55f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org      ['repo', 'init',
56f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org       '-u', 'https://android.googlesource.com/platform/manifest',
57f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org       '-b', 'android-4.2.1_r1',
58f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org       '-g', 'all,-notdefault,-device,-darwin,-mips,-x86'],
59f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org      cwd=ANDROID_DIR)
60f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org
61f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  print '@@@BUILD_STEP Sync Android@@@'
62f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  CallSubProcess(['repo', 'sync', '-j4'], cwd=ANDROID_DIR)
63f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org
64f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  print '@@@BUILD_STEP Build Android@@@'
65f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  CallSubProcess(
66f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org      ['/bin/bash',
67f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org       '-c', 'source build/envsetup.sh && lunch full-eng && make -j4'],
68f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org      cwd=ANDROID_DIR)
69f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org
70f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org
71b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.comdef GypTestFormat(title, format=None, msvs_version=None):
72cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  """Run the gyp tests for a given format, emitting annotator tags.
73cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
74cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  See annotator docs at:
75cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    https://sites.google.com/a/chromium.org/dev/developers/testing/chromium-build-infrastructure/buildbot-annotations
76cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  Args:
77cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    format: gyp format to test.
78cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  Returns:
79cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    0 for sucesss, 1 for failure.
80cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  """
81b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com  if not format:
82b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com    format = title
83b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com
84cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  print '@@@BUILD_STEP ' + title + '@@@'
8549db410d2c638f1a1999bbd4f2a70258d736f8f3bradnelson@google.com  sys.stdout.flush()
8649db410d2c638f1a1999bbd4f2a70258d736f8f3bradnelson@google.com  env = os.environ.copy()
87cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  if msvs_version:
8849db410d2c638f1a1999bbd4f2a70258d736f8f3bradnelson@google.com    env['GYP_MSVS_VERSION'] = msvs_version
89f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  command = ' '.join(
9049db410d2c638f1a1999bbd4f2a70258d736f8f3bradnelson@google.com      [sys.executable, 'trunk/gyptest.py',
91cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com       '--all',
92cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com       '--passed',
93cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com       '--format', format,
9446b4f67e79748c751cb2ec7e769bc2cfbcfb9f79bradnelson@google.com       '--chdir', 'trunk'])
95f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  if format == 'android':
96f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    # gyptest needs the environment setup from envsetup/lunch in order to build
97f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    # using the 'android' backend, so this is done in a single shell.
98f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    retcode = subprocess.call(
99f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org        ['/bin/bash',
100f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org         '-c', 'source build/envsetup.sh && lunch full-eng && cd %s && %s'
101f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org         % (ROOT_DIR, command)],
102f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org        cwd=ANDROID_DIR, env=env)
103f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  else:
104f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    retcode = subprocess.call(command, cwd=ROOT_DIR, env=env, shell=True)
105cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  if retcode:
106cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    # Emit failure tag, and keep going.
107cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    print '@@@STEP_FAILURE@@@'
108cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    return 1
10949db410d2c638f1a1999bbd4f2a70258d736f8f3bradnelson@google.com  return 0
110cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
111cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
112cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.comdef GypBuild():
11399cfb2cb7fbbeae7ee01a83a2115503d3ad55638bradnelson@google.com  # Dump out/ directory.
11499cfb2cb7fbbeae7ee01a83a2115503d3ad55638bradnelson@google.com  print '@@@BUILD_STEP cleanup@@@'
115b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com  print 'Removing %s...' % OUT_DIR
116b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com  shutil.rmtree(OUT_DIR, ignore_errors=True)
11799cfb2cb7fbbeae7ee01a83a2115503d3ad55638bradnelson@google.com  print 'Done.'
11899cfb2cb7fbbeae7ee01a83a2115503d3ad55638bradnelson@google.com
119cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  retcode = 0
120f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  # The Android gyp bot runs on linux so this must be tested first.
121f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  if os.environ['BUILDBOT_BUILDERNAME'] == 'gyp-android':
122f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    PrepareAndroidTree()
123f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org    retcode += GypTestFormat('android')
124f1d6506f0acf422f5a5dbe0e7a3af47ee6c26c2ctorne@chromium.org  elif sys.platform.startswith('linux'):
125b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com    retcode += GypTestFormat('ninja')
126b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com    retcode += GypTestFormat('make')
127cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  elif sys.platform == 'darwin':
128b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com    retcode += GypTestFormat('ninja')
129b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com    retcode += GypTestFormat('xcode')
130b940d959cdac6d2ebb3fe07892d4baabc8ebe548bradnelson@google.com    retcode += GypTestFormat('make')
131cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  elif sys.platform == 'win32':
132880525d606ba0b4b185351e379c25d74fbc2d326scottmg@chromium.org    retcode += GypTestFormat('ninja')
13349db410d2c638f1a1999bbd4f2a70258d736f8f3bradnelson@google.com    if os.environ['BUILDBOT_BUILDERNAME'] == 'gyp-win64':
13449db410d2c638f1a1999bbd4f2a70258d736f8f3bradnelson@google.com      retcode += GypTestFormat('msvs-2010', format='msvs', msvs_version='2010')
135f9f6c9cc9d55a2025e5300a5addca3c6d290c330scottmg@chromium.org      retcode += GypTestFormat('msvs-2012', format='msvs', msvs_version='2012')
136cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  else:
137cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    raise Exception('Unknown platform')
138cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  if retcode:
139cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    # TODO(bradnelson): once the annotator supports a postscript (section for
140cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    #     after the build proper that could be used for cumulative failures),
141cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    #     use that instead of this. This isolates the final return value so
142cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    #     that it isn't misattributed to the last stage.
143cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    print '@@@BUILD_STEP failures@@@'
144cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com    sys.exit(retcode)
145cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
146cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com
147cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.comif __name__ == '__main__':
148cbfc497b03c0bd2c6bafb0be388b21ee72b73bdbbradnelson@google.com  GypBuild()
149