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

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: Fixed one of the docstrings Created 4 years, 8 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 2016 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 re
9 import tempfile
10 import time
11
12 from recipe_engine import recipe_api
13 from . import archive as chromium_archive
jbudorick 2016/05/04 18:10:42 If you're going to alias it in the same recipe_mod
mikecase (-- gone --) 2016/06/16 17:55:08 Done
14
15 GS_CHROMEDRIVER_BUCKET = 'chromedriver'
16 GS_CHROMEDRIVER_DATA_BUCKET = 'chromedriver-data'
17 GS_CHROMEDRIVER_RELEASE_URL = 'chromedriver'
18 GS_CONTINUOUS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/continuous'
19 GS_PREBUILTS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/prebuilts'
20 GS_SERVER_LOGS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/server_logs'
21
22 TEST_LOG_FORMAT = '%s_log.json'
23
24
25 class ChromedriverApi(recipe_api.RecipeApi):
26
27 def __init__(self, *args, **kwargs):
28 super(ChromedriverApi, self).__init__(*args, **kwargs)
29 self.archive = chromium_archive.Archive(self.m)
jbudorick 2016/05/04 18:10:42 Why is this public? If you have to provide public
mikecase (-- gone --) 2016/06/16 17:55:08 Done
30 self._chromedriver_log_dir = None
31
32 @property
33 def chromedriver_dir(self):
34 """Gets the directory of the chromedriver code in Chromium."""
35 return self.m.path['checkout'].join('chrome', 'test', 'chromedriver')
36
37 @property
38 def chromedriver_log_dir(self):
39 """Gets the directory of where the chromedriver logs are saved."""
40 if not self._chromedriver_log_dir:
41 self._chromedriver_log_dir = self.m.path.mkdtemp('chromedriver_logs')
jbudorick 2016/05/04 18:10:43 Does this get cleaned up somewhere? Should it?
42 return self._chromedriver_log_dir
43
44 def get_chromedriver_platform(self, is_android):
45 """Gets the platform name for chromedriver."""
46 bitness = '32'
jbudorick 2016/05/04 18:10:42 nit: 'bitness'? Why not just 'bits'?
mikecase (-- gone --) 2016/06/16 17:55:08 The reason is because that is what the scripts I c
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:
jbudorick 2016/05/04 18:10:42 Can you just do this at the beginning?
mikecase (-- gone --) 2016/06/16 17:55:08 Done
51 platform = 'android'
52 return platform
53
54 def archive_prebuilts(self, commit_position):
55 """Uploads the prebuilts to google storage."""
56 output_zip_path = self.m.path.mkdtemp('zip_to_archive').join(
jbudorick 2016/05/04 18:10:43 Same question w.r.t. cleaning up the temporary dir
mikecase (-- gone --) 2016/06/16 17:55:08 I made sure I clean up all temp dirs now.
57 'chromedriver.zip')
58
59 pkg = self.m.zip.make_package(
60 root=self.m.chromium.output_dir, output=output_zip_path)
61 pkg.add_file(path=self.m.chromium.output_dir.join('chromedriver'))
62 pkg.zip(step_name='zip chromedriver')
63
64 self.m.gsutil.upload(
65 name='archive prebuilt',
66 source=output_zip_path,
67 bucket=GS_PREBUILTS_URL,
68 dest='r%s.zip' % commit_position,
69 link_name='Prebuilt chromedriver r%s.zip' % commit_position)
70
71 def download_prebuilts(self):
72 """Downloads the most recent prebuilts from google storage."""
73 prebuilt_dir = self.m.path.mkdtemp('prebuilt')
74 zipfile = prebuilt_dir.join('build.zip')
75 unzip_dir = prebuilt_dir.join('unzipped')
76
77 self.m.gsutil.download_latest_file(base_url=GS_PREBUILTS_URL,
78 partial_name=GS_PREBUILTS_URL + '/r',
79 destination=zipfile,
80 name='download latest prebuilt')
81 self.m.zip.unzip(step_name='unzip prebuilt',
82 zip_file=zipfile,
83 output=unzip_dir)
84 self.m.file.move(name='move prebuilt',
85 source=unzip_dir.join('chromedriver'),
86 dest=self.m.chromium.output_dir,
87 infra_step=False)
88
89 def archive_server_logs(self):
90 """Uploads chromedriver server logs to google storage."""
91 server_logs = self.m.file.glob(
92 name='glob search for server logs',
93 pattern=self.chromedriver_log_dir.join('*'),
94 test_data=[self.chromedriver_log_dir.join('chromedriver_123'),
95 self.chromedriver_log_dir.join('chromedriver_456'),
96 self.chromedriver_log_dir.join('chromedriver_789')])
97 with self.m.step.nest('upload chromedriver server logs'):
98 for server_log in server_logs:
99 self.m.gsutil.upload(name='uploading %s' % server_log,
100 source=server_log,
101 bucket=GS_SERVER_LOGS_URL,
102 dest=self.m.path.basename(server_log),
103 link_name='server log %s' % server_log)
104
105 def get_test_results_log(self, chromedriver_platform):
106 """Gets the test results log for the given chromedriver platform.
107
108 Args:
109 chromedriver_platform: The platform that the test results log is for.
110
111 Returns:
112 A dictionary where the keys are commit positions and the values are
113 booleans indicating whether the tests passed.
114 """
115 log_name = TEST_LOG_FORMAT % chromedriver_platform
116 temp_log = self.m.path.mkdtemp('results_log').join(log_name)
117 try:
118 self.m.gsutil.download(name='download results log',
119 source=log_name,
120 bucket=GS_CHROMEDRIVER_DATA_BUCKET,
121 dest=temp_log)
122 json_data = self.m.file.read(name='read results log file',
123 path=temp_log,
124 test_data='{"2222222222": true}')
125 json_dict = self.m.json.loads(json_data)
126 except self.m.step.StepFailure:
127 json_dict = {}
128 return { int(k): v for k, v in json_dict.items() }
jbudorick 2016/05/04 18:10:43 nit: no spaces after { & before }
mikecase (-- gone --) 2016/06/16 17:55:08 done
129
130 def put_test_results_log(self, chromedriver_platform, test_results_log):
131 """Pushes the given test results log to google storage."""
132 temp_dir = self.m.path.mkdtemp('results_log')
133 log_name = TEST_LOG_FORMAT % chromedriver_platform
134 log_path = temp_dir.join(log_name)
135 self.m.file.write(name='write results log to file %s' % log_name,
136 path=log_path,
137 data=self.m.json.dumps(test_results_log))
138 self.m.gsutil.upload(name='upload results log %s' % log_name,
139 source=log_path,
140 bucket=GS_CHROMEDRIVER_DATA_BUCKET,
141 dest=log_name,
142 link_name='results log')
143
144 def update_test_results_log(self, chromedriver_platform,
145 commit_position, passed):
146 """Updates the test results log stored in GS for the given platform.
147
148 Args:
149 chromedriver_platform: The platform name.
150 commit_position: The commit position number.
151 passed: Boolean indicating whether the tests passed at this
152 commit position.
153 """
154 log = self.get_test_results_log(chromedriver_platform)
155 while len(log) > 500: # pragma: no cover
jbudorick 2016/05/04 18:10:43 yikes
mikecase (-- gone --) 2016/06/16 17:55:08 haha. This was ported from the chromedriver script
156 del log[min(log.keys())]
157 if commit_position not in log:
158 log[commit_position] = bool(passed)
159 self.put_test_results_log(chromedriver_platform, log)
160 else:
161 raise self.m.step.StepFailure(
162 'Results already exist for commit position %s' % commit_position)
163
164 def get_version(self):
165 """Get the current chromedriver version."""
166 version_file = self.chromedriver_dir.join('VERSION')
jbudorick 2016/05/04 18:10:43 Is VERSION just a text file with a string version
mikecase (-- gone --) 2016/06/16 17:55:08 yes. But this function is now gone as I am only ad
167 return self.m.file.read(name='read version file',
168 path=version_file,
169 test_data="9.99").strip()
170
171 def get_supported_chrome_versions(self):
172 """Get the minimum and maximum supported Chrome versions.
173
174 Returns:
175 A tuple of the form (min_version, max_version).
176 """
177 # Minimum supported Chrome version is embedded as:
178 # const int kMinimumSupportedChromeVersion[] = {27, 0, 1453, 0};
179 with self.m.step.nest('Getting supported chrome versions'):
180 version_cc_file_name = 'version.cc'
181 version_cc_file_data = self.m.file.read(
182 name='read %s for min supported chrome' % version_cc_file_name,
183 path=self.chromedriver_dir.join('chrome', version_cc_file_name),
184 test_data='int kMinimumSupportedChromeVersion[] = {42, 0, 2311, 0};')
185 min_version_re = re.compile(
186 r'int kMinimumSupportedChromeVersion\[\] = {(\d+), \d+, \d+, \d+};')
jbudorick 2016/05/04 18:10:43 - module-scope constant, plz - I'm not crazy about
mikecase (-- gone --) 2016/06/16 17:55:08 This is a copy of the implementation from the Chro
187 for line in version_cc_file_data.splitlines():
188 m = min_version_re.match(line)
189 if m:
190 chrome_min_version = m.group(1)
191 break
192 else: # pragma: no cover
jbudorick 2016/05/04 18:10:42 This should be coverable in example.py.
193 chrome_min_version = None
194 self.m.step.active_result.presentation.step_text = (
195 'Error parsing chrome min version from %s file.'
196 % version_cc_file_name)
197 self.m.step.active_result.presentation.status = self.m.step.FAILURE
198
199 version_file_name = 'VERSION'
200 version_file_data = self.m.file.read(
201 name='read %s for max supported chrome' % version_file_name,
202 path=self.m.path['checkout'].join('chrome', version_file_name),
203 test_data='MAJOR=46\nMINOR=0\nBUILD=2469\nPATCH=0')
204 max_version_re = re.compile(r'MAJOR=(\d+)')
jbudorick 2016/05/04 18:10:42 module-scope constant here too, plz
205 for line in version_file_data.splitlines():
206 m = max_version_re.match(line)
207 if m:
208 chrome_max_version = m.group(1)
209 break
210 else: # pragma: no cover
jbudorick 2016/05/04 18:10:42 This should also be coverable in example.py.
211 chrome_max_version = None
212 self.m.step.active_result.presentation.step_text = (
213 'Error parsing chrome max version from %s file.'
214 % version_file_name)
215 self.m.step.active_result.presentation.status = self.m.step.FAILURE
216
217 return (chrome_min_version, chrome_max_version)
218
219 def commit_position_state(self, test_results_log, commit_position):
220 """Check the state of tests at a given commit position.
221
222 Considers tests as having passed at a commit position if they passed at
223 revisons both before and after.
224
225 Args:
226 test_results_log: A test results log dictionary from
227 |get_test_results_log|.
228 commit_position: The commit position to check at.
229
230 Returns:
231 'passed', 'failed', or 'unknown'
232 """
233 assert isinstance(commit_position, int), (
234 'The commit position must be an int')
235
236 keys = sorted(test_results_log.keys())
jbudorick 2016/05/04 18:10:43 nit: a few blank lines in here would make this mor
237 # Return passed if the exact commit position passed on Android.
238 if commit_position in test_results_log:
239 return 'passed' if test_results_log[commit_position] else 'failed'
jbudorick 2016/05/04 18:10:42 You have 'failed' three times in this function. As
240 # Tests were not run on this exact commit position on Android.
241 index = bisect.bisect_right(keys, commit_position)
242 # Tests have not yet run on Android at or above this commit position.
243 if index == len(test_results_log):
244 return 'unknown'
245 # No log exists for any prior commit position, assume it failed.
246 if index == 0:
247 return 'failed' # pragma: no cover
248 # Return passed if the commit position on both sides passed.
249 if test_results_log[keys[index]] and test_results_log[keys[index - 1]]:
250 return 'passed' # pragma: no cover
251 return 'failed'
252
253 def archive_good_build(self, chromedriver_platform, commit_position):
254 """Archive chromedriver binary if the build is green."""
255 assert chromedriver_platform != 'android'
jbudorick 2016/05/04 18:10:42 ?
256 server_name = 'chromedriver'
257 if self.m.platform.is_win:
258 server_name += '.exe'
259
260 output_zip_path = self.m.path.mkdtemp(
jbudorick 2016/05/04 18:10:43 temp directory cleanup, etc
261 'zip_to_archive').join('chromedriver.zip')
262
263 pkg = self.m.zip.make_package(root=self.m.chromium.output_dir,
264 output=output_zip_path)
265 pkg.add_file(path=self.m.chromium.output_dir.join(server_name))
266 pkg.zip(step_name='zip chromedriver')
267
268 build_name = 'chromedriver_%s_%s.%s.zip' % (
269 chromedriver_platform, self.get_version(), commit_position)
270 self.m.gsutil.upload(name='archive good build',
271 source=output_zip_path,
272 bucket=GS_CONTINUOUS_URL,
273 dest=build_name,
274 link_name=build_name)
275
276 latest_build_file = self.m.path.mkdtemp(
277 'latest_build_file_dir').join('latest_build')
278 latest_url = 'latest_%s' % chromedriver_platform
279 self.m.file.write(name='write latest build version',
280 path='latest_build_file',
281 data=build_name)
282 self.m.gsutil.upload(name='upload latest build version',
283 source=latest_build_file,
284 bucket=GS_CONTINUOUS_URL,
285 dest=latest_url,
286 link_name='latest build version')
287
288 def was_released(self, version, chromedriver_platform):
289 """Check if the specified version is released for the given platform."""
290 try:
291 step_result = self.m.gsutil.list(
292 name='list chromedriver versions',
293 url='gs://%s/%s/chromedriver_%s.zip' % (
294 GS_CHROMEDRIVER_BUCKET, version, chromedriver_platform))
295 return True
296 except self.m.step.StepFailure:
297 return False
298
299 def maybe_release(self, chromedriver_platform):
300 """Releases a release candidate if conditions are right."""
301 assert chromedriver_platform != 'android'
jbudorick 2016/05/04 18:10:43 ?
302 version = self.get_version()
303 # Check if the current version has already been released.
304 if self.was_released(version, chromedriver_platform):
305 return
306 # Fetch Android test results.
307 android_test_results = self.get_test_results_log('android')
308 # Fetch release candidates.
309 step_result = self.m.gsutil.list(
310 name='list release candidates',
311 url='gs://%s/chromedriver_%s_%s*' % (
312 GS_CONTINUOUS_URL, chromedriver_platform, version),
313 stdout=self.m.raw_io.output(),
314 step_test_data=lambda: self.m.raw_io.test_api.stream_output(
315 'test/dir/chromedriver_linux64_9.99.2222222222.zip',
316 stream='stdout'))
317 output = step_result.stdout
318
319 candidate_pattern = re.compile(r'.*/chromedriver_%s_%s\.(\d+)\.zip$' % (
320 chromedriver_platform, version))
321 candidates = []
322 for line in output.strip().split('\n'):
jbudorick 2016/05/04 18:10:42 splitlines?
323 result = candidate_pattern.match(line)
324 if result:
325 candidates.append(int(result.group(1)))
326
327 # Release the latest candidate build that passed Android, if any.
328 # In this way, if a hot fix is needed, we can delete the release from
329 # the chromedriver bucket instead of bumping up the release version number.
330 candidates.sort(reverse=True)
331 # TODO(mikecase): Add some form of logging to indicate which candidates
332 # failed the tests and which candidates have no test results at all.
333 for commit_position in candidates:
334 android_result = self.commit_position_state(android_test_results,
335 commit_position)
336 if android_result == 'passed':
337 step_result.presentation.step_text = (
338 'Android tests passed at commit position %s' % commit_position)
339 candidate = 'chromedriver_%s_%s.%s.zip' % (
340 chromedriver_platform, version, commit_position)
341 self.release(GS_CONTINUOUS_URL, candidate,
342 version, chromedriver_platform)
343 break
jbudorick 2016/05/04 18:10:43 break at the end of a function...?
344
345 def release(self, bucket, build, version, chromedriver_platform):
346 """Releases the given candidate build."""
347 release_name = 'chromedriver_%s.zip' % chromedriver_platform
348 temp_dir = self.m.path.mkdtemp('temp_dir')
349 zip_path = temp_dir.join(build)
350 self.m.gsutil.download(name='download release build',
351 source=build,
352 bucket=bucket,
353 dest=zip_path)
354 if self.m.platform.is_linux:
355 unzip_dir = temp_dir.join('unzipped')
356 self.m.zip.unzip(step_name='unzip prebuilt',
357 zip_file=zip_path,
358 output=unzip_dir)
359 server_path = unzip_dir.join('chromedriver')
360 zip_path = unzip_dir.join('chromedriver.zip')
361 self.m.step(name='strip', cmd=['strip', server_path])
362
363 pkg = self.m.zip.make_package(root=unzip_dir, output=zip_path)
364 pkg.add_file(path=server_path)
365 pkg.zip(step_name='zip chromedriver')
366
367 self.m.gsutil.upload(
368 name='upload release build',
369 source=zip_path,
370 bucket=GS_CHROMEDRIVER_BUCKET,
371 dest='%s/%s' % (version, release_name))
372
373 self.maybe_upload_release_notes(version)
374 self.maybe_update_latest_release(version)
375
376 def get_web_page_content(self, url, test_data=''):
jbudorick 2016/05/04 18:10:43 What the?
377 """Return the content of the web page specified by the given url."""
378 step_result = self.m.python.inline('get webpage content', program="""
379 import sys
380 import urllib2
381 print urllib2.urlopen(sys.argv[1])
382 """,
383 args=[url],
384 stdout=self.m.raw_io.output(),
385 step_test_data=(lambda: self.m.raw_io.test_api.stream_output(
386 test_data, stream='stdout')))
387 return step_result.stdout
388
389 def maybe_upload_release_notes(self, version):
390 """Upload release notes if conditions are right."""
391 # Check if the current version has already been released.
392 notes_name = 'notes.txt'
393 notes_bucket = GS_CHROMEDRIVER_BUCKET
394 notes_url = '%s/%s' % (version, notes_name)
395 prev_version = '.'.join([version.split('.')[0],
396 str(int(version.split('.')[1]) - 1)])
397 prev_notes_url = '%s/%s' % (prev_version, notes_name)
398
399 try:
400 step_result = self.m.gsutil.list(
401 name='list version notes',
402 url='gs://%s/%s' % (notes_bucket, notes_url))
403 return
404 except self.m.step.StepFailure:
405 pass
406
407 fixed_issues = []
408 query = ('https://code.google.com/p/chromedriver/issues/csv?'
409 'can=1&q=label%%3AChromeDriver-%s&colspec=ID%%20Summary' % version)
410 issues = self.get_web_page_content(
411 query, test_data=(
412 '"ID","Summary","AllLabels"\n'
413 '"1000","Bug Summary","ChromeDriver-%s, Hotlist-GoodFirstBug"\n'
414 % version))
415 for issue in csv.reader(issues.split('\n')[1:]):
416 if not issue: # pragma: no cover
417 continue
418 else:
419 issue_id = issue[0]
420 desc = issue[1]
421 labels = issue[2].split(', ')
422 labels.remove('ChromeDriver-%s' % version)
423 if 'Hotlist-GoodFirstBug' in labels:
424 labels.remove('Hotlist-GoodFirstBug')
425 fixed_issues += ['Resolved issue %s: %s [%s]' %
426 (issue_id, desc, labels)]
427
428 temp_notes_file = self.m.path.mkdtemp('temp_notes').join('temp_notes')
429
430 try:
431 self.m.gsutil.download(name='download prev notes',
432 source=prev_notes_url,
433 bucket=notes_bucket,
434 dest=temp_notes_file)
435 old_notes = self.m.file.read(name='read old notes',
436 path=temp_notes_file)
437 except self.m.step.StepFailure:
438 old_notes = ''
439
440 new_notes = '----------ChromeDriver v%s (%s)----------\n%s\n%s\n\n%s' % (
441 version, datetime.date.today().isoformat(),
442 'Supports Chrome v%s-%s' % self.get_supported_chrome_versions(),
443 '\n'.join(fixed_issues),
444 old_notes)
445 self.m.file.write(name='write new notes',
446 path=temp_notes_file,
447 data=new_notes)
448 self.m.gsutil.upload(name='upload new notes',
449 source=temp_notes_file,
450 bucket=notes_bucket,
451 dest=notes_url)
452
453 def maybe_update_latest_release(self, version):
454 """Update the file LATEST_RELEASE with the latest release version number."""
455 latest_release_filename = 'LATEST_RELEASE'
456 latest_release_url = 'gs://%s/%s' % (
457 GS_CHROMEDRIVER_BUCKET, latest_release_filename)
458
459 # Check if LATEST_RELEASE is up-to-date.
460 step_result = self.m.gsutil.cat(
461 name='check latest release',
462 url=latest_release_url,
463 stdout=self.m.raw_io.output(),
464 step_test_data=lambda: self.m.raw_io.test_api.stream_output(
465 '9.98', stream='stdout'))
466 latest_released_version = step_result.stdout
467
468 if version == latest_released_version:
469 return
470
471 # Check if chromedriver was released on all supported platforms.
472 supported_platforms = ['linux32', 'linux64', 'mac32', 'win32']
473 for platform in supported_platforms:
474 if not self.was_released(version, platform):
475 return # pragma: no cover
476
477 temp_latest_release_filename = self.m.path.mkdtemp(
478 'temp_notes').join('temp_notes')
479 self.m.file.write(name='write latest release number',
480 path=temp_latest_release_filename,
481 data=version)
482 self.m.gsutil.upload(name='upload latest release number',
483 source=temp_latest_release_filename,
484 bucket=GS_CHROMEDRIVER_BUCKET,
485 dest=latest_release_filename)
486
487 def add_tools_to_path(self, env):
488 """Add some tools like Ant and Java to PATH for testing steps to use."""
489 paths = []
490 error_message = ''
491 if self.m.platform.is_win:
492 paths = [
493 # Path to Ant and Java, required for the java acceptance tests.
494 'C:\\Program Files (x86)\\Java\\ant\\bin',
495 'C:\\Program Files (x86)\\Java\\jre\\bin',
496 ]
497 error_message = ('Java test steps will fail as expected and '
498 'they can be ignored.\n'
499 'Ant, Java or others might not be installed on bot.\n'
500 'Please refer to page "WATERFALL" on site '
501 'go/chromedriver.\n'
502 '\n'
503 'Missing Directories\n'
504 '%s')
505 if paths:
506 # Empty step to let us log errors for adding tools to path.
507 step_result = self.m.step('add tools to path', [])
508 missing_directories = []
509 for path in paths:
510 if (not self.m.path.exists(path) or
511 not self.m.file.listdir(name='tools', path=path)):
512 missing_directories.append(path)
513 if missing_directories:
514 step_result.presentation.step_text = (
515 error_message % '\n'.join(missing_directories))
516 return
517
518 env['PATH'] = self.m.path.pathsep.join(
519 [env['PATH']] + paths) # pragma: no cover
520
521 def generate_test_command(self, script, chromedriver, ref_chromedriver=None,
522 chrome=None, chrome_version=None,
523 android_package=None, build_type=None,
524 verbose=None):
525 cmd = [
526 script,
527 '--chromedriver', chromedriver,
528 '--log-dir', str(self.chromedriver_log_dir)
529 ]
530 if ref_chromedriver:
531 cmd.extend(['--reference-chromedriver', ref_chromedriver])
532 if chrome:
533 cmd.extend(['--chrome', chrome])
534 if chrome_version:
535 cmd.extend(['--chrome-version', chrome_version])
536 if build_type:
537 cmd.extend(['--build-type', build_type])
538 if verbose:
539 cmd.extend(['--verbose'])
540 if android_package:
541 cmd = ['xvfb-run', '-a'] + cmd
542 cmd.extend(['--android-package', android_package])
543 return cmd
544
545 def run_python_tests(self, chromedriver, ref_chromedriver,
546 chrome=None, chrome_version=None,
547 chrome_version_name=None, android_package=None,
548 build_type=None, **kwargs):
549 version_info = ''
550 if chrome_version_name:
551 version_info = '(%s)' % chrome_version_name
552 self.m.step('python_tests%s' % version_info,
553 self.generate_test_command('run_py_tests.py', chromedriver,
554 ref_chromedriver=ref_chromedriver,
555 chrome=chrome,
556 chrome_version=chrome_version,
557 android_package=android_package,
558 build_type=build_type),
559 **kwargs)
560
561 def run_java_tests(self, chromedriver, chrome=None, chrome_version=None,
562 chrome_version_name=None, android_package=None,
563 build_type=None, verbose=False, **kwargs):
564 version_info = ''
565 if chrome_version_name:
566 version_info = '(%s)' % chrome_version_name
567 self.m.step('java_tests%s' % version_info,
568 self.generate_test_command('run_java_tests.py',
569 chromedriver,
570 ref_chromedriver=None,
571 chrome=chrome,
572 chrome_version=chrome_version,
573 android_package=android_package,
574 build_type=build_type,
575 verbose=verbose),
576 **kwargs)
577
578 def run_cpp_tests(self, cpp_tests):
579 self.m.step('chromedriver_tests', [cpp_tests])
580
581 def download_chrome(self, version_name, revision, download_site):
582 try:
583 temp_dir = self.m.path.mkdtemp('chrome')
584 return (temp_dir, self.archive.download_chrome(
585 revision, temp_dir, download_site))
586 except self.m.step.StepFailure:
587 return (None, None)
588
589 def kill_chromes(self):
590 chrome_map = {
591 'win': 'chrome.exe',
592 'mac': 'Chromium',
593 'linux': 'chrome',
594 }
595 if self.m.platform.is_win:
596 cmd = ['taskkill', '/F', '/IM']
597 else:
598 cmd = ['killall', '-9']
599 cmd.append(chrome_map[self.m.platform.name])
600 self.m.step('kill chromes', cmd)
601
602 def run_all_tests(self, android_packages=None):
603 exe_postfix = ''
jbudorick 2016/05/04 18:10:42 I think this is cleaner if you set the affected va
604 if self.m.platform.is_win:
605 exe_postfix = '.exe'
606 cpp_tests_name = 'chromedriver_tests' + exe_postfix
607 server_name = 'chromedriver' + exe_postfix
608
609 required_build_outputs = [server_name]
610 if not android_packages:
611 required_build_outputs += [cpp_tests_name]
612 build_type = self.m.path.basename(self.m.chromium.output_dir)
613
614 test_env = {'PATH': '%(PATH)s'}
615 self.add_tools_to_path(test_env)
616
617 chromedriver = self.m.chromium.output_dir.join(server_name)
618 platform_name = self.m.platform.name
619 if self.m.platform.is_linux and self.m.platform.bits == 64:
620 platform_name = 'linux64'
621 ref_chromedriver = self.m.path.join(
622 self.m.path['checkout'],
623 'chrome', 'test', 'chromedriver', 'third_party', 'java_tests',
624 'reference_builds', 'chromedriver_%s%s' % (platform_name, exe_postfix))
625
626 failure = False
627 if android_packages:
628 test_env['PATH'] = self.m.path.pathsep.join([
629 test_env['PATH'],
630 str(self.m.path['checkout'].join(
631 'chrome', 'test', 'chromedriver', 'chrome'))])
632 for package in android_packages:
633 try:
634 with self.m.step.defer_results():
635 self.run_python_tests(chromedriver,
636 ref_chromedriver,
637 chrome_version_name=package,
638 android_package=package,
639 build_type=build_type,
640 env=test_env)
641 self.run_java_tests(chromedriver,
642 chrome_version_name=package,
643 android_package=package,
644 build_type=build_type,
645 verbose=True,
646 env=test_env)
647 except recipe_api.AggregatedStepFailure:
648 failure = True
649 else:
650 latest_snapshot_revision = self.archive.get_latest_snapshot_version()
651
652 versions = [
653 ['HEAD', latest_snapshot_revision],
654 ['47', self.archive.CHROME_47_REVISION],
655 ['46', self.archive.CHROME_46_REVISION],
656 ['45', self.archive.CHROME_45_REVISION],
657 ]
658 for version in versions:
659 download_site = chromium_archive.Url.GS_CHROMIUM_CONTINUOUS_URL
660 version_name = version[0]
661 if version_name == 'HEAD':
662 version_name = version[1]
663 download_site = self.archive.get_snapshot_download_site()
664 temp_dir, chrome_path = self.download_chrome(
665 version_name, version[1], download_site)
666 try:
667 with self.m.step.defer_results():
668 self.run_python_tests(chromedriver,
669 ref_chromedriver,
670 chrome=chrome_path,
671 chrome_version=version[0],
672 chrome_version_name='v%s' % version_name,
673 build_type=build_type)
674 self.run_java_tests(chromedriver, chrome=chrome_path,
675 chrome_version=version[0],
676 chrome_version_name='v%s' % version_name,
677 build_type=build_type)
678 self.kill_chromes()
679 except recipe_api.AggregatedStepFailure:
680 failure = True
681
682 try:
683 cpp_tests = self.m.chromium.output_dir.join(cpp_tests_name)
684 self.run_cpp_tests(cpp_tests)
685 except recipe_api.StepFailure:
686 failure = True
687 return not failure
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698