7
7
"""Argument-less script to select what to run on the buildbots."""
8
8
9
9
10
+ import filecmp
10
11
import os
11
12
import shutil
12
13
import subprocess
30
31
31
32
def CallSubProcess (* args , ** kwargs ):
32
33
"""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 )
34
36
if retcode != 0 :
35
37
print '@@@STEP_EXCEPTION@@@'
36
38
sys .exit (1 )
@@ -49,10 +51,6 @@ def PrepareCmake():
49
51
50
52
print '@@@BUILD_STEP Initialize CMake checkout@@@'
51
53
os .mkdir (CMAKE_DIR )
52
- CallSubProcess (['git' , 'config' , '--global' , 'user.name' , 'trybot' ])
53
- CallSubProcess (['git' , 'config' , '--global' ,
54
- 'user.email' ,
'[email protected] ' ])
55
- CallSubProcess (['git' , 'config' , '--global' , 'color.ui' , 'false' ])
56
54
57
55
print '@@@BUILD_STEP Sync CMake@@@'
58
56
CallSubProcess (
@@ -73,41 +71,96 @@ def PrepareCmake():
73
71
CallSubProcess ( ['make' , 'cmake' ], cwd = CMAKE_DIR )
74
72
75
73
74
+ _ANDROID_SETUP = 'source build/envsetup.sh && lunch full-eng'
75
+
76
+
76
77
def PrepareAndroidTree ():
77
78
"""Prepare an Android tree to run 'android' format tests."""
78
79
if os .environ ['BUILDBOT_CLOBBER' ] == '1' :
79
80
print '@@@BUILD_STEP Clobber Android checkout@@@'
80
81
shutil .rmtree (ANDROID_DIR )
81
82
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 ):
85
119
return
86
120
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' ,
'[email protected] ' ])
92
- CallSubProcess (['git' , 'config' , '--global' , 'color.ui' , 'false' ])
121
+ print '@@@BUILD_STEP Build Android@@@'
93
122
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 ],
98
125
cwd = ANDROID_DIR )
99
126
100
- print '@@@BUILD_STEP Sync Android@@@'
101
- CallSubProcess (['repo' , 'sync' , '-j4' ], cwd = ANDROID_DIR )
102
127
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 )
104
150
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 ],
107
153
cwd = ANDROID_DIR )
108
154
109
155
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 = []):
111
164
"""Run the gyp tests for a given format, emitting annotator tags.
112
165
113
166
See annotator docs at:
@@ -131,14 +184,13 @@ def GypTestFormat(title, format=None, msvs_version=None):
131
184
'--passed' ,
132
185
'--format' , format ,
133
186
'--path' , CMAKE_BIN_DIR ,
134
- '--chdir' , 'trunk' ])
187
+ '--chdir' , 'trunk' ] + tests )
135
188
if format == 'android' :
136
189
# gyptest needs the environment setup from envsetup/lunch in order to build
137
190
# using the 'android' backend, so this is done in a single shell.
138
191
retcode = subprocess .call (
139
192
['/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 )],
142
194
cwd = ANDROID_DIR , env = env )
143
195
else :
144
196
retcode = subprocess .call (command , cwd = ROOT_DIR , env = env , shell = True )
@@ -160,7 +212,11 @@ def GypBuild():
160
212
# The Android gyp bot runs on linux so this must be tested first.
161
213
if os .environ ['BUILDBOT_BUILDERNAME' ] == 'gyp-android' :
162
214
PrepareAndroidTree ()
163
- retcode += GypTestFormat ('android' )
215
+ StartAndroidEmulator ()
216
+ try :
217
+ retcode += GypTestFormat ('android' )
218
+ finally :
219
+ StopAndroidEmulator ()
164
220
elif sys .platform .startswith ('linux' ):
165
221
retcode += GypTestFormat ('ninja' )
166
222
retcode += GypTestFormat ('make' )
@@ -173,8 +229,13 @@ def GypBuild():
173
229
elif sys .platform == 'win32' :
174
230
retcode += GypTestFormat ('ninja' )
175
231
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' )
178
239
else :
179
240
raise Exception ('Unknown platform' )
180
241
if retcode :
0 commit comments