77"""Argument-less script to select what to run on the buildbots."""
88
99
10+ import filecmp
1011import os
1112import shutil
1213import subprocess
3031
3132def CallSubProcess (* args , ** kwargs ):
3233 """Wrapper around subprocess.call which treats errors as build exceptions."""
33- retcode = subprocess .call (* args , ** kwargs )
34+ with open (os .devnull ) as devnull_fd :
35+ retcode = subprocess .call (stdin = devnull_fd , * args , ** kwargs )
3436 if retcode != 0 :
3537 print '@@@STEP_EXCEPTION@@@'
3638 sys .exit (1 )
@@ -49,10 +51,6 @@ def PrepareCmake():
4951
5052 print '@@@BUILD_STEP Initialize CMake checkout@@@'
5153 os .mkdir (CMAKE_DIR )
52- CallSubProcess (['git' , 'config' , '--global' , 'user.name' , 'trybot' ])
53- CallSubProcess (['git' , 'config' , '--global' ,
54- 'user.email' , 'chrome-bot@google.com' ])
55- CallSubProcess (['git' , 'config' , '--global' , 'color.ui' , 'false' ])
5654
5755 print '@@@BUILD_STEP Sync CMake@@@'
5856 CallSubProcess (
@@ -73,41 +71,96 @@ def PrepareCmake():
7371 CallSubProcess ( ['make' , 'cmake' ], cwd = CMAKE_DIR )
7472
7573
74+ _ANDROID_SETUP = 'source build/envsetup.sh && lunch full-eng'
75+
76+
7677def PrepareAndroidTree ():
7778 """Prepare an Android tree to run 'android' format tests."""
7879 if os .environ ['BUILDBOT_CLOBBER' ] == '1' :
7980 print '@@@BUILD_STEP Clobber Android checkout@@@'
8081 shutil .rmtree (ANDROID_DIR )
8182
82- # The release of Android we use is static, so there's no need to do anything
83- # if the directory already exists.
84- if os .path .isdir (ANDROID_DIR ):
83+ # (Re)create the directory so that the following steps will succeed.
84+ if not os .path .isdir (ANDROID_DIR ):
85+ os .mkdir (ANDROID_DIR )
86+
87+ # We use a manifest from the gyp project listing pinned revisions of AOSP to
88+ # use, to ensure that we test against a stable target. This needs to be
89+ # updated to pick up new build system changes sometimes, so we must test if
90+ # it has changed.
91+ manifest_filename = 'aosp_manifest.xml'
92+ gyp_manifest = os .path .join (BUILDBOT_DIR , manifest_filename )
93+ android_manifest = os .path .join (ANDROID_DIR , '.repo' , 'manifests' ,
94+ manifest_filename )
95+ manifest_is_current = (os .path .isfile (android_manifest ) and
96+ filecmp .cmp (gyp_manifest , android_manifest ))
97+ if not manifest_is_current :
98+ # It's safe to repeat these steps, so just do them again to make sure we are
99+ # in a good state.
100+ print '@@@BUILD_STEP Initialize Android checkout@@@'
101+ CallSubProcess (
102+ ['repo' , 'init' ,
103+ '-u' , 'https://android.googlesource.com/platform/manifest' ,
104+ '-b' , 'master' ,
105+ '-g' , 'all,-notdefault,-device,-darwin,-mips,-x86' ],
106+ cwd = ANDROID_DIR )
107+ shutil .copy (gyp_manifest , android_manifest )
108+
109+ print '@@@BUILD_STEP Sync Android@@@'
110+ CallSubProcess (['repo' , 'sync' , '-j4' , '-m' , manifest_filename ],
111+ cwd = ANDROID_DIR )
112+
113+ # If we already built the system image successfully and didn't sync to a new
114+ # version of the source, skip running the build again as it's expensive even
115+ # when there's nothing to do.
116+ system_img = os .path .join (ANDROID_DIR , 'out' , 'target' , 'product' , 'generic' ,
117+ 'system.img' )
118+ if manifest_is_current and os .path .isfile (system_img ):
85119 return
86120
87- print '@@@BUILD_STEP Initialize Android checkout@@@'
88- os .mkdir (ANDROID_DIR )
89- CallSubProcess (['git' , 'config' , '--global' , 'user.name' , 'trybot' ])
90- CallSubProcess (['git' , 'config' , '--global' ,
91- 'user.email' , 'chrome-bot@google.com' ])
92- CallSubProcess (['git' , 'config' , '--global' , 'color.ui' , 'false' ])
121+ print '@@@BUILD_STEP Build Android@@@'
93122 CallSubProcess (
94- ['repo' , 'init' ,
95- '-u' , 'https://android.googlesource.com/platform/manifest' ,
96- '-b' , 'android-4.2.1_r1' ,
97- '-g' , 'all,-notdefault,-device,-darwin,-mips,-x86' ],
123+ ['/bin/bash' ,
124+ '-c' , '%s && make -j4' % _ANDROID_SETUP ],
98125 cwd = ANDROID_DIR )
99126
100- print '@@@BUILD_STEP Sync Android@@@'
101- CallSubProcess (['repo' , 'sync' , '-j4' ], cwd = ANDROID_DIR )
102127
103- print '@@@BUILD_STEP Build Android@@@'
128+ def StartAndroidEmulator ():
129+ """Start an android emulator from the built android tree."""
130+ print '@@@BUILD_STEP Start Android emulator@@@'
131+
132+ CallSubProcess (['/bin/bash' , '-c' ,
133+ '%s && adb kill-server ' % _ANDROID_SETUP ],
134+ cwd = ANDROID_DIR )
135+
136+ # If taskset is available, use it to force adbd to run only on one core, as,
137+ # sadly, it improves its reliability (see crbug.com/268450).
138+ adbd_wrapper = ''
139+ with open (os .devnull , 'w' ) as devnull_fd :
140+ if subprocess .call (['which' , 'taskset' ], stdout = devnull_fd ) == 0 :
141+ adbd_wrapper = 'taskset -c 0'
142+ CallSubProcess (['/bin/bash' , '-c' ,
143+ '%s && %s adb start-server ' % (_ANDROID_SETUP , adbd_wrapper )],
144+ cwd = ANDROID_DIR )
145+
146+ subprocess .Popen (
147+ ['/bin/bash' , '-c' ,
148+ '%s && emulator -no-window' % _ANDROID_SETUP ],
149+ cwd = ANDROID_DIR )
104150 CallSubProcess (
105- ['/bin/bash' ,
106- '-c' , 'source build/envsetup.sh && lunch full-eng && make -j4' ],
151+ ['/bin/bash' , '-c' ,
152+ '%s && adb wait-for-device' % _ANDROID_SETUP ],
107153 cwd = ANDROID_DIR )
108154
109155
110- def GypTestFormat (title , format = None , msvs_version = None ):
156+ def StopAndroidEmulator ():
157+ """Stop all android emulators."""
158+ print '@@@BUILD_STEP Stop Android emulator@@@'
159+ # If this fails, it's because there is no emulator running.
160+ subprocess .call (['pkill' , 'emulator.*' ])
161+
162+
163+ def GypTestFormat (title , format = None , msvs_version = None , tests = []):
111164 """Run the gyp tests for a given format, emitting annotator tags.
112165
113166 See annotator docs at:
@@ -131,14 +184,13 @@ def GypTestFormat(title, format=None, msvs_version=None):
131184 '--passed' ,
132185 '--format' , format ,
133186 '--path' , CMAKE_BIN_DIR ,
134- '--chdir' , 'trunk' ])
187+ '--chdir' , 'trunk' ] + tests )
135188 if format == 'android' :
136189 # gyptest needs the environment setup from envsetup/lunch in order to build
137190 # using the 'android' backend, so this is done in a single shell.
138191 retcode = subprocess .call (
139192 ['/bin/bash' ,
140- '-c' , 'source build/envsetup.sh && lunch full-eng && cd %s && %s'
141- % (ROOT_DIR , command )],
193+ '-c' , '%s && cd %s && %s' % (_ANDROID_SETUP , ROOT_DIR , command )],
142194 cwd = ANDROID_DIR , env = env )
143195 else :
144196 retcode = subprocess .call (command , cwd = ROOT_DIR , env = env , shell = True )
@@ -160,7 +212,11 @@ def GypBuild():
160212 # The Android gyp bot runs on linux so this must be tested first.
161213 if os .environ ['BUILDBOT_BUILDERNAME' ] == 'gyp-android' :
162214 PrepareAndroidTree ()
163- retcode += GypTestFormat ('android' )
215+ StartAndroidEmulator ()
216+ try :
217+ retcode += GypTestFormat ('android' )
218+ finally :
219+ StopAndroidEmulator ()
164220 elif sys .platform .startswith ('linux' ):
165221 retcode += GypTestFormat ('ninja' )
166222 retcode += GypTestFormat ('make' )
@@ -173,8 +229,13 @@ def GypBuild():
173229 elif sys .platform == 'win32' :
174230 retcode += GypTestFormat ('ninja' )
175231 if os .environ ['BUILDBOT_BUILDERNAME' ] == 'gyp-win64' :
176- retcode += GypTestFormat ('msvs-2010' , format = 'msvs' , msvs_version = '2010' )
177- retcode += GypTestFormat ('msvs-2012' , format = 'msvs' , msvs_version = '2012' )
232+ retcode += GypTestFormat ('msvs-ninja-2013' , format = 'msvs-ninja' ,
233+ msvs_version = '2013' ,
234+ tests = [
235+ r'test\generator-output\gyptest-actions.py' ,
236+ r'test\generator-output\gyptest-relocate.py' ,
237+ r'test\generator-output\gyptest-rules.py' ])
238+ retcode += GypTestFormat ('msvs-2013' , format = 'msvs' , msvs_version = '2013' )
178239 else :
179240 raise Exception ('Unknown platform' )
180241 if retcode :
0 commit comments