Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: scripts/slave/recipe_modules/chromedriver/api.py

Issue 1274723004: Converted Android Chromedriver buildbot scripts to recipes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import bisect
6 import csv
7 import datetime
8 import logging
9 import re
10 import time
11 import urllib2
12
13 from recipe_engine import recipe_api
14 from . import archive as chromium_archive
15
16 GS_CHROMEDRIVER_BUCKET = 'chromedriver'
luqui 2015/08/06 00:57:37 Be aware that such things have a way of migrating
mikecase (-- gone --) 2016/04/04 21:46:42 Ack
17 GS_CHROMEDRIVER_DATA_BUCKET = 'chromedriver-data'
18 GS_CHROMEDRIVER_RELEASE_URL = 'chromedriver'
19 GS_CONTINUOUS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/continuous'
20 GS_PREBUILTS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/prebuilts'
21 GS_SERVER_LOGS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/server_logs'
22
23 SERVER_LOGS_LINK = (
24 'http://chromedriver-data.storage.googleapis.com/server_logs')
25 TEST_LOG_FORMAT = '%s_log.json'
26 GS_GIT_LOG_URL = (
27 'https://chromium.googlesource.com/chromium/src/+/%s?format=json')
28 GS_SEARCH_PATTERN = (
29 r'Cr-Commit-Position: refs/heads/master@{#(\d+)}')
30 CR_REV_URL = 'https://cr-rev.appspot.com/_ah/api/crrev/v1/redirect/%s'
31
32
33 class ChromedriverApi(recipe_api.RecipeApi):
34
35 def __init__(self, *args, **kwargs):
36 super(ChromedriverApi, self).__init__(*args, **kwargs)
37 self.archive = chromium_archive.Archive(self)
38
39 @property
40 def chromedriver_dir(self):
41 """Gets the directory of the chromedriver code in Chromium."""
42 return self.m.path['checkout'].join('chrome', 'test', 'chromedriver')
43
44 def get_chromedriver_platform(self, is_android):
45 """Gets the platform name for chromedriver."""
46 bitness = '32'
47 if self.m.platform.is_linux and self.m.platform.bits == 64:
48 bitness = '64'
49 platform = '%s%s' % (self.m.platform.name, bitness)
50 if is_android:
51 platform = 'android'
52 return platform
53
54 def get_build_dir(self, required_paths):
luqui 2015/08/06 00:57:37 Is it possible to compute what this ought to be in
mikecase (-- gone --) 2016/04/04 21:46:41 I'm honestly not too familiar with this code (I'm
55 """Returns the preferred build directory that contains given paths."""
56 debug_dirs = [self.m.path['checkout'].join('out', 'Debug'),
57 self.m.path['checkout'].join('build', 'Debug'),
58 self.m.path['checkout'].join('xcodebuild', 'Debug')]
59 release_dirs = [self.m.path['checkout'].join('out', 'Release'),
60 self.m.path['checkout'].join('build', 'Release'),
61 self.m.path['checkout'].join('xcodebuild', 'Release')]
62 for build_dir in debug_dirs + release_dirs:
63 for required_path in required_paths:
64 self.m.path.mock_add_paths(self.m.path.join(build_dir, required_path))
65 if not self.m.path.exists(
66 self.m.path.join(build_dir, required_path)): # pragma: no cover
67 logging.debug('%s not in %s' % (required_path, build_dir))
68 break;
69 else:
70 return build_dir
71 raise RuntimeError('Cannot find build directory containing %s' %
72 ', '.join(required_paths)) # pragma: no cover
73
74 def archive_prebuilts(self, commit_position):
75 """Uploads the prebuilts to google storage."""
76 chromedriver_dir = self.get_build_dir('chromedriver')
77 output_zip_path = self.m.path.mkdtemp('zip_to_archive').join(
78 'chromedriver.zip')
79 pkg = self.m.zip.make_package(root=chromedriver_dir, output=output_zip_path)
80 pkg.add_file(path=chromedriver_dir.join('chromedriver'))
81 pkg.zip(step_name='zip chromedriver')
82 self.m.gsutil.upload(
83 name='archive prebuilt',
84 source=output_zip_path,
85 bucket=GS_PREBUILTS_URL,
86 dest='r%s.zip' % commit_position,
87 link_name='Prebuilt chromedriver r%s.zip' % commit_position)
88
89 def download_prebuilts(self):
90 """Downloads the most recent prebuilts from google storage."""
91 prebuilt_dir = self.m.path.mkdtemp('prebuilt')
92 zipfile = prebuilt_dir.join('build.zip')
93 unzip_dir = prebuilt_dir.join('unzipped')
94
95 self.m.gsutil.download_latest_file(base_url=GS_PREBUILTS_URL,
96 partial_name=GS_PREBUILTS_URL + '/r',
97 destination=zipfile,
98 name='download latest prebuilt')
99 self.m.zip.unzip(step_name='unzip prebuilt',
100 zip_file=zipfile,
101 output=unzip_dir)
102 self.m.file.move(name='move prebuilt',
103 source=unzip_dir.join('chromedriver'),
104 dest=self.get_build_dir(['host_forwarder']),
105 infra_step=False)
106
107 def archive_server_logs(self):
108 """Uploads chromedriver server logs to google storage."""
109 server_logs = self.m.file.glob(
110 name='glob search for server logs',
111 pattern=self.m.path['tmp_base'].join('chromedriver_*', '*'),
luqui 2015/08/06 00:57:36 How do we know the logs will be put in tmp_base?
mikecase (-- gone --) 2016/04/04 21:46:41 Done. Made a chromedriver_log_dir to store the log
112 test_data=[self.m.path['tmp_base'].join('chromedriver_123'),
113 self.m.path['tmp_base'].join('chromedriver_456'),
114 self.m.path['tmp_base'].join('chromedriver_789')])
115 for server_log in server_logs:
116 self.m.gsutil.upload(name='upload %s' % server_log,
117 source=server_log,
118 bucket=GS_SERVER_LOGS_URL,
119 dest=self.m.path.basename(server_log),
120 link_name='server log %s' % server_log)
121
122 def get_test_results_log(self, chromedriver_platform):
123 """Gets the test results log for the given chromedriver platform.
124
125 Args:
126 chromedriver_platform: The platform that the test results log is for.
127
128 Returns:
129 A dictionary where the keys are commit positions and the values are
130 booleans indicating whether the tests passed.
131 """
132 log_name = TEST_LOG_FORMAT % chromedriver_platform
133 temp_log = self.m.path.mkdtemp('results_log').join(log_name)
134 try:
135 self.m.gsutil.download(name='download results log',
136 source=log_name,
137 bucket=GS_CHROMEDRIVER_DATA_BUCKET,
138 dest=temp_log)
139 json_data = self.m.file.read(name='read results log file',
140 path=temp_log,
141 test_data='{"222222": true}')
142 json_dict = self.m.json.loads(json_data)
143 except self.m.step.StepFailure:
144 json_dict = {}
145 # Workaround for json encoding dictionary keys as strings.
146 return dict([(int(v[0]), v[1]) for v in json_dict.items()])
luqui 2015/08/06 00:57:37 return { int(k): v for k, v in json_dict.items() }
mikecase (-- gone --) 2016/04/04 21:46:41 Done
147
148 def put_test_results_log(self, chromedriver_platform, test_results_log):
149 """Pushes the given test results log to google storage."""
150 temp_dir = self.m.path.mkdtemp('results_log')
151 log_name = TEST_LOG_FORMAT % chromedriver_platform
152 log_path = temp_dir.join(log_name)
153 self.m.file.write(name='write log to file %s' % log_name,
154 path=log_path,
155 data=self.m.json.dumps(test_results_log))
156 self.m.gsutil.upload(name='upload log %s' % log_name,
157 source=log_path,
158 bucket=GS_CHROMEDRIVER_DATA_BUCKET,
159 dest=log_name,
160 link_name='results log')
161
162 def update_test_results_log(self, chromedriver_platform,
163 commit_position, passed):
164 """Updates the test results log for the given platform.
luqui 2015/08/06 00:57:37 This description is a bit unclear, not sure what y
mikecase (-- gone --) 2016/04/04 21:46:42 Done, mentioned the log is stored in GS.
165
166 Args:
167 chromedriver_platform: The platform name.
168 commit_position: The commit position number.
169 passed: Boolean indicating whether the tests passed at this
170 commit position.
171 """
172 log = self.get_test_results_log(chromedriver_platform)
173 if len(log) > 500: # pragma: no cover
luqui 2015/08/06 00:57:36 I know we're only adding one at a time so it shoul
mikecase (-- gone --) 2016/04/04 21:46:41 Agree, done.
174 del log[min(log.keys())]
175 assert commit_position not in log, \
luqui 2015/08/06 00:57:36 Should this really be a failure, or just a skip &
mikecase (-- gone --) 2016/04/04 21:46:42 Changed to skip and warn.
176 'Results already exist for commit position %s' % commit_position
177 log[commit_position] = bool(passed)
178 self.put_test_results_log(chromedriver_platform, log)
179
180 def get_version(self):
181 """Get the current chromedriver version."""
182 version_file = self.chromedriver_dir.join('VERSION')
183 return self.m.file.read(name='read version file',
184 path=version_file,
185 test_data="9.99").strip()
186
187 def get_supported_chrome_versions(self):
188 """Get the minimum and maximum supported Chrome versions.
189
190 Returns:
191 A tuple of the form (min_version, max_version).
192 """
193 # Minimum supported Chrome version is embedded as:
194 # const int kMinimumSupportedChromeVersion[] = {27, 0, 1453, 0};
195 version_cc_file_name = 'version.cc'
196 version_cc_file_data = self.m.file.read(
197 name='read %s' % version_cc_file_name,
198 path=self.chromedriver_dir.join('chrome', version_cc_file_name),
199 test_data='int kMinimumSupportedChromeVersion[] = {42, 0, 2311, 0};')
200 chrome_min_version_line = [x for x in version_cc_file_data.splitlines()
201 if 'kMinimumSupportedChromeVersion' in x]
202 chrome_min_version = chrome_min_version_line[0].split('{')[1].split(',')[0]
luqui 2015/08/06 00:57:37 Use a regex instead of 'in' and 'split'. It'll be
mikecase (-- gone --) 2016/04/04 21:46:41 Switching to regex.
203
204 version_file_name = 'VERSION'
205 version_file_data = self.m.file.read(
luqui 2015/08/06 00:57:36 BTW we have support for nested steps now if this g
mikecase (-- gone --) 2016/04/04 21:46:41 Done. Trying out the nested steps.
206 name='read %s' % version_file_name,
207 path=self.m.path['checkout'].join('chrome', version_file_name),
208 test_data='MAJOR=46\nMINOR=0\nBUILD=2469\nPATCH=0')
209 chrome_max_version_line = version_file_data.splitlines()[0]
210 chrome_max_version =chrome_max_version_line.split('=')[1].strip()
211 return (chrome_min_version, chrome_max_version)
212
213 def commit_position_state(self, test_results_log, commit_position):
214 """Check the state of tests at a given commit position.
215
216 Considers tests as having passed at a commit position if they passed at
217 revisons both before and after.
218
219 Args:
220 test_results_log: A test results log dictionary from
221 get_test_results_log().
222 commit_position: The commit position to check at.
223
224 Returns:
225 'passed', 'failed', or 'unknown'
226 """
227 assert isinstance(commit_position, int), ('The commit position must '
228 'be an int')
229
230 keys = sorted(test_results_log.keys())
231 # Return passed if the exact commit position passed on Android.
232 if commit_position in test_results_log:
233 return 'passed' if test_results_log[commit_position] else 'failed'
234 # Tests were not run on this exact commit position on Android.
235 index = bisect.bisect_right(keys, commit_position)
236 # Tests have not yet run on Android at or above this commit position.
237 if index == len(test_results_log):
238 return 'unknown'
239 # No log exists for any prior commit position, assume it failed.
240 if index == 0:
241 return 'failed'
242 # Return passed if the commit position on both sides passed.
243 if test_results_log[keys[index]] and test_results_log[keys[index - 1]]:
244 return 'passed'
245 return 'failed'
246
247 def archive_good_build(self, chromedriver_platform, commit_position):
248 """Archive chromedriver binary if the build is green."""
249 assert chromedriver_platform != 'android'
250 server_name = 'chromedriver'
251 if self.m.platform.is_win:
252 server_name += '.exe'
253
254 chromedriver_dir = self.get_build_dir(server_name)
255 output_zip_path = self.m.path.mkdtemp(
256 'zip_to_archive').join('chromedriver.zip')
257 pkg = self.m.zip.make_package(root=chromedriver_dir, output=output_zip_path)
luqui 2015/08/06 00:57:37 Separate these three lines by whitespace since the
mikecase (-- gone --) 2016/04/04 21:46:42 Done. Separated out these 3 lines w/ whitespace.
258 pkg.add_file(path=chromedriver_dir.join(server_name))
259 pkg.zip(step_name='zip chromedriver')
260 build_name = 'chromedriver_%s_%s.%s.zip' % (
261 chromedriver_platform, self.get_version(), commit_position)
262 self.m.gsutil.upload(name='archive good build',
263 source=output_zip_path,
264 bucket=GS_CONTINUOUS_URL,
265 dest=build_name,
266 link_name=build_name)
267
268 latest_build_file = self.m.path.mkdtemp(
269 'latest_build_file_dir').join('latest_build')
270 latest_url = 'latest_%s' % chromedriver_platform
271 self.m.file.write(name='write latest build version',
272 path='latest_build_file',
273 data=build_name)
274 self.m.gsutil.upload(name='upload latest build version',
275 source=latest_build_file,
276 bucket=GS_CONTINUOUS_URL,
277 dest=latest_url,
278 link_name='latest build version')
279
280 def was_released(self, version, chromedriver_platform):
281 """Check if the specified version is released for the given platform."""
282 try:
283 step_result = self.m.gsutil.list(
284 name='list chromedriver versions',
285 url='gs://%s/%s/chromedriver_%s.zip' % (
286 GS_CHROMEDRIVER_BUCKET, version, chromedriver_platform))
287 return True
288 except self.m.step.StepFailure:
289 return False
290
291 def maybe_release(self, chromedriver_platform):
292 """Releases a release candidate if conditions are right."""
293 assert chromedriver_platform != 'android'
luqui 2015/08/06 20:52:58 Why? (answer in comment) I'm confused, since belo
samuong 2015/08/06 21:58:39 ChromeDriver doesn't run on Android. It runs on a
294 version = self.get_version()
295 # Check if the current version has already been released.
296 if self.was_released(version, chromedriver_platform):
297 return
298 # Fetch Android test results.
299 android_test_results = self.get_test_results_log('android')
300 # Fetch release candidates.
301 step_result = self.m.gsutil.list(
302 name='list release candidates',
303 url='gs://%s/chromedriver_%s_%s*' % (
304 GS_CONTINUOUS_URL, chromedriver_platform, version),
305 stdout=self.m.raw_io.output(),
306 step_test_data=lambda: self.m.raw_io.test_api.stream_output(
307 'test/dir/chromedriver_linux64_9.99.222222.zip', stream='stdout'))
308 output = step_result.stdout
309
310 candidate_pattern = re.compile(r'.*/chromedriver_%s_%s\.(\d+)\.zip$' % (
311 chromedriver_platform, version))
312 candidates = []
313 for line in output.strip().split('\n'):
314 result = candidate_pattern.match(line)
315 if not result:
316 logging.warning('Ignored line "%s"' % line)
317 continue
318 candidates.append(int(result.group(1)))
319
320 # Release the latest candidate build that passed Android, if any.
321 # In this way, if a hot fix is needed, we can delete the release from
322 # the chromedriver bucket instead of bumping up the release version number.
323 candidates.sort(reverse=True)
324 for commit_position in candidates:
325 android_result = self.commit_position_state(android_test_results,
326 commit_position)
327 if android_result == 'failed':
328 logging.warning('Android tests did not pass at commit position %s' %
329 commit_position)
330 elif android_result == 'passed':
331 logging.warning('Android tests passed at commit position %s' %
332 commit_position)
333 candidate = 'chromedriver_%s_%s.%s.zip' % (
334 chromedriver_platform, version, commit_position)
335 self.release(GS_CONTINUOUS_URL, candidate,
336 version, chromedriver_platform)
337 break
338 else:
339 logging.warning('Android tests have not run at a commit position '
340 'as recent as %s' % commit_position) # pragma: no cover
341
342 def release(self, bucket, build, version, chromedriver_platform):
343 """Releases the given candidate build."""
344 release_name = 'chromedriver_%s.zip' % chromedriver_platform
345 temp_dir = self.m.path.mkdtemp('temp_dir')
346 zip_path = temp_dir.join(build)
347 self.m.gsutil.download(name='download release build',
348 source=build,
349 bucket=bucket,
350 dest=zip_path)
351 if self.m.platform.is_linux:
352 unzip_dir = temp_dir.join('unzipped')
353 self.m.zip.unzip(step_name='unzip prebuilt',
354 zip_file=zip_path,
355 output=unzip_dir)
356 server_path = unzip_dir.join('chromedriver')
357 zip_path = unzip_dir.join('chromedriver.zip')
358 self.m.step(name='strip', cmd=['strip', server_path])
359 pkg = self.m.zip.make_package(root=unzip_dir, output=zip_path)
360 pkg.add_file(path=server_path)
361 pkg.zip(step_name='zip chromedriver')
362
363 self.m.gsutil.upload(
364 name='upload release build',
365 source=zip_path,
366 bucket=GS_CHROMEDRIVER_BUCKET,
367 dest='%s/%s' % (version, release_name))
368
369 self.maybe_upload_release_notes(version)
370 self.maybe_update_latest_release(version)
371
372 def get_web_page_content(self, url):
373 """Return the content of the web page specified by the given url."""
374 return urllib2.urlopen(url).read()
375
376 def maybe_upload_release_notes(self, version):
377 """Upload release notes if conditions are right."""
378 # Check if the current version has already been released.
379 notes_name = 'notes.txt'
380 notes_bucket = GS_CHROMEDRIVER_BUCKET
381 notes_url = '%s/%s' % (version, notes_name)
382 prev_version = '.'.join([version.split('.')[0],
383 str(int(version.split('.')[1]) - 1)])
384 prev_notes_url = '%s/%s' % (prev_version, notes_name)
385
386 try:
387 step_result = self.m.gsutil.list(
388 name='list version notes',
389 url='gs://%s/%s' % (notes_bucket, notes_url))
390 return
391 except self.m.step.StepFailure:
392 pass
393
394 fixed_issues = []
395 query = ('https://code.google.com/p/chromedriver/issues/csv?'
396 'can=1&q=label%%3AChromeDriver-%s&colspec=ID%%20Summary' % version)
397 issues = self.get_web_page_content(query)
398 for issue in csv.reader(issues.split('\n')[1:]):
399 if not issue:
400 continue
401 else: # pragma: no cover
402 issue_id = issue[0]
403 desc = issue[1]
404 labels = issue[2]
405 labels.remove('ChromeDriver-%s' % version)
406 fixed_issues += ['Resolved issue %s: %s [%s]' %
407 (issue_id, desc, labels)]
408
409
410 temp_notes_fname = self.m.path.mkdtemp('temp_notes').join('temp_notes')
411
412 try:
413 self.m.gsutil.download(name='download prev notes',
414 source=prev_notes_url,
415 bucket=notes_bucket,
416 dest=temp_notes_fname)
417 old_notes = self.m.file.read(name='read old notes',
418 path=temp_notes_fname)
419 except self.m.step.StepFailure:
420 old_notes = ''
421
422 new_notes = '----------ChromeDriver v%s (%s)----------\n%s\n%s\n\n%s' % (
423 version, datetime.date.today().isoformat(),
424 'Supports Chrome v%s-%s' % self.get_supported_chrome_versions(),
425 '\n'.join(fixed_issues),
426 old_notes)
427 self.m.file.write(name='write new notes',
428 path=temp_notes_fname,
429 data=new_notes)
430 self.m.gsutil.upload(name='upload new notes',
431 source=temp_notes_fname,
432 bucket=notes_bucket,
433 dest=notes_url)
434
435 def maybe_update_latest_release(self, version):
436 """Update the file LATEST_RELEASE with the latest release version number."""
437 latest_release_fname = 'LATEST_RELEASE'
438 latest_release_url = 'gs://%s/%s' % (
439 GS_CHROMEDRIVER_BUCKET, latest_release_fname)
440
441 # Check if LATEST_RELEASE is up-to-date.
442 step_result = self.m.gsutil.cat(
443 name='check latest release',
444 url=latest_release_url,
445 stdout=self.m.raw_io.output(),
446 step_test_data=lambda: self.m.raw_io.test_api.stream_output(
447 '9.98', stream='stdout'))
448 latest_released_version = step_result.stdout
449
450 if version == latest_released_version:
451 return
452
453 # Check if chromedriver was released on all supported platforms.
454 supported_platforms = ['linux32', 'linux64', 'mac32', 'win32']
455 for platform in supported_platforms:
456 if not self.was_released(version, platform):
457 return # pragma: no cover
458
459 temp_latest_release_fname = self.m.path.mkdtemp(
460 'temp_notes').join('temp_notes')
461 self.m.file.write(name='write latest release number',
462 path=temp_latest_release_fname,
463 data=version)
464 self.m.gsutil.upload(name='upload latest release number',
465 source=temp_latest_release_fname,
466 bucket=GS_CHROMEDRIVER_BUCKET,
467 dest=latest_release_fname)
468
469 def wait_for_latest_snapshot(self, commit_position):
luqui 2015/08/06 20:52:58 This will tie up a builder just sleeping. How lon
mikecase (-- gone --) 2016/04/04 21:46:41 Yeah, I think that is a good idea. I'll look to se
470 while True:
471 snapshot_position = self.archive.get_latest_snapshot_version()
472 if commit_position is not None and snapshot_position is not None:
473 if int(snapshot_position) >= int(commit_position):
474 break
475 logging.debug('Waiting for snapshot >= %s, found %s' %
476 (commit_position, snapshot_position)) # pragma: no cover
477 time.sleep(60) # pragma: no cover
478 logging.debug('Got snapshot commit position %s' % snapshot_position)
479
480 def add_tools_to_path(self, env):
481 """Add some tools like Ant and Java to PATH for testing steps to use."""
482 paths = []
483 error_message = ''
484 if self.m.platform.is_win:
485 paths = [
486 # Path to Ant and Java, required for the java acceptance tests.
487 'C:\\Program Files (x86)\\Java\\ant\\bin',
luqui 2015/08/06 20:52:58 Ack hardcoded paths! I do not have a suggestion h
samuong 2015/08/06 21:58:39 I'd love to get rid of this too, but we'd need to
488 'C:\\Program Files (x86)\\Java\\jre\\bin',
489 ]
490 error_message = ('Java test steps will fail as expected and '
491 'they can be ignored.\n'
492 'Ant, Java or others might not be installed on bot.\n'
493 'Please refer to page "WATERFALL" on site '
494 'go/chromedriver.')
495 if paths:
496 path_missing = False
497 for path in paths:
498 if (not self.m.path.exists(path) or
499 not self.m.file.listdir(name='tools', path=path)):
500 logging.warning('Directory "%s" is not found or empty.' % path)
501 path_missing = True
502 if path_missing:
503 logging.error(error_message)
504 return
505 env['PATH'] = self.m.path.pathsep.join(
506 [env['PATH']] + paths) # pragma: no cover
507
508 def generate_test_command(self, script, chromedriver, ref_chromedriver=None,
509 chrome=None, chrome_version=None,
510 android_package=None, build_type=None, verbose=None) :
511 log_path = self.m.path.mkdtemp('chromedriver_').join('test_log')
512 cmd = [script, '--chromedriver', chromedriver, '--log-path', log_path]
513 if ref_chromedriver:
514 cmd.extend(['--reference-chromedriver', ref_chromedriver])
515 if chrome:
516 cmd.extend(['--chrome', chrome])
517 if chrome_version:
518 cmd.extend(['--chrome-version', chrome_version])
519 if build_type:
520 cmd.extend(['--build-type', build_type])
521 if verbose:
522 cmd.extend(['--verbose'])
523 if android_package:
524 cmd = ['xvfb-run', '-a'] + cmd
525 cmd.extend(['--android-package', android_package])
526 return cmd
527
528 def run_python_tests(self, chromedriver, ref_chromedriver,
529 chrome=None, chrome_version=None,
530 chrome_version_name=None, android_package=None,
531 build_type=None, **kwargs):
532 version_info = ''
533 if chrome_version_name:
534 version_info = '(%s)' % chrome_version_name
535 self.m.step('python_tests%s' % version_info,
536 self.generate_test_command('run_py_tests.py', chromedriver,
537 ref_chromedriver=ref_chromedriver,
538 chrome=chrome,
539 chrome_version=chrome_version,
540 android_package=android_package,
541 build_type=build_type),
542 **kwargs)
543
544 def run_java_tests(self, chromedriver, chrome=None, chrome_version=None,
545 chrome_version_name=None, android_package=None,
546 build_type=None, verbose=False, **kwargs):
547 version_info = ''
548 if chrome_version_name:
549 version_info = '(%s)' % chrome_version_name
550 self.m.step('java_tests%s' % version_info,
551 self.generate_test_command('run_java_tests.py',
552 chromedriver,
553 ref_chromedriver=None,
554 chrome=chrome,
555 chrome_version=chrome_version,
556 android_package=android_package,
557 build_type=build_type,
558 verbose=verbose),
559 **kwargs)
560
561 def run_cpp_tests(self, cpp_tests):
562 self.m.step('chromedriver_tests', [cpp_tests])
563
564 def download_chrome(self, version_name, revision, download_site):
565 try:
566 temp_dir = self.m.path.mkdtemp('chrome')
567 return (temp_dir, self.archive.download_chrome(
568 revision, temp_dir, download_site))
569 except self.m.step.StepFailure:
570 return (None, None)
571
572 def kill_chromes(self):
573 chrome_map = {
574 'win': 'chrome.exe',
575 'mac': 'Chromium',
576 'linux': 'chrome',
577 }
578 if self.m.platform.is_win:
579 cmd = ['taskkill', '/F', '/IM']
580 else:
581 cmd = ['killall', '-9']
582 cmd.append(chrome_map[self.m.platform.name])
583 self.m.step('kill chromes', cmd)
584
585 def run_all_tests(self, android_packages=None):
586 exe_postfix = ''
587 if self.m.platform.is_win:
588 exe_postfix = '.exe'
589 cpp_tests_name = 'chromedriver_tests' + exe_postfix
590 server_name = 'chromedriver' + exe_postfix
591
592 required_build_outputs = [server_name]
593 if not android_packages:
594 required_build_outputs += [cpp_tests_name]
595 build_dir = self.get_build_dir(required_build_outputs)
596 build_type = self.m.path.basename(build_dir)
597 logging.info('Using build outputs from %s' % build_dir)
598
599 test_env = {'PATH': '%(PATH)s'}
600 self.add_tools_to_path(test_env)
601
602 chromedriver = self.m.path.join(build_dir, server_name)
603 platform_name = self.m.platform.name
604 if self.m.platform.is_linux and self.m.platform.bits == 64:
605 platform_name = 'linux64'
606 ref_chromedriver = self.m.path.join(
607 self.m.path['checkout'],
608 'chrome', 'test', 'chromedriver', 'third_party', 'java_tests',
609 'reference_builds', 'chromedriver_%s%s' % (platform_name, exe_postfix))
610
611 failure = False
612 if android_packages:
613 test_env['PATH'] = self.m.path.pathsep.join([
614 test_env['PATH'],
615 str(self.m.path['checkout'].join(
616 'chrome', 'test', 'chromedriver', 'chrome'))])
617 for package in android_packages:
618 try:
619 with self.m.step.defer_results():
620 self.run_python_tests(chromedriver,
621 ref_chromedriver,
622 chrome_version_name=package,
623 android_package=package,
624 build_type=build_type,
625 env=test_env)
626 self.run_java_tests(chromedriver,
627 chrome_version_name=package,
628 android_package=package,
629 build_type=build_type,
630 verbose=True,
631 env=test_env)
632 except recipe_api.AggregatedStepFailure:
633 failure = True
634 else:
635 latest_snapshot_revision = self.archive.get_latest_snapshot_version()
636
637 versions = [
638 ['HEAD', latest_snapshot_revision],
639 ['44', self.archive.CHROME_44_REVISION],
640 ['43', self.archive.CHROME_43_REVISION],
641 ['42', self.archive.CHROME_42_REVISION],
642 ]
643 for version in versions:
644 download_site = chromium_archive.Url.GS_CHROMIUM_CONTINUOUS_URL
645 version_name = version[0]
646 if version_name == 'HEAD':
647 version_name = version[1]
648 download_site = self.archive.get_snapshot_download_site()
649 temp_dir, chrome_path = self.download_chrome(
650 version_name, version[1], download_site)
651 try:
652 with self.m.step.defer_results():
653 self.run_python_tests(chromedriver,
654 ref_chromedriver,
655 chrome=chrome_path,
656 chrome_version=version[0],
657 chrome_version_name='v%s' % version_name,
658 build_type=build_type)
659 self.run_java_tests(chromedriver, chrome=chrome_path,
660 chrome_version=version[0],
661 chrome_version_name='v%s' % version_name,
662 build_type=build_type)
663 self.kill_chromes()
664 except recipe_api.AggregatedStepFailure:
665 failure = True
666
667 try:
668 cpp_tests = self.m.path.join(build_dir, cpp_tests_name)
669 self.run_cpp_tests(cpp_tests)
670 except recipe_api.StepFailure:
671 failure = True
672 return not failure
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698