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

Side by Side Diff: scripts/slave/unittests/gatekeeper_ng_test.py

Issue 172523005: Keep track of hashes triggered instead of builds. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Fix typos. Created 6 years, 10 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
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Copyright 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Unit tests for gatekeeper_ng.py. 6 """Unit tests for gatekeeper_ng.py.
7 7
8 This is a basic check that gatekeeper_ng.py can properly interpret builds and 8 This is a basic check that gatekeeper_ng.py can properly interpret builds and
9 close the tree. 9 close the tree.
10 10
11 """ 11 """
12 12
13 # Needs to be at the top, otherwise coverage will spit nonsense. 13 # Needs to be at the top, otherwise coverage will spit nonsense.
14 import utils 14 import utils
15 15
16 import contextlib 16 import contextlib
17 import json 17 import json
18 import mock 18 import mock
19 import os 19 import os
20 import StringIO 20 import StringIO
21 import sys 21 import sys
22 import tempfile 22 import tempfile
23 import unittest 23 import unittest
24 import urllib2 24 import urllib2
25 import urlparse 25 import urlparse
26 26
27 import test_env # pylint: disable=W0403,W0611 27 import test_env # pylint: disable=W0403,W0611
28 28
29 from slave import gatekeeper_ng 29 from slave import gatekeeper_ng
30 from slave import gatekeeper_ng_db
30 31
31 32
32 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) 33 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
33 34
34 35
35 class BuildLog(object): 36 class BuildLog(object):
36 def __init__(self, name, fp=None, string=None, logjson=None): 37 def __init__(self, name, fp=None, string=None, logjson=None):
37 self.name = name 38 self.name = name
38 self.fp = fp 39 self.fp = fp
39 self.string = string 40 self.string = string
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 130
130 self.status_url = 'https://chromium-status.appspot.com/status' 131 self.status_url = 'https://chromium-status.appspot.com/status'
131 self.mailer_url = 'https://chromium-build.appspot.com/mailer/email' 132 self.mailer_url = 'https://chromium-build.appspot.com/mailer/email'
132 self.handle_url_str(self.mailer_url, '') 133 self.handle_url_str(self.mailer_url, '')
133 self.handle_url_str(self.status_url, 'the status') 134 self.handle_url_str(self.status_url, 'the status')
134 135
135 self.master_url_root = 'http://build.chromium.org/p/' 136 self.master_url_root = 'http://build.chromium.org/p/'
136 self.masters = [self.create_generic_build_tree('Chromium FYI', 137 self.masters = [self.create_generic_build_tree('Chromium FYI',
137 'chromium.fyi')] 138 'chromium.fyi')]
138 139
140 self.build_db_file = self.fill_tempfile('{}')
139 self.gatekeeper_file = self.fill_tempfile('{}') 141 self.gatekeeper_file = self.fill_tempfile('{}')
140 self.email_secret_file = self.fill_tempfile('seekrit') 142 self.email_secret_file = self.fill_tempfile('seekrit')
141 self.status_secret_file = self.fill_tempfile('reindeerflotilla') 143 self.status_secret_file = self.fill_tempfile('reindeerflotilla')
142 144
143 self._gatekeeper_config = None 145 self._gatekeeper_config = None
144 146
145 def fill_tempfile(self, content): 147 def fill_tempfile(self, content):
146 fd, filename = tempfile.mkstemp() 148 fd, filename = tempfile.mkstemp()
147 os.write(fd, content) 149 os.write(fd, content)
148 os.close(fd) 150 os.close(fd)
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 return Build(number, [step0, step1, step2, step3], committers) 225 return Build(number, [step0, step1, step2, step3], committers)
224 226
225 def create_generic_build_tree(self, master_title, master_url_chunk): 227 def create_generic_build_tree(self, master_title, master_url_chunk):
226 build = GatekeeperTest.create_generic_build(1, ['a_committer@chromium.org']) 228 build = GatekeeperTest.create_generic_build(1, ['a_committer@chromium.org'])
227 229
228 builder = Builder('mybuilder', [build]) 230 builder = Builder('mybuilder', [build])
229 231
230 return Master(master_title, self.master_url_root + master_url_chunk, 232 return Master(master_title, self.master_url_root + master_url_chunk,
231 [builder]) 233 [builder])
232 234
233 def call_gatekeeper(self): 235 def call_gatekeeper(self, build_db=None, json=None): # pylint: disable=W0621
234 """Sets up handlers for all the json and actually calls gatekeeper.""" 236 """Sets up handlers for all the json and actually calls gatekeeper."""
237 self.url_calls = []
235 self.handle_build_tree(self.masters) 238 self.handle_build_tree(self.masters)
236 ret = gatekeeper_ng.main() 239 json = json or self.gatekeeper_file
240 self._gatekeeper_config = self._gatekeeper_config or {}
241 if not build_db:
242 build_db = gatekeeper_ng_db.gen_db(masters={
243 self.masters[0].url: {
244 'mybuilder': {
245 0: gatekeeper_ng_db.gen_build(finished=True)
246 }
247 }
248 })
249
250 with open(self.build_db_file, 'w') as f:
251 gatekeeper_ng_db.convert_db_to_json(build_db, self._gatekeeper_config, f)
252
253 old_argv = sys.argv[:]
254 sys.argv.extend(['--build-db=%s' % self.build_db_file,
255 '--json', json])
256
257 try:
258 ret = gatekeeper_ng.main()
259 finally:
260 sys.argv = old_argv
261
237 if ret != 0: 262 if ret != 0:
238 raise ValueError('return code was %d' % ret) 263 raise ValueError('return code was %d' % ret)
239 264
240 # Return urls as a convenience. 265 # Return urls as a convenience.
241 return [call['url'] for call in self.url_calls] 266 return [call['url'] for call in self.url_calls]
242 267
268
269 def process_build_db(self, master, builder):
270 """Reads the build_db from a file and splits out finished/unfinished."""
271 new_build_db = gatekeeper_ng_db.get_build_db(self.build_db_file)
272 builds = new_build_db.masters[master][builder]
273 finished_new_builds = dict(
274 (k, v) for k, v in builds.iteritems() if v.finished)
275 unfinished_new_builds = dict(
276 (k, v) for k, v in builds.iteritems() if not v.finished)
277 return unfinished_new_builds, finished_new_builds
278
279
243 @contextlib.contextmanager 280 @contextlib.contextmanager
244 def gatekeeper_config_editor(self): 281 def gatekeeper_config_editor(self):
282 """Wrapper to edit the gatekeeper_config, then reserialize it."""
245 if not self._gatekeeper_config: 283 if not self._gatekeeper_config:
246 with open(self.gatekeeper_file) as f: 284 with open(self.gatekeeper_file) as f:
247 self._gatekeeper_config = json.load(f) 285 self._gatekeeper_config = json.load(f)
248 286
249 yield self._gatekeeper_config 287 yield self._gatekeeper_config
250 288
251 with open(self.gatekeeper_file, 'w') as f: 289 with open(self.gatekeeper_file, 'w') as f:
252 json.dump(self._gatekeeper_config, f) 290 json.dump(self._gatekeeper_config, f)
253 self._gatekeeper_config = None 291 self._gatekeeper_config = None
254 else: 292 else:
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 def handle_url_json(self, url, data): 358 def handle_url_json(self, url, data):
321 """Add a json object to handle a mocked URL.""" 359 """Add a json object to handle a mocked URL."""
322 buf = StringIO.StringIO() 360 buf = StringIO.StringIO()
323 json.dump(data, buf) 361 json.dump(data, buf)
324 buf.seek(0) 362 buf.seek(0)
325 self.handle_url_fp(url, buf) 363 self.handle_url_fp(url, buf)
326 364
327 365
328 #### Email and status. 366 #### Email and status.
329 367
330 def testBasicURLQuery(self):
331 """Check that things are basically sane."""
332 sys.argv.extend([m.url for m in self.masters])
333 sys.argv.extend(['--skip-build-db-update',
334 '--json', self.gatekeeper_file,
335 '--no-email-app'])
336
337 self.handle_build_tree([self.masters[0]])
338 gatekeeper_ng.main()
339
340 def testIgnoreNoGatekeeper(self): 368 def testIgnoreNoGatekeeper(self):
341 """Check that logs aren't read unless the builder is noted in the config.""" 369 """Check that logs aren't read unless the builder is noted in the config."""
342 370
343 sys.argv.extend([m.url for m in self.masters]) 371 sys.argv.extend([m.url for m in self.masters])
344 sys.argv.extend(['--skip-build-db-update', 372 sys.argv.extend(['--skip-build-db-update',
345 '--json', self.gatekeeper_file,
346 '--no-email-app']) 373 '--no-email-app'])
347 374
348 self.add_gatekeeper_section(self.masters[0].url, 375 self.add_gatekeeper_section(self.masters[0].url,
349 self.masters[0].builders[0].name, 376 self.masters[0].builders[0].name,
350 {}) 377 {})
351 378
352 urls = self.call_gatekeeper() 379 urls = self.call_gatekeeper()
353 self.assertEquals(urls, [self.masters[0].url + '/json']) 380 self.assertEquals(urls, [self.masters[0].url + '/json'])
354 381
355 def testIgnoreSuccessfulBuildNoGatekeeperSteps(self):
356 """If gatekeeper_spec doesn't have any annotations, don't fail build."""
357 sys.argv.extend([m.url for m in self.masters])
358 sys.argv.extend(['--skip-build-db-update',
359 '--json', self.gatekeeper_file,
360 '--email-app-secret-file=%s' % self.email_secret_file])
361
362
363 self.handle_build_tree([self.masters[0]])
364 gatekeeper_ng.main()
365 urls = [call['url'] for call in self.url_calls]
366 self.assertNotIn(self.mailer_url, urls)
367
368 def testFailedBuildDetected(self): 382 def testFailedBuildDetected(self):
369 """Test that an erroneous build result closes the tree.""" 383 """Test that an erroneous build result closes the tree."""
370 sys.argv.extend([m.url for m in self.masters]) 384 sys.argv.extend([m.url for m in self.masters])
371 sys.argv.extend(['--skip-build-db-update', 385 sys.argv.extend(['--skip-build-db-update',
372 '--json', self.gatekeeper_file,
373 '--email-app-secret-file=%s' % self.email_secret_file]) 386 '--email-app-secret-file=%s' % self.email_secret_file])
374 387
375 self.masters[0].builders[0].builds[0].results = 3 388 self.masters[0].builders[0].builds[0].results = 3
376 self.add_gatekeeper_master_config(self.masters[0].url, 389 self.add_gatekeeper_master_config(self.masters[0].url,
377 {'respect_build_status': True}) 390 {'respect_build_status': True})
378 self.add_gatekeeper_section(self.masters[0].url, 391 self.add_gatekeeper_section(self.masters[0].url,
379 self.masters[0].builders[0].name, 392 self.masters[0].builders[0].name,
380 {}, 393 {},
381 idx=0) 394 idx=0)
382 395
383 self.handle_url_str(self.mailer_url, '') 396 self.call_gatekeeper()
384
385 self.handle_build_tree([self.masters[0]])
386 gatekeeper_ng.main()
387 397
388 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 398 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
389 mailer_data = GatekeeperTest.decode_param_json( 399 mailer_data = GatekeeperTest.decode_param_json(
390 self.url_calls[-1]['params']) 400 self.url_calls[-1]['params'])
391 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 401 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
392 402
393 def testFailedBuildNoEmail(self): 403 def testFailedBuildNoEmail(self):
394 """Test that no email is sent if there are no watchers.""" 404 """Test that no email is sent if there are no watchers."""
395 sys.argv.extend([m.url for m in self.masters]) 405 sys.argv.extend([m.url for m in self.masters])
396 sys.argv.extend(['--skip-build-db-update', 406 sys.argv.extend(['--skip-build-db-update',
397 '--json', self.gatekeeper_file,
398 '--email-app-secret-file=%s' % self.email_secret_file]) 407 '--email-app-secret-file=%s' % self.email_secret_file])
399 408
400 409
401 self.masters[0].builders[0].builds[0].results = 3 410 self.masters[0].builders[0].builds[0].results = 3
402 self.masters[0].builders[0].builds[0].blame = [] 411 self.masters[0].builders[0].builds[0].blame = []
403 self.add_gatekeeper_master_config(self.masters[0].url, 412 self.add_gatekeeper_master_config(self.masters[0].url,
404 {'respect_build_status': True}) 413 {'respect_build_status': True})
405 self.add_gatekeeper_section(self.masters[0].url, 414 self.add_gatekeeper_section(self.masters[0].url,
406 self.masters[0].builders[0].name, 415 self.masters[0].builders[0].name,
407 {}, 416 {},
408 idx=0) 417 idx=0)
409 418
410 419
411 urls = self.call_gatekeeper() 420 urls = self.call_gatekeeper()
412 self.assertNotIn(self.mailer_url, urls) 421 self.assertNotIn(self.mailer_url, urls)
413 422
414 423
415 def testStepNonCloserFailureIgnored(self): 424 def testStepNonCloserFailureIgnored(self):
416 """Test that a non-closing failure is ignored.""" 425 """Test that a non-closing failure is ignored."""
417 sys.argv.extend([m.url for m in self.masters]) 426 sys.argv.extend([m.url for m in self.masters])
418 sys.argv.extend(['--skip-build-db-update', 427 sys.argv.extend(['--skip-build-db-update',
419 '--json', self.gatekeeper_file,
420 '--email-app-secret-file=%s' % self.email_secret_file]) 428 '--email-app-secret-file=%s' % self.email_secret_file])
421 429
422 self.masters[0].builders[0].builds[0].steps[2].results = [2, None] 430 self.masters[0].builders[0].builds[0].steps[2].results = [2, None]
423 self.add_gatekeeper_section(self.masters[0].url, 431 self.add_gatekeeper_section(self.masters[0].url,
424 self.masters[0].builders[0].name, 432 self.masters[0].builders[0].name,
425 {'closing_steps': ['step1']}) 433 {'closing_steps': ['step1']})
426 434
427 urls = self.call_gatekeeper() 435 urls = self.call_gatekeeper()
428 self.assertNotIn(self.mailer_url, urls) 436 self.assertNotIn(self.mailer_url, urls)
429 437
430 def testStepCloserFailureDetected(self): 438 def testStepCloserFailureDetected(self):
431 """Test that a failed closing step closes the tree.""" 439 """Test that a failed closing step closes the tree."""
432 sys.argv.extend([m.url for m in self.masters]) 440 sys.argv.extend([m.url for m in self.masters])
433 sys.argv.extend(['--skip-build-db-update', 441 sys.argv.extend(['--skip-build-db-update',
434 '--json', self.gatekeeper_file,
435 '--email-app-secret-file=%s' % self.email_secret_file]) 442 '--email-app-secret-file=%s' % self.email_secret_file])
436 443
437 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 444 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
438 self.add_gatekeeper_section(self.masters[0].url, 445 self.add_gatekeeper_section(self.masters[0].url,
439 self.masters[0].builders[0].name, 446 self.masters[0].builders[0].name,
440 {'closing_steps': ['step1']}) 447 {'closing_steps': ['step1']})
441 448
442 self.call_gatekeeper() 449 self.call_gatekeeper()
443 450
444 # Check that gatekeeper indeed sent an email. 451 # Check that gatekeeper indeed sent an email.
445 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 452 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
446 mailer_data = GatekeeperTest.decode_param_json( 453 mailer_data = GatekeeperTest.decode_param_json(
447 self.url_calls[-1]['params']) 454 self.url_calls[-1]['params'])
448 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 455 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
449 456
450 def testStepCloserFailureOptional(self): 457 def testStepCloserFailureOptional(self):
451 """Test that a failed closing_optional step closes the tree.""" 458 """Test that a failed closing_optional step closes the tree."""
452 sys.argv.extend([m.url for m in self.masters]) 459 sys.argv.extend([m.url for m in self.masters])
453 sys.argv.extend(['--skip-build-db-update', 460 sys.argv.extend(['--skip-build-db-update',
454 '--json', self.gatekeeper_file,
455 '--email-app-secret-file=%s' % self.email_secret_file]) 461 '--email-app-secret-file=%s' % self.email_secret_file])
456 462
457 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 463 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
458 self.add_gatekeeper_section(self.masters[0].url, 464 self.add_gatekeeper_section(self.masters[0].url,
459 self.masters[0].builders[0].name, 465 self.masters[0].builders[0].name,
460 {'closing_optional': ['step1']}) 466 {'closing_optional': ['step1']})
461 467
462 self.call_gatekeeper() 468 self.call_gatekeeper()
463 469
464 # Check that gatekeeper indeed sent an email. 470 # Check that gatekeeper indeed sent an email.
465 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 471 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
466 mailer_data = GatekeeperTest.decode_param_json( 472 mailer_data = GatekeeperTest.decode_param_json(
467 self.url_calls[-1]['params']) 473 self.url_calls[-1]['params'])
468 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 474 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
469 475
470 def testStepCloserFailureOptionalStar(self): 476 def testStepCloserFailureOptionalStar(self):
471 """Test that a failed closing_optional * step closes the tree.""" 477 """Test that a failed closing_optional * step closes the tree."""
472 sys.argv.extend([m.url for m in self.masters]) 478 sys.argv.extend([m.url for m in self.masters])
473 sys.argv.extend(['--skip-build-db-update', 479 sys.argv.extend(['--skip-build-db-update',
474 '--json', self.gatekeeper_file,
475 '--email-app-secret-file=%s' % self.email_secret_file]) 480 '--email-app-secret-file=%s' % self.email_secret_file])
476 481
477 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 482 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
478 self.add_gatekeeper_section(self.masters[0].url, 483 self.add_gatekeeper_section(self.masters[0].url,
479 self.masters[0].builders[0].name, 484 self.masters[0].builders[0].name,
480 {'closing_optional': ['*']}) 485 {'closing_optional': ['*']})
481 486
482 self.call_gatekeeper() 487 self.call_gatekeeper()
483 488
484 # Check that gatekeeper indeed sent an email. 489 # Check that gatekeeper indeed sent an email.
485 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 490 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
486 mailer_data = GatekeeperTest.decode_param_json( 491 mailer_data = GatekeeperTest.decode_param_json(
487 self.url_calls[-1]['params']) 492 self.url_calls[-1]['params'])
488 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 493 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
489 494
490 def testStepOmissionDetected(self): 495 def testStepOmissionDetected(self):
491 """Test that the lack of a closing step closes the tree.""" 496 """Test that the lack of a closing step closes the tree."""
492 sys.argv.extend([m.url for m in self.masters]) 497 sys.argv.extend([m.url for m in self.masters])
493 sys.argv.extend(['--skip-build-db-update', 498 sys.argv.extend(['--skip-build-db-update',
494 '--json', self.gatekeeper_file,
495 '--email-app-secret-file=%s' % self.email_secret_file]) 499 '--email-app-secret-file=%s' % self.email_secret_file])
496 500
497 self.add_gatekeeper_section(self.masters[0].url, 501 self.add_gatekeeper_section(self.masters[0].url,
498 self.masters[0].builders[0].name, 502 self.masters[0].builders[0].name,
499 {'closing_steps': ['step4']}) 503 {'closing_steps': ['step4']})
500 504
501 self.call_gatekeeper() 505 self.call_gatekeeper()
502 506
503 # Check that gatekeeper indeed sent an email. 507 # Check that gatekeeper indeed sent an email.
504 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 508 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
505 mailer_data = GatekeeperTest.decode_param_json(self.url_calls[-1]['params']) 509 mailer_data = GatekeeperTest.decode_param_json(self.url_calls[-1]['params'])
506 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 510 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
507 511
508 def testStepOmissionOptional(self): 512 def testStepOmissionOptional(self):
509 """Test that the lack of a closing_optional step doesn't close the tree.""" 513 """Test that the lack of a closing_optional step doesn't close the tree."""
510 sys.argv.extend([m.url for m in self.masters]) 514 sys.argv.extend([m.url for m in self.masters])
511 sys.argv.extend(['--skip-build-db-update', 515 sys.argv.extend(['--skip-build-db-update',
512 '--json', self.gatekeeper_file,
513 '--email-app-secret-file=%s' % self.email_secret_file]) 516 '--email-app-secret-file=%s' % self.email_secret_file])
514 517
515 self.add_gatekeeper_section(self.masters[0].url, 518 self.add_gatekeeper_section(self.masters[0].url,
516 self.masters[0].builders[0].name, 519 self.masters[0].builders[0].name,
517 {'closing_optional': ['step4']}) 520 {'closing_optional': ['step4']})
518 521
519 self.call_gatekeeper() 522 self.call_gatekeeper()
520 urls = self.call_gatekeeper() 523 urls = self.call_gatekeeper()
521 self.assertNotIn(self.status_url, urls) 524 self.assertNotIn(self.status_url, urls)
522 self.assertNotIn(self.mailer_url, urls) 525 self.assertNotIn(self.mailer_url, urls)
523 526
524 def testStepForgivingOmissionOptional(self): 527 def testStepForgivingOmissionOptional(self):
525 """Test that the lack of a forgiving_optional step doesn't close tree.""" 528 """Test that the lack of a forgiving_optional step doesn't close tree."""
526 sys.argv.extend([m.url for m in self.masters]) 529 sys.argv.extend([m.url for m in self.masters])
527 sys.argv.extend(['--skip-build-db-update', 530 sys.argv.extend(['--skip-build-db-update',
528 '--json', self.gatekeeper_file,
529 '--email-app-secret-file=%s' % self.email_secret_file]) 531 '--email-app-secret-file=%s' % self.email_secret_file])
530 532
531 self.add_gatekeeper_section(self.masters[0].url, 533 self.add_gatekeeper_section(self.masters[0].url,
532 self.masters[0].builders[0].name, 534 self.masters[0].builders[0].name,
533 {'forgiving_optional': ['step4']}) 535 {'forgiving_optional': ['step4']})
534 536
535 self.call_gatekeeper() 537 self.call_gatekeeper()
536 538
537 urls = self.call_gatekeeper() 539 urls = self.call_gatekeeper()
538 self.assertNotIn(self.status_url, urls) 540 self.assertNotIn(self.status_url, urls)
539 self.assertNotIn(self.mailer_url, urls) 541 self.assertNotIn(self.mailer_url, urls)
540 542
541 def testStepNotStarted(self): 543 def testStepNotStarted(self):
542 """Test that a skipped closing step closes the tree.""" 544 """Test that a skipped closing step closes the tree."""
543 sys.argv.extend([m.url for m in self.masters]) 545 sys.argv.extend([m.url for m in self.masters])
544 sys.argv.extend(['--skip-build-db-update', 546 sys.argv.extend(['--skip-build-db-update',
545 '--json', self.gatekeeper_file,
546 '--email-app-secret-file=%s' % self.email_secret_file]) 547 '--email-app-secret-file=%s' % self.email_secret_file])
547 548
548 self.add_gatekeeper_section(self.masters[0].url, 549 self.add_gatekeeper_section(self.masters[0].url,
549 self.masters[0].builders[0].name, 550 self.masters[0].builders[0].name,
550 {'closing_steps': ['step1']}) 551 {'closing_steps': ['step1']})
551 552
552 self.masters[0].builders[0].builds[0].steps[1].isStarted = False 553 self.masters[0].builders[0].builds[0].steps[1].isStarted = False
553 self.masters[0].builders[0].builds[0].steps[1].isFinished = False 554 self.masters[0].builders[0].builds[0].steps[1].isFinished = False
554 555
555 self.call_gatekeeper() 556 self.call_gatekeeper()
556 557
557 # Check that gatekeeper indeed sent an email. 558 # Check that gatekeeper indeed sent an email.
558 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 559 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
559 mailer_data = GatekeeperTest.decode_param_json( 560 mailer_data = GatekeeperTest.decode_param_json(
560 self.url_calls[-1]['params']) 561 self.url_calls[-1]['params'])
561 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 562 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
562 563
563 def testGatekeeperOOO(self): 564 def testGatekeeperOOO(self):
564 """Test that gatekeeper_spec works even if not the first step.""" 565 """Test that gatekeeper_spec works even if not the first step."""
565 sys.argv.extend([m.url for m in self.masters]) 566 sys.argv.extend([m.url for m in self.masters])
566 sys.argv.extend(['--skip-build-db-update', 567 sys.argv.extend(['--skip-build-db-update',
567 '--json', self.gatekeeper_file,
568 '--email-app-secret-file=%s' % self.email_secret_file]) 568 '--email-app-secret-file=%s' % self.email_secret_file])
569 569
570 self.add_gatekeeper_section(self.masters[0].url, 570 self.add_gatekeeper_section(self.masters[0].url,
571 self.masters[0].builders[0].name, 571 self.masters[0].builders[0].name,
572 {'closing_steps': ['step1']}) 572 {'closing_steps': ['step1']})
573 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 573 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
574 574
575 spec = self.masters[0].builders[0].builds[0].steps 575 spec = self.masters[0].builders[0].builds[0].steps
576 self.masters[0].builders[0].builds[0].steps = spec[1:]+spec[:1] 576 self.masters[0].builders[0].builds[0].steps = spec[1:]+spec[:1]
577 577
578 self.call_gatekeeper() 578 self.call_gatekeeper()
579 579
580 # Check that gatekeeper indeed sent an email. 580 # Check that gatekeeper indeed sent an email.
581 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 581 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
582 mailer_data = GatekeeperTest.decode_param_json( 582 mailer_data = GatekeeperTest.decode_param_json(
583 self.url_calls[-1]['params']) 583 self.url_calls[-1]['params'])
584 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 584 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
585 585
586 def testFailedBuildClosesTree(self): 586 def testFailedBuildClosesTree(self):
587 """Test that a failed build calls to the status app.""" 587 """Test that a failed build calls to the status app."""
588 sys.argv.extend([m.url for m in self.masters]) 588 sys.argv.extend([m.url for m in self.masters])
589 sys.argv.extend(['--skip-build-db-update', 589 sys.argv.extend(['--skip-build-db-update',
590 '--no-email-app', '--set-status', 590 '--no-email-app', '--set-status',
591 '--json', self.gatekeeper_file,
592 '--password-file', self.status_secret_file]) 591 '--password-file', self.status_secret_file])
593 592
594 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 593 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
595 self.add_gatekeeper_section(self.masters[0].url, 594 self.add_gatekeeper_section(self.masters[0].url,
596 self.masters[0].builders[0].name, 595 self.masters[0].builders[0].name,
597 {'closing_steps': ['step1']}) 596 {'closing_steps': ['step1']})
598 597
599 urls = self.call_gatekeeper() 598 urls = self.call_gatekeeper()
600 self.assertIn(self.status_url, urls) 599 self.assertIn(self.status_url, urls)
601 600
602 def testIgnoredStepsDontCloseTree(self): 601 def testIgnoredStepsDontCloseTree(self):
603 """Test that ignored steps don't call to the status app.""" 602 """Test that ignored steps don't call to the status app."""
604 sys.argv.extend([m.url for m in self.masters]) 603 sys.argv.extend([m.url for m in self.masters])
605 sys.argv.extend(['--skip-build-db-update', 604 sys.argv.extend(['--skip-build-db-update',
606 '--no-email-app', '--set-status', 605 '--no-email-app', '--set-status',
607 '--json', self.gatekeeper_file,
608 '--password-file', self.status_secret_file]) 606 '--password-file', self.status_secret_file])
609 607
610 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 608 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
611 self.add_gatekeeper_section(self.masters[0].url, 609 self.add_gatekeeper_section(self.masters[0].url,
612 self.masters[0].builders[0].name, 610 self.masters[0].builders[0].name,
613 {'closing_steps': ['step2']}) 611 {'closing_steps': ['step2']})
614 612
615 self.handle_url_str(self.status_url, 'the status') 613 self.handle_url_str(self.status_url, 'the status')
616 614
617 urls = self.call_gatekeeper() 615 urls = self.call_gatekeeper()
618 self.assertNotIn(self.status_url, urls) 616 self.assertNotIn(self.status_url, urls)
619 617
620 def testDefaultSubjectTemplate(self): 618 def testDefaultSubjectTemplate(self):
621 """Test that the subject template is set by default.""" 619 """Test that the subject template is set by default."""
622 sys.argv.extend([m.url for m in self.masters]) 620 sys.argv.extend([m.url for m in self.masters])
623 sys.argv.extend(['--skip-build-db-update', 621 sys.argv.extend(['--skip-build-db-update',
624 '--json', self.gatekeeper_file,
625 '--email-app-secret-file=%s' % self.email_secret_file]) 622 '--email-app-secret-file=%s' % self.email_secret_file])
626 623
627 self.add_gatekeeper_section(self.masters[0].url, 624 self.add_gatekeeper_section(self.masters[0].url,
628 self.masters[0].builders[0].name, 625 self.masters[0].builders[0].name,
629 {'closing_steps': ['step4']}) 626 {'closing_steps': ['step4']})
630 627
631 self.call_gatekeeper() 628 self.call_gatekeeper()
632 629
633 # Check that gatekeeper indeed sent an email. 630 # Check that gatekeeper indeed sent an email.
634 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 631 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
635 mailer_data = GatekeeperTest.decode_param_json(self.url_calls[-1]['params']) 632 mailer_data = GatekeeperTest.decode_param_json(self.url_calls[-1]['params'])
636 self.assertEquals(mailer_data['subject_template'], unicode( 633 self.assertEquals(mailer_data['subject_template'], unicode(
637 'buildbot %(result)s in %(projectName)s on %(builder)s, ' 634 'buildbot %(result)s in %(projectName)s on %(builder)s, '
638 'revision %(revision)s')) 635 'revision %(revision)s'))
639 636
640 637
641 def testEmailJson(self): 638 def testEmailJson(self):
642 """Test that the email json is formatted correctly.""" 639 """Test that the email json is formatted correctly."""
643 sys.argv.extend([m.url for m in self.masters]) 640 sys.argv.extend([m.url for m in self.masters])
644 sys.argv.extend(['--skip-build-db-update', 641 sys.argv.extend(['--skip-build-db-update',
645 '--json', self.gatekeeper_file,
646 '--email-app-secret-file=%s' % self.email_secret_file]) 642 '--email-app-secret-file=%s' % self.email_secret_file])
647 643
648 subject_template = 'build %(result)s, oh no!' 644 subject_template = 'build %(result)s, oh no!'
649 self.masters[0].builders[0].builds[0].results = 3 645 self.masters[0].builders[0].builds[0].results = 3
650 self.add_gatekeeper_master_config(self.masters[0].url, 646 self.add_gatekeeper_master_config(self.masters[0].url,
651 {'respect_build_status': True}) 647 {'respect_build_status': True})
652 self.add_gatekeeper_section(self.masters[0].url, 648 self.add_gatekeeper_section(self.masters[0].url,
653 self.masters[0].builders[0].name, 649 self.masters[0].builders[0].name,
654 {'subject_template': subject_template}, 650 {'subject_template': subject_template},
655 idx=0) 651 idx=0)
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 self.assertEquals(mailer_data['project_name'], unicode('Chromium FYI')) 689 self.assertEquals(mailer_data['project_name'], unicode('Chromium FYI'))
694 self.assertEquals(mailer_data['from_addr'], 'buildbot@chromium.org') 690 self.assertEquals(mailer_data['from_addr'], 'buildbot@chromium.org')
695 self.assertEquals(mailer_data['subject_template'], 691 self.assertEquals(mailer_data['subject_template'],
696 unicode(subject_template)) 692 unicode(subject_template))
697 693
698 694
699 #### BuildDB operation. 695 #### BuildDB operation.
700 696
701 def testIncrementalScanning(self): 697 def testIncrementalScanning(self):
702 """Test that builds in the build DB are skipped.""" 698 """Test that builds in the build DB are skipped."""
703 fd, dbfilename = tempfile.mkstemp() 699 build_db = gatekeeper_ng_db.gen_db(masters={
704 build_db = {self.masters[0].url: { 'mybuilder': 1 }} 700 self.masters[0].url: {
705 os.write(fd, json.dumps(build_db)) 701 'mybuilder': {
706 os.close(fd) 702 1: gatekeeper_ng_db.gen_build(finished=True)}}})
707 703
708 sys.argv.extend([m.url for m in self.masters]) 704 sys.argv.extend([m.url for m in self.masters])
709 sys.argv.extend(['--build-db=%s' % dbfilename, 705 sys.argv.extend(['--email-app-secret-file=%s' % self.email_secret_file])
710 '--json', self.gatekeeper_file,
711 '--email-app-secret-file=%s' % self.email_secret_file])
712 706
713 707
714 self.add_gatekeeper_section(self.masters[0].url, 708 self.add_gatekeeper_section(self.masters[0].url,
715 self.masters[0].builders[0].name, 709 self.masters[0].builders[0].name,
716 {'closing_steps': ['step1']}) 710 {'closing_steps': ['step1']})
717 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 711 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
718 712
719 self.masters[0].builders[0].builds.append( 713 self.masters[0].builders[0].builds.append(
720 GatekeeperTest.create_generic_build(2,[ 714 GatekeeperTest.create_generic_build(2,[
721 'a_second_committer@chromium.org'])) 715 'a_second_committer@chromium.org']))
722 self.masters[0].builders[0].builds[1].steps[1].results = [2, None] 716 self.masters[0].builders[0].builds[1].steps[1].results = [2, None]
723 717
724 @contextlib.contextmanager 718 self.call_gatekeeper(build_db=build_db)
725 def delfile(filename): 719 _, finished_new_builds = self.process_build_db(
726 yield 720 self.masters[0].url, 'mybuilder')
727 os.unlink(filename) 721 self.assertEquals(finished_new_builds,
722 {2: gatekeeper_ng_db.gen_build(finished=True, triggered=[
723 '2be9f9320c2d26b09e416d615ff047'
724 '86abc74794bd5b669a1bb4228f884ddf50'])})
728 725
729 with delfile(dbfilename): 726 # Check that gatekeeper indeed sent an email.
730 self.call_gatekeeper()
731 with open(dbfilename) as f:
732 new_build_db = json.load(f)
733 self.assertEquals(new_build_db, {self.masters[0].url: {'mybuilder': 2}})
734
735 #check that gatekeeper indeed sent an email.
736 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 727 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
737 mailer_data = GatekeeperTest.decode_param_json( 728 mailer_data = GatekeeperTest.decode_param_json(
738 self.url_calls[-1]['params']) 729 self.url_calls[-1]['params'])
739 self.assertEquals(mailer_data['recipients'], 730 self.assertEquals(mailer_data['recipients'],
740 ['a_second_committer@chromium.org']) 731 ['a_second_committer@chromium.org'])
741 urls = [call['url'] for call in self.url_calls] 732 urls = [call['url'] for call in self.url_calls]
742 self.assertEquals(urls.count(self.mailer_url), 1) 733 self.assertEquals(urls.count(self.mailer_url), 1)
743 734
744 735
745 #### Gatekeeper parsing. 736 #### Gatekeeper parsing.
746 737
747 def testSheriffParsing(self): 738 def testSheriffParsing(self):
748 """Test that sheriff annotations are properly parsed.""" 739 """Test that sheriff annotations are properly parsed."""
749 sys.argv.extend([m.url for m in self.masters]) 740 sys.argv.extend([m.url for m in self.masters])
750 sys.argv.extend(['--skip-build-db-update', 741 sys.argv.extend(['--skip-build-db-update',
751 '--json', self.gatekeeper_file,
752 '--email-app-secret-file=%s' % self.email_secret_file]) 742 '--email-app-secret-file=%s' % self.email_secret_file])
753 743
754 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 744 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
755 self.add_gatekeeper_section(self.masters[0].url, 745 self.add_gatekeeper_section(self.masters[0].url,
756 self.masters[0].builders[0].name, 746 self.masters[0].builders[0].name,
757 {'closing_steps': ['step1'], 747 {'closing_steps': ['step1'],
758 'sheriff_classes': ['sheriff_android']}) 748 'sheriff_classes': ['sheriff_android']})
759 749
760 750
761 sheriff_url = 'http://build.chromium.org/p/chromium/sheriff_android.js' 751 sheriff_url = 'http://build.chromium.org/p/chromium/sheriff_android.js'
(...skipping 11 matching lines...) Expand all
773 mailer_data['recipients'].sort() 763 mailer_data['recipients'].sort()
774 self.assertEquals(mailer_data['recipients'], 764 self.assertEquals(mailer_data['recipients'],
775 ['a_committer@chromium.org', 765 ['a_committer@chromium.org',
776 'anothersheriff@google.com', 766 'anothersheriff@google.com',
777 'asheriff@google.com']) 767 'asheriff@google.com'])
778 768
779 def testNoSheriff(self): 769 def testNoSheriff(self):
780 """Test that a no-sheriff condition works OK (weekends).""" 770 """Test that a no-sheriff condition works OK (weekends)."""
781 sys.argv.extend([m.url for m in self.masters]) 771 sys.argv.extend([m.url for m in self.masters])
782 sys.argv.extend(['--skip-build-db-update', 772 sys.argv.extend(['--skip-build-db-update',
783 '--json', self.gatekeeper_file,
784 '--email-app-secret-file=%s' % self.email_secret_file]) 773 '--email-app-secret-file=%s' % self.email_secret_file])
785 774
786 self.masters[0].builders[0].builds[0].blame = [] 775 self.masters[0].builders[0].builds[0].blame = []
787 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 776 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
788 777
789 self.add_gatekeeper_section(self.masters[0].url, 778 self.add_gatekeeper_section(self.masters[0].url,
790 self.masters[0].builders[0].name, 779 self.masters[0].builders[0].name,
791 {'closing_steps': ['step1'], 780 {'closing_steps': ['step1'],
792 'sheriff_classes': ['sheriff_android']}) 781 'sheriff_classes': ['sheriff_android']})
793 782
794 sheriff_url = 'http://build.chromium.org/p/chromium/sheriff_android.js' 783 sheriff_url = 'http://build.chromium.org/p/chromium/sheriff_android.js'
795 sheriff_string = 'document.write(\'None (channel is sheriff)\')' 784 sheriff_string = 'document.write(\'None (channel is sheriff)\')'
796 self.handle_url_str(sheriff_url, sheriff_string) 785 self.handle_url_str(sheriff_url, sheriff_string)
797 786
798 self.call_gatekeeper() 787 self.call_gatekeeper()
799 788
800 self.assertEquals(self.url_calls[-1]['url'], sheriff_url) 789 self.assertEquals(self.url_calls[-1]['url'], sheriff_url)
801 790
802 urls = [call['url'] for call in self.url_calls] 791 urls = [call['url'] for call in self.url_calls]
803 self.assertNotIn(self.mailer_url, urls) 792 self.assertNotIn(self.mailer_url, urls)
804 793
805 def testNoSheriffButBlame(self): 794 def testNoSheriffButBlame(self):
806 """Test that no-sheriff works ok with a blamelist.""" 795 """Test that no-sheriff works ok with a blamelist."""
807 sys.argv.extend([m.url for m in self.masters]) 796 sys.argv.extend([m.url for m in self.masters])
808 sys.argv.extend(['--skip-build-db-update', 797 sys.argv.extend(['--skip-build-db-update',
809 '--json', self.gatekeeper_file,
810 '--email-app-secret-file=%s' % self.email_secret_file]) 798 '--email-app-secret-file=%s' % self.email_secret_file])
811 799
812 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 800 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
813 self.add_gatekeeper_section(self.masters[0].url, 801 self.add_gatekeeper_section(self.masters[0].url,
814 self.masters[0].builders[0].name, 802 self.masters[0].builders[0].name,
815 {'closing_steps': ['step1'], 803 {'closing_steps': ['step1'],
816 'sheriff_classes': ['sheriff_android']}) 804 'sheriff_classes': ['sheriff_android']})
817 805
818 sheriff_url = 'http://build.chromium.org/p/chromium/sheriff_android.js' 806 sheriff_url = 'http://build.chromium.org/p/chromium/sheriff_android.js'
819 sheriff_string = 'document.write(\'None (channel is sheriff)\')' 807 sheriff_string = 'document.write(\'None (channel is sheriff)\')'
820 self.handle_url_str(sheriff_url, sheriff_string) 808 self.handle_url_str(sheriff_url, sheriff_string)
821 809
822 self.call_gatekeeper() 810 self.call_gatekeeper()
823 811
824 self.assertEquals(self.url_calls[-2]['url'], sheriff_url) 812 self.assertEquals(self.url_calls[-2]['url'], sheriff_url)
825 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 813 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
826 mailer_data = GatekeeperTest.decode_param_json( 814 mailer_data = GatekeeperTest.decode_param_json(
827 self.url_calls[-1]['params']) 815 self.url_calls[-1]['params'])
828 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 816 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
829 817
830 def testMultiSheriff(self): 818 def testMultiSheriff(self):
831 """Test that multiple sheriff lists can be merged.""" 819 """Test that multiple sheriff lists can be merged."""
832 sys.argv.extend([m.url for m in self.masters]) 820 sys.argv.extend([m.url for m in self.masters])
833 sys.argv.extend(['--skip-build-db-update', 821 sys.argv.extend(['--skip-build-db-update',
834 '--json', self.gatekeeper_file,
835 '--email-app-secret-file=%s' % self.email_secret_file]) 822 '--email-app-secret-file=%s' % self.email_secret_file])
836 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 823 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
837 self.add_gatekeeper_section(self.masters[0].url, 824 self.add_gatekeeper_section(self.masters[0].url,
838 self.masters[0].builders[0].name, 825 self.masters[0].builders[0].name,
839 {'closing_steps': ['step1'], 826 {'closing_steps': ['step1'],
840 'sheriff_classes': ['sheriff_android', 827 'sheriff_classes': ['sheriff_android',
841 'sheriff']}) 828 'sheriff']})
842 829
843 sheriff_url = 'http://build.chromium.org/p/chromium/sheriff_android.js' 830 sheriff_url = 'http://build.chromium.org/p/chromium/sheriff_android.js'
844 sheriff_string = 'document.write(\'asheriff, anothersheriff\')' 831 sheriff_string = 'document.write(\'asheriff, anothersheriff\')'
(...skipping 16 matching lines...) Expand all
861 self.assertEquals(mailer_data['recipients'], 848 self.assertEquals(mailer_data['recipients'],
862 ['a_committer@chromium.org', 849 ['a_committer@chromium.org',
863 'anothersheriff@google.com', 850 'anothersheriff@google.com',
864 'asheriff@google.com', 851 'asheriff@google.com',
865 'athirdsheriff@google.com']) 852 'athirdsheriff@google.com'])
866 853
867 def testNotifyParsing(self): 854 def testNotifyParsing(self):
868 """Test that additional watchers can be merged to the mailing list.""" 855 """Test that additional watchers can be merged to the mailing list."""
869 sys.argv.extend([m.url for m in self.masters]) 856 sys.argv.extend([m.url for m in self.masters])
870 sys.argv.extend(['--skip-build-db-update', 857 sys.argv.extend(['--skip-build-db-update',
871 '--json', self.gatekeeper_file,
872 '--email-app-secret-file=%s' % self.email_secret_file]) 858 '--email-app-secret-file=%s' % self.email_secret_file])
873 859
874 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 860 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
875 self.add_gatekeeper_section(self.masters[0].url, 861 self.add_gatekeeper_section(self.masters[0].url,
876 self.masters[0].builders[0].name, 862 self.masters[0].builders[0].name,
877 {'closing_steps': ['step1'], 863 {'closing_steps': ['step1'],
878 'tree_notify': ['a_watcher@chromium.org']}) 864 'tree_notify': ['a_watcher@chromium.org']})
879 865
880 sheriff_url = 'http://build.chromium.org/p/chromium/sheriff_android.js' 866 sheriff_url = 'http://build.chromium.org/p/chromium/sheriff_android.js'
881 sheriff_string = 'document.write(\'asheriff, anothersheriff\')' 867 sheriff_string = 'document.write(\'asheriff, anothersheriff\')'
882 self.handle_url_str(sheriff_url, sheriff_string) 868 self.handle_url_str(sheriff_url, sheriff_string)
883 869
884 self.call_gatekeeper() 870 self.call_gatekeeper()
885 871
886 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 872 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
887 873
888 mailer_data = GatekeeperTest.decode_param_json( 874 mailer_data = GatekeeperTest.decode_param_json(
889 self.url_calls[-1]['params']) 875 self.url_calls[-1]['params'])
890 mailer_data['recipients'].sort() 876 mailer_data['recipients'].sort()
891 self.assertEquals(mailer_data['recipients'], 877 self.assertEquals(mailer_data['recipients'],
892 ['a_committer@chromium.org', 878 ['a_committer@chromium.org',
893 'a_watcher@chromium.org']) 879 'a_watcher@chromium.org'])
894 880
895 def testNotifyNoBlame(self): 881 def testNotifyNoBlame(self):
896 """Test that notify works with no blamelist.""" 882 """Test that notify works with no blamelist."""
897 sys.argv.extend([m.url for m in self.masters]) 883 sys.argv.extend([m.url for m in self.masters])
898 sys.argv.extend(['--skip-build-db-update', 884 sys.argv.extend(['--skip-build-db-update',
899 '--json', self.gatekeeper_file,
900 '--email-app-secret-file=%s' % self.email_secret_file]) 885 '--email-app-secret-file=%s' % self.email_secret_file])
901 886
902 self.masters[0].builders[0].builds[0].blame = [] 887 self.masters[0].builders[0].builds[0].blame = []
903 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 888 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
904 self.add_gatekeeper_section(self.masters[0].url, 889 self.add_gatekeeper_section(self.masters[0].url,
905 self.masters[0].builders[0].name, 890 self.masters[0].builders[0].name,
906 {'closing_steps': ['step1'], 891 {'closing_steps': ['step1'],
907 'tree_notify': ['a_watcher@chromium.org']}) 892 'tree_notify': ['a_watcher@chromium.org']})
908 893
909 self.call_gatekeeper() 894 self.call_gatekeeper()
910 895
911 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 896 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
912 897
913 mailer_data = GatekeeperTest.decode_param_json( 898 mailer_data = GatekeeperTest.decode_param_json(
914 self.url_calls[-1]['params']) 899 self.url_calls[-1]['params'])
915 mailer_data['recipients'].sort() 900 mailer_data['recipients'].sort()
916 self.assertEquals(mailer_data['recipients'], ['a_watcher@chromium.org']) 901 self.assertEquals(mailer_data['recipients'], ['a_watcher@chromium.org'])
917 902
918 def testForgivingSteps(self): 903 def testForgivingSteps(self):
919 """Test that forgiving steps set status but don't email blamelist.""" 904 """Test that forgiving steps set status but don't email blamelist."""
920 sys.argv.extend([m.url for m in self.masters]) 905 sys.argv.extend([m.url for m in self.masters])
921 sys.argv.extend(['--skip-build-db-update', 906 sys.argv.extend(['--skip-build-db-update',
922 '--json', self.gatekeeper_file,
923 '--email-app-secret-file=%s' % self.email_secret_file, 907 '--email-app-secret-file=%s' % self.email_secret_file,
924 '--set-status', '--password-file', self.status_secret_file 908 '--set-status', '--password-file', self.status_secret_file
925 ]) 909 ])
926 910
927 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 911 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
928 self.add_gatekeeper_section(self.masters[0].url, 912 self.add_gatekeeper_section(self.masters[0].url,
929 self.masters[0].builders[0].name, 913 self.masters[0].builders[0].name,
930 {'forgiving_steps': ['step1']}) 914 {'forgiving_steps': ['step1']})
931 urls = self.call_gatekeeper() 915 urls = self.call_gatekeeper()
932 916
933 self.assertNotIn(self.mailer_url, urls) 917 self.assertNotIn(self.mailer_url, urls)
934 self.assertIn(self.status_url, urls) 918 self.assertIn(self.status_url, urls)
935 919
936 def testForgivingOptional(self): 920 def testForgivingOptional(self):
937 """Test that forgiving_optional steps set status but don't email.""" 921 """Test that forgiving_optional steps set status but don't email."""
938 sys.argv.extend([m.url for m in self.masters]) 922 sys.argv.extend([m.url for m in self.masters])
939 sys.argv.extend(['--skip-build-db-update', 923 sys.argv.extend(['--skip-build-db-update',
940 '--json', self.gatekeeper_file,
941 '--email-app-secret-file=%s' % self.email_secret_file, 924 '--email-app-secret-file=%s' % self.email_secret_file,
942 '--set-status', '--password-file', self.status_secret_file 925 '--set-status', '--password-file', self.status_secret_file
943 ]) 926 ])
944 927
945 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 928 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
946 self.add_gatekeeper_section(self.masters[0].url, 929 self.add_gatekeeper_section(self.masters[0].url,
947 self.masters[0].builders[0].name, 930 self.masters[0].builders[0].name,
948 {'forgiving_optional': ['step1']}) 931 {'forgiving_optional': ['step1']})
949 urls = self.call_gatekeeper() 932 urls = self.call_gatekeeper()
950 933
951 self.assertNotIn(self.mailer_url, urls) 934 self.assertNotIn(self.mailer_url, urls)
952 self.assertIn(self.status_url, urls) 935 self.assertIn(self.status_url, urls)
953 936
954 def testForgivingOptionalStar(self): 937 def testForgivingOptionalStar(self):
955 """Test that forgiving_optional * sets status but doesn't email.""" 938 """Test that forgiving_optional * sets status but doesn't email."""
956 sys.argv.extend([m.url for m in self.masters]) 939 sys.argv.extend([m.url for m in self.masters])
957 sys.argv.extend(['--skip-build-db-update', 940 sys.argv.extend(['--skip-build-db-update',
958 '--json', self.gatekeeper_file,
959 '--email-app-secret-file=%s' % self.email_secret_file, 941 '--email-app-secret-file=%s' % self.email_secret_file,
960 '--set-status', '--password-file', self.status_secret_file 942 '--set-status', '--password-file', self.status_secret_file
961 ]) 943 ])
962 944
963 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 945 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
964 self.add_gatekeeper_section(self.masters[0].url, 946 self.add_gatekeeper_section(self.masters[0].url,
965 self.masters[0].builders[0].name, 947 self.masters[0].builders[0].name,
966 {'forgiving_optional': ['*']}) 948 {'forgiving_optional': ['*']})
967 urls = self.call_gatekeeper() 949 urls = self.call_gatekeeper()
968 950
969 self.assertNotIn(self.mailer_url, urls) 951 self.assertNotIn(self.mailer_url, urls)
970 self.assertIn(self.status_url, urls) 952 self.assertIn(self.status_url, urls)
971 953
972 def testForgiveAllSteps(self): 954 def testForgiveAllSteps(self):
973 """Test that setting forgive_all prevents emailing the blamelist.""" 955 """Test that setting forgive_all prevents emailing the blamelist."""
974 sys.argv.extend([m.url for m in self.masters]) 956 sys.argv.extend([m.url for m in self.masters])
975 sys.argv.extend(['--skip-build-db-update', 957 sys.argv.extend(['--skip-build-db-update',
976 '--json', self.gatekeeper_file,
977 '--email-app-secret-file=%s' % self.email_secret_file, 958 '--email-app-secret-file=%s' % self.email_secret_file,
978 '--set-status', '--password-file', self.status_secret_file 959 '--set-status', '--password-file', self.status_secret_file
979 ]) 960 ])
980 961
981 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 962 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
982 self.add_gatekeeper_section(self.masters[0].url, 963 self.add_gatekeeper_section(self.masters[0].url,
983 self.masters[0].builders[0].name, 964 self.masters[0].builders[0].name,
984 {'closing_steps': ['step1'], 965 {'closing_steps': ['step1'],
985 'forgive_all': 'true'}) 966 'forgive_all': 'true'})
986 urls = self.call_gatekeeper() 967 urls = self.call_gatekeeper()
987 968
988 self.assertNotIn(self.mailer_url, urls) 969 self.assertNotIn(self.mailer_url, urls)
989 self.assertIn(self.status_url, urls) 970 self.assertIn(self.status_url, urls)
990 971
991 def testForgiveAllOptionalSteps(self): 972 def testForgiveAllOptionalSteps(self):
992 """Test that setting forgive_all prevents emailing the blamelist.""" 973 """Test that setting forgive_all prevents emailing the blamelist."""
993 sys.argv.extend([m.url for m in self.masters]) 974 sys.argv.extend([m.url for m in self.masters])
994 sys.argv.extend(['--skip-build-db-update', 975 sys.argv.extend(['--skip-build-db-update',
995 '--json', self.gatekeeper_file,
996 '--email-app-secret-file=%s' % self.email_secret_file, 976 '--email-app-secret-file=%s' % self.email_secret_file,
997 '--set-status', '--password-file', self.status_secret_file 977 '--set-status', '--password-file', self.status_secret_file
998 ]) 978 ])
999 979
1000 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 980 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1001 self.add_gatekeeper_section(self.masters[0].url, 981 self.add_gatekeeper_section(self.masters[0].url,
1002 self.masters[0].builders[0].name, 982 self.masters[0].builders[0].name,
1003 {'closing_optional': ['step1'], 983 {'closing_optional': ['step1'],
1004 'forgive_all': 'true'}) 984 'forgive_all': 'true'})
1005 urls = self.call_gatekeeper() 985 urls = self.call_gatekeeper()
1006 986
1007 self.assertNotIn(self.mailer_url, urls) 987 self.assertNotIn(self.mailer_url, urls)
1008 self.assertIn(self.status_url, urls) 988 self.assertIn(self.status_url, urls)
1009 989
1010 #### Multiple failures. 990 #### Multiple failures.
1011 991
1012 def testSequentialFailures(self): 992 def testSequentialFailures(self):
1013 """Test that the status app is only hit once if many failures are seen.""" 993 """Test that the status app is only hit once if many failures are seen."""
1014 sys.argv.extend([m.url for m in self.masters]) 994 sys.argv.extend([m.url for m in self.masters])
1015 sys.argv.extend(['--skip-build-db-update', 995 sys.argv.extend(['--skip-build-db-update',
1016 '--json', self.gatekeeper_file,
1017 '--email-app-secret-file=%s' % self.email_secret_file, 996 '--email-app-secret-file=%s' % self.email_secret_file,
1018 '--set-status', '--password-file', self.status_secret_file 997 '--set-status', '--password-file', self.status_secret_file
1019 ]) 998 ])
1020 999
1021 new_build = self.create_generic_build(2, 1000 new_build = self.create_generic_build(2,
1022 ['a_second_committer@chromium.org']) 1001 ['a_second_committer@chromium.org'])
1023 self.masters[0].builders[0].builds.append(new_build) 1002 self.masters[0].builders[0].builds.append(new_build)
1024 1003
1025 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1004 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1026 self.add_gatekeeper_section(self.masters[0].url, 1005 self.add_gatekeeper_section(self.masters[0].url,
(...skipping 12 matching lines...) Expand all
1039 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 1018 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
1040 mailer_data = GatekeeperTest.decode_param_json( 1019 mailer_data = GatekeeperTest.decode_param_json(
1041 self.url_calls[-1]['params']) 1020 self.url_calls[-1]['params'])
1042 self.assertEquals(mailer_data['recipients'], 1021 self.assertEquals(mailer_data['recipients'],
1043 ['a_second_committer@chromium.org']) 1022 ['a_second_committer@chromium.org'])
1044 1023
1045 def testSequentialOneFailure(self): 1024 def testSequentialOneFailure(self):
1046 """Test that failing builds aren't mixed with good ones.""" 1025 """Test that failing builds aren't mixed with good ones."""
1047 sys.argv.extend([m.url for m in self.masters]) 1026 sys.argv.extend([m.url for m in self.masters])
1048 sys.argv.extend(['--skip-build-db-update', 1027 sys.argv.extend(['--skip-build-db-update',
1049 '--json', self.gatekeeper_file,
1050 '--email-app-secret-file=%s' % self.email_secret_file, 1028 '--email-app-secret-file=%s' % self.email_secret_file,
1051 '--set-status', '--password-file', self.status_secret_file 1029 '--set-status', '--password-file', self.status_secret_file
1052 ]) 1030 ])
1053 1031
1054 new_build = self.create_generic_build(2, 1032 new_build = self.create_generic_build(2,
1055 ['a_second_committer@chromium.org']) 1033 ['a_second_committer@chromium.org'])
1056 self.masters[0].builders[0].builds.append(new_build) 1034 self.masters[0].builders[0].builds.append(new_build)
1057 1035
1058 self.add_gatekeeper_section(self.masters[0].url, 1036 self.add_gatekeeper_section(self.masters[0].url,
1059 self.masters[0].builders[0].name, 1037 self.masters[0].builders[0].name,
1060 {'closing_steps': ['step1']}) 1038 {'closing_steps': ['step1']})
1061 1039
1062 self.masters[0].builders[0].builds[1].steps[1].results = [2, None] 1040 self.masters[0].builders[0].builds[1].steps[1].results = [2, None]
1063 1041
1064 urls = self.call_gatekeeper() 1042 urls = self.call_gatekeeper()
1065 self.assertEquals(urls.count(self.status_url), 1) 1043 self.assertEquals(urls.count(self.status_url), 1)
1066 self.assertEquals(urls.count(self.mailer_url), 1) 1044 self.assertEquals(urls.count(self.mailer_url), 1)
1067 1045
1068 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1046 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1069 mailer_data = GatekeeperTest.decode_param_json( 1047 mailer_data = GatekeeperTest.decode_param_json(
1070 self.url_calls[-1]['params']) 1048 self.url_calls[-1]['params'])
1071 self.assertEquals(mailer_data['recipients'], 1049 self.assertEquals(mailer_data['recipients'],
1072 ['a_second_committer@chromium.org']) 1050 ['a_second_committer@chromium.org'])
1073 1051
1074 def testStarBuilder(self): 1052 def testStarBuilder(self):
1075 """Test that * captures failures across all builders.""" 1053 """Test that * captures failures across all builders."""
1076 sys.argv.extend([m.url for m in self.masters]) 1054 sys.argv.extend([m.url for m in self.masters])
1077 sys.argv.extend(['--skip-build-db-update', 1055 sys.argv.extend(['--skip-build-db-update',
1078 '--json', self.gatekeeper_file,
1079 '--email-app-secret-file=%s' % self.email_secret_file]) 1056 '--email-app-secret-file=%s' % self.email_secret_file])
1080 1057
1081 self.add_gatekeeper_section(self.masters[0].url, 1058 self.add_gatekeeper_section(self.masters[0].url,
1082 '*', 1059 '*',
1083 {'closing_steps': ['step4']}) 1060 {'closing_steps': ['step4']})
1084 1061
1085 self.call_gatekeeper() 1062 self.call_gatekeeper()
1086 1063
1087 # Check that gatekeeper indeed sent an email. 1064 # Check that gatekeeper indeed sent an email.
1088 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1065 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1089 mailer_data = GatekeeperTest.decode_param_json(self.url_calls[-1]['params']) 1066 mailer_data = GatekeeperTest.decode_param_json(self.url_calls[-1]['params'])
1090 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 1067 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
1091 1068
1092 def testStarBuilderOverride(self): 1069 def testStarBuilderOverride(self):
1093 """Test that * can be explicitly overridden.""" 1070 """Test that * can be explicitly overridden."""
1094 sys.argv.extend([m.url for m in self.masters]) 1071 sys.argv.extend([m.url for m in self.masters])
1095 sys.argv.extend(['--skip-build-db-update', 1072 sys.argv.extend(['--skip-build-db-update',
1096 '--json', self.gatekeeper_file,
1097 '--email-app-secret-file=%s' % self.email_secret_file]) 1073 '--email-app-secret-file=%s' % self.email_secret_file])
1098 1074
1099 # step3 won't fail the build. 1075 # step3 won't fail the build.
1100 self.add_gatekeeper_section(self.masters[0].url, 1076 self.add_gatekeeper_section(self.masters[0].url,
1101 '*', 1077 '*',
1102 {'closing_steps': ['step3']}) 1078 {'closing_steps': ['step3']})
1103 1079
1104 # But step4 will. 1080 # But step4 will.
1105 self.add_gatekeeper_section(self.masters[0].url, 1081 self.add_gatekeeper_section(self.masters[0].url,
1106 self.masters[0].builders[0].name, 1082 self.masters[0].builders[0].name,
1107 {'closing_steps': ['step4']}, 1083 {'closing_steps': ['step4']},
1108 idx=0) 1084 idx=0)
1109 1085
1110 self.call_gatekeeper() 1086 self.call_gatekeeper()
1111 1087
1112 # Check that gatekeeper indeed sent an email. 1088 # Check that gatekeeper indeed sent an email.
1113 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1089 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1114 mailer_data = GatekeeperTest.decode_param_json(self.url_calls[-1]['params']) 1090 mailer_data = GatekeeperTest.decode_param_json(self.url_calls[-1]['params'])
1115 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 1091 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
1116 1092
1117 def testStarBuilderNoPropagate(self): 1093 def testStarBuilderNoPropagate(self):
1118 """Test that * doesn't propagate to other builders.""" 1094 """Test that * doesn't propagate to other builders."""
1119 sys.argv.extend([m.url for m in self.masters]) 1095 sys.argv.extend([m.url for m in self.masters])
1120 sys.argv.extend(['--skip-build-db-update', 1096 sys.argv.extend(['--skip-build-db-update',
1121 '--json', self.gatekeeper_file,
1122 '--email-app-secret-file=%s' % self.email_secret_file]) 1097 '--email-app-secret-file=%s' % self.email_secret_file])
1123 1098
1124 # step4 will fail the build. 1099 # step4 will fail the build.
1125 self.add_gatekeeper_section(self.masters[0].url, 1100 self.add_gatekeeper_section(self.masters[0].url,
1126 '*', 1101 '*',
1127 {'closing_steps': ['step4']}) 1102 {'closing_steps': ['step4']})
1128 1103
1129 # But step3 won't. 1104 # But step3 won't.
1130 self.add_gatekeeper_section(self.masters[0].url, 1105 self.add_gatekeeper_section(self.masters[0].url,
1131 self.masters[0].builders[0].name, 1106 self.masters[0].builders[0].name,
1132 {'closing_steps': ['step3']}, 1107 {'closing_steps': ['step3']},
1133 idx=0) 1108 idx=0)
1134 1109
1135 urls = self.call_gatekeeper() 1110 urls = self.call_gatekeeper()
1136 1111
1137 self.assertNotIn(self.mailer_url, urls) 1112 self.assertNotIn(self.mailer_url, urls)
1138 1113
1139 def testMultiBuilderOneFailure(self): 1114 def testMultiBuilderOneFailure(self):
1140 """Test that failure in one build doesn't affect another.""" 1115 """Test that failure in one build doesn't affect another."""
1141 sys.argv.extend([m.url for m in self.masters]) 1116 sys.argv.extend([m.url for m in self.masters])
1142 sys.argv.extend(['--skip-build-db-update', 1117 sys.argv.extend(['--skip-build-db-update',
1143 '--json', self.gatekeeper_file,
1144 '--email-app-secret-file=%s' % self.email_secret_file, 1118 '--email-app-secret-file=%s' % self.email_secret_file,
1145 '--set-status', '--password-file', self.status_secret_file 1119 '--set-status', '--password-file', self.status_secret_file
1146 ]) 1120 ])
1147 1121
1122 build_db = gatekeeper_ng_db.gen_db(masters={
1123 self.masters[0].url: {
1124 'mybuilder': {
1125 0: gatekeeper_ng_db.gen_build(finished=True)},
1126 'mybuilder2': {
1127 0: gatekeeper_ng_db.gen_build(finished=True)},
1128 }})
1129
1148 new_build = self.create_generic_build(2, 1130 new_build = self.create_generic_build(2,
1149 ['a_second_committer@chromium.org']) 1131 ['a_second_committer@chromium.org'])
1150 self.masters[0].builders.append(Builder('mybuilder2', [new_build])) 1132 self.masters[0].builders.append(Builder('mybuilder2', [new_build]))
1151 1133
1152 self.add_gatekeeper_section(self.masters[0].url, 1134 self.add_gatekeeper_section(self.masters[0].url,
1153 self.masters[0].builders[0].name, 1135 self.masters[0].builders[0].name,
1154 {'closing_steps': ['step1']}) 1136 {'closing_steps': ['step1']})
1155 1137
1156 self.masters[0].builders[1].builds[0].steps[1].results = [2, None] 1138 self.masters[0].builders[1].builds[0].steps[1].results = [2, None]
1157 self.add_gatekeeper_section(self.masters[0].url, 1139 self.add_gatekeeper_section(self.masters[0].url,
1158 self.masters[0].builders[1].name, 1140 self.masters[0].builders[1].name,
1159 {'closing_steps': ['step1']}, 1141 {'closing_steps': ['step1']},
1160 idx=0) 1142 idx=0)
1161 1143
1162 urls = self.call_gatekeeper() 1144 urls = self.call_gatekeeper(build_db=build_db)
1163 self.assertEquals(urls.count(self.status_url), 1) 1145 self.assertEquals(urls.count(self.status_url), 1)
1164 self.assertEquals(urls.count(self.mailer_url), 1) 1146 self.assertEquals(urls.count(self.mailer_url), 1)
1165 1147
1166 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1148 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1167 mailer_data = GatekeeperTest.decode_param_json( 1149 mailer_data = GatekeeperTest.decode_param_json(
1168 self.url_calls[-1]['params']) 1150 self.url_calls[-1]['params'])
1169 self.assertEquals(mailer_data['recipients'], 1151 self.assertEquals(mailer_data['recipients'],
1170 ['a_second_committer@chromium.org']) 1152 ['a_second_committer@chromium.org'])
1171 1153
1172 def testMultiBuilderFailures(self): 1154 def testMultiBuilderFailures(self):
1173 """Test that failures on several builders are handled properly.""" 1155 """Test that failures on several builders are handled properly."""
1174 master_url = 'http://build.chromium.org/p/chromium.fyi' 1156 master_url = 'http://build.chromium.org/p/chromium.fyi'
1175 sys.argv.extend([master_url, 1157 sys.argv.extend([master_url,
1176 '--skip-build-db-update', 1158 '--skip-build-db-update',
1177 '--json', self.gatekeeper_file,
1178 '--email-app-secret-file=%s' % self.email_secret_file, 1159 '--email-app-secret-file=%s' % self.email_secret_file,
1179 '--set-status', '--password-file', self.status_secret_file 1160 '--set-status', '--password-file', self.status_secret_file
1180 ]) 1161 ])
1181 1162
1163 build_db = gatekeeper_ng_db.gen_db(masters={
1164 self.masters[0].url: {
1165 'mybuilder': {
1166 0: gatekeeper_ng_db.gen_build(finished=True)},
1167 'mybuilder2': {
1168 0: gatekeeper_ng_db.gen_build(finished=True)},
1169 }})
1170
1182 new_build = self.create_generic_build(2, 1171 new_build = self.create_generic_build(2,
1183 ['a_second_committer@chromium.org']) 1172 ['a_second_committer@chromium.org'])
1184 self.masters[0].builders.append(Builder('mybuilder2', [new_build])) 1173 self.masters[0].builders.append(Builder('mybuilder2', [new_build]))
1185 1174
1186 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1175 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1187 self.add_gatekeeper_section(self.masters[0].url, 1176 self.add_gatekeeper_section(self.masters[0].url,
1188 self.masters[0].builders[0].name, 1177 self.masters[0].builders[0].name,
1189 {'closing_steps': ['step1']}) 1178 {'closing_steps': ['step1']})
1190 1179
1191 self.masters[0].builders[1].builds[0].steps[1].results = [2, None] 1180 self.masters[0].builders[1].builds[0].steps[1].results = [2, None]
1192 self.add_gatekeeper_section(self.masters[0].url, 1181 self.add_gatekeeper_section(self.masters[0].url,
1193 self.masters[0].builders[1].name, 1182 self.masters[0].builders[1].name,
1194 {'closing_steps': ['step1']}, 1183 {'closing_steps': ['step1']},
1195 idx=0) 1184 idx=0)
1196 1185
1197 urls = self.call_gatekeeper() 1186 urls = self.call_gatekeeper(build_db=build_db)
1198 self.assertEquals(urls.count(self.status_url), 1) 1187 self.assertEquals(urls.count(self.status_url), 1)
1199 1188
1200 self.assertEquals(self.url_calls[-2]['url'], self.mailer_url) 1189 self.assertEquals(self.url_calls[-2]['url'], self.mailer_url)
1201 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1190 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1202 mailer_data = GatekeeperTest.decode_param_json( 1191 mailer_data = GatekeeperTest.decode_param_json(
1203 self.url_calls[-2]['params']) 1192 self.url_calls[-2]['params'])
1204 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 1193 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
1205 mailer_data = GatekeeperTest.decode_param_json( 1194 mailer_data = GatekeeperTest.decode_param_json(
1206 self.url_calls[-1]['params']) 1195 self.url_calls[-1]['params'])
1207 self.assertEquals(mailer_data['recipients'], 1196 self.assertEquals(mailer_data['recipients'],
1208 ['a_second_committer@chromium.org']) 1197 ['a_second_committer@chromium.org'])
1209 1198
1210 def testMultiMaster(self): 1199 def testMultiMaster(self):
1211 """Test that multiple master failures are handled properly.""" 1200 """Test that multiple master failures are handled properly."""
1212 self.masters.append(self.create_generic_build_tree('Chromium FYI 2', 1201 self.masters.append(self.create_generic_build_tree('Chromium FYI 2',
1213 'chromium2.fyi')) 1202 'chromium2.fyi'))
1214 1203
1215 sys.argv.extend([m.url for m in self.masters]) 1204 sys.argv.extend([m.url for m in self.masters])
1216 sys.argv.extend(['--skip-build-db-update', 1205 sys.argv.extend(['--skip-build-db-update',
1217 '--json', self.gatekeeper_file,
1218 '--email-app-secret-file=%s' % self.email_secret_file, 1206 '--email-app-secret-file=%s' % self.email_secret_file,
1219 '--set-status', '--password-file', self.status_secret_file 1207 '--set-status', '--password-file', self.status_secret_file
1220 ]) 1208 ])
1221 1209
1210 build_db = gatekeeper_ng_db.gen_db(masters={
1211 self.masters[0].url: {
1212 'mybuilder': {
1213 0: gatekeeper_ng_db.gen_build(finished=True)},
1214 },
1215 self.masters[1].url: {
1216 'mybuilder': {
1217 0: gatekeeper_ng_db.gen_build(finished=True)},
1218 },
1219 })
1220
1222 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1221 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1223 self.add_gatekeeper_section(self.masters[0].url, 1222 self.add_gatekeeper_section(self.masters[0].url,
1224 self.masters[0].builders[0].name, 1223 self.masters[0].builders[0].name,
1225 {'closing_steps': ['step1']}) 1224 {'closing_steps': ['step1']})
1226 1225
1227 self.masters[1].builders[0].builds[0].blame = [ 1226 self.masters[1].builders[0].builds[0].blame = [
1228 'a_second_committer@chromium.org'] 1227 'a_second_committer@chromium.org']
1229 self.masters[1].builders[0].builds[0].steps[1].results = [2, None] 1228 self.masters[1].builders[0].builds[0].steps[1].results = [2, None]
1230 self.add_gatekeeper_section(self.masters[1].url, 1229 self.add_gatekeeper_section(self.masters[1].url,
1231 self.masters[0].builders[0].name, 1230 self.masters[0].builders[0].name,
1232 {'closing_steps': ['step1']}) 1231 {'closing_steps': ['step1']})
1233 1232
1234 urls = self.call_gatekeeper() 1233 urls = self.call_gatekeeper(build_db)
1235 self.assertEquals(urls.count(self.status_url), 1) 1234 self.assertEquals(urls.count(self.status_url), 1)
1236 1235
1237 self.assertEquals(urls[-1], self.mailer_url) 1236 self.assertEquals(urls[-1], self.mailer_url)
1238 self.assertEquals(urls[-1], self.mailer_url) 1237 self.assertEquals(urls[-1], self.mailer_url)
1239 mailer_data = GatekeeperTest.decode_param_json( 1238 mailer_data = GatekeeperTest.decode_param_json(
1240 self.url_calls[-2]['params']) 1239 self.url_calls[-2]['params'])
1241 self.assertEquals(mailer_data['recipients'], 1240 self.assertEquals(mailer_data['recipients'],
1242 ['a_committer@chromium.org']) 1241 ['a_committer@chromium.org'])
1243 mailer_data = GatekeeperTest.decode_param_json( 1242 mailer_data = GatekeeperTest.decode_param_json(
1244 self.url_calls[-1]['params']) 1243 self.url_calls[-1]['params'])
1245 self.assertEquals(mailer_data['recipients'], 1244 self.assertEquals(mailer_data['recipients'],
1246 ['a_second_committer@chromium.org']) 1245 ['a_second_committer@chromium.org'])
1247 1246
1248 #### Partial builds (still running). 1247 #### Partial builds (still running).
1249 1248
1250 def testDontFailOmissionOnUncompletedBuild(self): 1249 def testDontFailOmissionOnUncompletedBuild(self):
1251 """Don't fail a running build because of omitted steps.""" 1250 """Don't fail a running build because of omitted steps."""
1252 sys.argv.extend([m.url for m in self.masters]) 1251 sys.argv.extend([m.url for m in self.masters])
1253 sys.argv.extend(['--skip-build-db-update', 1252 sys.argv.extend(['--skip-build-db-update',
1254 '--json', self.gatekeeper_file,
1255 '--no-email-app', '--set-status', 1253 '--no-email-app', '--set-status',
1256 '--password-file', self.status_secret_file]) 1254 '--password-file', self.status_secret_file])
1257 1255
1258 self.masters[0].builders[0].builds[0].steps.append( 1256 self.masters[0].builders[0].builds[0].steps.append(
1259 BuildStep('step4', [], isStarted=True, isFinished=True)) 1257 BuildStep('step4', [], isStarted=True, isFinished=True))
1260 mybuild = self.create_generic_build(2, ['a_second_committer@chromium.org']) 1258 mybuild = self.create_generic_build(2, ['a_second_committer@chromium.org'])
1261 mybuild.finished = False 1259 mybuild.finished = False
1262 self.masters[0].builders[0].builds.append(mybuild) 1260 self.masters[0].builders[0].builds.append(mybuild)
1263 self.add_gatekeeper_section(self.masters[0].url, 1261 self.add_gatekeeper_section(self.masters[0].url,
1264 self.masters[0].builders[0].name, 1262 self.masters[0].builders[0].name,
1265 {'closing_steps': ['step4']}) 1263 {'closing_steps': ['step4']})
1266 1264
1267 urls = self.call_gatekeeper() 1265 urls = self.call_gatekeeper()
1268 self.assertNotIn(self.status_url, urls) 1266 self.assertNotIn(self.status_url, urls)
1269 1267
1270 def testFailedBuildInProgress(self): 1268 def testFailedBuildInProgress(self):
1271 """Test that a still-running build can close the tree.""" 1269 """Test that a still-running build can close the tree."""
1272 sys.argv.extend([m.url for m in self.masters]) 1270 sys.argv.extend([m.url for m in self.masters])
1273 sys.argv.extend(['--skip-build-db-update', 1271 sys.argv.extend(['--skip-build-db-update',
1274 '--json', self.gatekeeper_file,
1275 '--no-email-app', '--set-status', 1272 '--no-email-app', '--set-status',
1276 '--password-file', self.status_secret_file]) 1273 '--password-file', self.status_secret_file])
1277 1274
1278 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1275 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1279 self.add_gatekeeper_section(self.masters[0].url, 1276 self.add_gatekeeper_section(self.masters[0].url,
1280 self.masters[0].builders[0].name, 1277 self.masters[0].builders[0].name,
1281 {'closing_steps': ['step1']}) 1278 {'closing_steps': ['step1']})
1282 mybuild = self.create_generic_build(2, ['a_second_committer@chromium.org']) 1279 mybuild = self.create_generic_build(2, ['a_second_committer@chromium.org'])
1283 mybuild.finished = False 1280 mybuild.finished = False
1284 self.masters[0].builders[0].builds.append(mybuild) 1281 self.masters[0].builders[0].builds.append(mybuild)
1285 1282
1286 urls = self.call_gatekeeper() 1283 urls = self.call_gatekeeper()
1287 self.assertIn(self.status_url, urls) 1284 self.assertIn(self.status_url, urls)
1288 1285
1289 def testUpdateBuildDBNotCompletedButFailed(self): 1286 def testUpdateBuildDBNotCompletedButFailed(self):
1290 """Test that partial builds increment the DB if they failed.""" 1287 """Test that partial builds increment the DB if they failed."""
1291 fd, dbfilename = tempfile.mkstemp() 1288 build_db = gatekeeper_ng_db.gen_db(masters={
1292 build_db = {self.masters[0].url: { 'mybuilder': 1 }} 1289 self.masters[0].url: {
1293 os.write(fd, json.dumps(build_db)) 1290 'mybuilder': {
1294 os.close(fd) 1291 1: gatekeeper_ng_db.gen_build(finished=True)}}})
1295 1292
1296 sys.argv.extend([m.url for m in self.masters]) 1293 sys.argv.extend([m.url for m in self.masters])
1297 sys.argv.extend(['--build-db=%s' % dbfilename, 1294 sys.argv.extend(['--no-email-app', '--set-status',
1298 '--json', self.gatekeeper_file,
1299 '--no-email-app', '--set-status',
1300 '--password-file', self.status_secret_file]) 1295 '--password-file', self.status_secret_file])
1301 1296
1302 mybuild = self.create_generic_build(2, ['a_second_committer@chromium.org']) 1297 mybuild = self.create_generic_build(2, ['a_second_committer@chromium.org'])
1303 mybuild.steps[1].results = [2, None] 1298 mybuild.steps[1].results = [2, None]
1304 mybuild.finished = False 1299 mybuild.finished = False
1305 self.masters[0].builders[0].builds.append(mybuild) 1300 self.masters[0].builders[0].builds.append(mybuild)
1306 self.add_gatekeeper_section(self.masters[0].url, 1301 self.add_gatekeeper_section(self.masters[0].url,
1307 self.masters[0].builders[0].name, 1302 self.masters[0].builders[0].name,
1308 {'closing_steps': ['step1']}) 1303 {'closing_steps': ['step1']})
1309 1304
1310 @contextlib.contextmanager 1305 urls = self.call_gatekeeper(build_db=build_db)
1311 def delfile(filename): 1306 unfinished_new_builds, finished_new_builds = self.process_build_db(
1312 yield 1307 self.masters[0].url, 'mybuilder')
1313 os.unlink(filename)
1314 1308
1315 with delfile(dbfilename): 1309 self.assertEquals(finished_new_builds,
1316 urls = self.call_gatekeeper() 1310 {1: gatekeeper_ng_db.gen_build(finished=True)})
1317 with open(dbfilename) as f: 1311 self.assertEquals(unfinished_new_builds,
1318 new_build_db = json.load(f) 1312 {2: gatekeeper_ng_db.gen_build(triggered=[
1319 self.assertEquals(new_build_db, {self.masters[0].url: {'mybuilder': 2}}) 1313 '2be9f9320c2d26b09e416d615'
1314 'ff04786abc74794bd5b669a1bb4228f884ddf50'])})
1315
1320 self.assertIn(self.status_url, urls) 1316 self.assertIn(self.status_url, urls)
1321 1317
1322 def testDontUpdateBuildDBIfNotCompleted(self): 1318 def testDontUpdateBuildDBIfNotCompleted(self):
1323 """Test that partial builds don't increment the DB if still running.""" 1319 """Test that partial builds aren't marked as finished."""
1324 fd, dbfilename = tempfile.mkstemp() 1320 build_db = gatekeeper_ng_db.gen_db(masters={
1325 build_db = {self.masters[0].url: { 'mybuilder': 1 }} 1321 self.masters[0].url: {
1326 os.write(fd, json.dumps(build_db)) 1322 'mybuilder': {
1327 os.close(fd) 1323 1: gatekeeper_ng_db.gen_build(finished=True),
1324 2: gatekeeper_ng_db.gen_build()}}})
1328 1325
1329 sys.argv.extend([m.url for m in self.masters]) 1326 sys.argv.extend([m.url for m in self.masters])
1330 sys.argv.extend(['--build-db=%s' % dbfilename, 1327 sys.argv.extend(['--no-email-app', '--set-status',
1331 '--json', self.gatekeeper_file,
1332 '--no-email-app', '--set-status',
1333 '--password-file', self.status_secret_file]) 1328 '--password-file', self.status_secret_file])
1334 1329
1335 mybuild = self.create_generic_build(2, ['a_second_committer@chromium.org']) 1330 mybuild = self.create_generic_build(2, ['a_second_committer@chromium.org'])
1336 mybuild.finished = False 1331 mybuild.finished = False
1337 self.masters[0].builders[0].builds.append(mybuild) 1332 self.masters[0].builders[0].builds.append(mybuild)
1338 self.add_gatekeeper_section(self.masters[0].url, 1333 self.add_gatekeeper_section(self.masters[0].url,
1339 self.masters[0].builders[0].name, 1334 self.masters[0].builders[0].name,
1340 {'closing_steps': ['step4']}) 1335 {'closing_steps': ['step4']})
1341 1336
1342 @contextlib.contextmanager 1337 urls = self.call_gatekeeper(build_db=build_db)
1343 def delfile(filename): 1338 unfinished_new_builds, finished_new_builds = self.process_build_db(
1344 yield 1339 self.masters[0].url, 'mybuilder')
1345 os.unlink(filename)
1346 1340
1347 with delfile(dbfilename): 1341 self.assertEquals(finished_new_builds,
1348 urls = self.call_gatekeeper() 1342 {1: gatekeeper_ng_db.gen_build(finished=True)})
1349 with open(dbfilename) as f: 1343 self.assertEquals(unfinished_new_builds,
1350 new_build_db = json.load(f) 1344 {2: gatekeeper_ng_db.gen_build()})
1351 self.assertEquals(new_build_db, {self.masters[0].url: {'mybuilder': 1}})
1352 self.assertNotIn(self.status_url, urls) 1345 self.assertNotIn(self.status_url, urls)
1353 1346
1347 def testTriggeringDoesntTriggerOnSameBuild(self):
1348 """Test that a section won't fire twice on a build."""
1349 sys.argv.extend([m.url for m in self.masters])
1350 sys.argv.extend(['--no-email-app', '--set-status',
1351 '--password-file', self.status_secret_file])
1352
1353 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1354 self.masters[0].builders[0].builds[0].finished = False
1355 self.add_gatekeeper_section(self.masters[0].url,
1356 self.masters[0].builders[0].name,
1357 {'closing_steps': ['step1']})
1358
1359 urls = self.call_gatekeeper()
1360 build_db = gatekeeper_ng_db.get_build_db(self.build_db_file)
1361 urls += self.call_gatekeeper(build_db=build_db)
1362 unfinished_new_builds, finished_new_builds = self.process_build_db(
1363 self.masters[0].url, 'mybuilder')
1364 self.assertEquals(finished_new_builds,
1365 {0: gatekeeper_ng_db.gen_build(finished=True)})
1366 self.assertEquals(unfinished_new_builds,
1367 {1: gatekeeper_ng_db.gen_build(triggered=[
1368 '2be9f9320c2d26b09e416d615ff047'
1369 '86abc74794bd5b669a1bb4228f884ddf50'])})
1370 self.assertEquals(1, len([u for u in urls if u == self.status_url]))
1371
1372 def testTriggeringOneHashDoesntStopAnother(self):
1373 """Test that firing on one hash doesn't prevent another hash triggering."""
1374 build_db = gatekeeper_ng_db.gen_db(masters={
1375 self.masters[0].url: {
1376 'mybuilder': {
1377 1: gatekeeper_ng_db.gen_build(finished=True)}}})
1378
1379 sys.argv.extend([m.url for m in self.masters])
1380 sys.argv.extend(['--no-email-app', '--set-status',
1381 '--password-file', self.status_secret_file])
1382
1383 mybuild = self.create_generic_build(2, ['a_second_committer@chromium.org'])
1384 mybuild.finished = False
1385 self.masters[0].builders[0].builds.append(mybuild)
1386 self.masters[0].builders[0].builds[1].steps[1].results = [2, None]
1387 self.add_gatekeeper_section(self.masters[0].url,
1388 self.masters[0].builders[0].name,
1389 {'closing_steps': ['step1']})
1390
1391 urls = self.call_gatekeeper(build_db=build_db)
1392 self.add_gatekeeper_section(self.masters[0].url,
1393 self.masters[0].builders[0].name,
1394 {'closing_steps': ['step2']})
1395 self.masters[0].builders[0].builds[1].steps[2].results = [2, None]
1396 build_db = gatekeeper_ng_db.get_build_db(self.build_db_file)
1397 urls += self.call_gatekeeper(build_db=build_db)
1398 unfinished_new_builds, finished_new_builds = self.process_build_db(
1399 self.masters[0].url, 'mybuilder')
1400 self.assertEquals(finished_new_builds,
1401 {1: gatekeeper_ng_db.gen_build(finished=True)})
1402 self.assertEquals(unfinished_new_builds,
1403 {2: gatekeeper_ng_db.gen_build(triggered=[
1404 '2be9f9320c2d26b09e416d615ff04786ab'
1405 'c74794bd5b669a1bb4228f884ddf50',
1406
1407 'ac0bb2a7245af2aa43c257a3c4eda19dee'
1408 'a4137bc1bce6a8b307047fd6149e32'])})
1409 self.assertEquals(2, len([u for u in urls if u == self.status_url]))
1410
1354 ### JSON config file tests. 1411 ### JSON config file tests.
1355 1412
1356 def testInheritFromCategory(self): 1413 def testInheritFromCategory(self):
1357 """Check that steps in categories are inherited by builders.""" 1414 """Check that steps in categories are inherited by builders."""
1358 sys.argv.extend([m.url for m in self.masters]) 1415 sys.argv.extend([m.url for m in self.masters])
1359 sys.argv.extend(['--skip-build-db-update', 1416 sys.argv.extend(['--skip-build-db-update',
1360 '--json', self.gatekeeper_file,
1361 '--email-app-secret-file=%s' % self.email_secret_file]) 1417 '--email-app-secret-file=%s' % self.email_secret_file])
1362 1418
1363 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1419 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1364 self.add_gatekeeper_category('mycat', {'closing_steps': ['step1']}) 1420 self.add_gatekeeper_category('mycat', {'closing_steps': ['step1']})
1365 self.add_gatekeeper_section(self.masters[0].url, 1421 self.add_gatekeeper_section(self.masters[0].url,
1366 self.masters[0].builders[0].name, 1422 self.masters[0].builders[0].name,
1367 {'categories': ['mycat']}) 1423 {'categories': ['mycat']})
1368 1424
1369 self.call_gatekeeper() 1425 self.call_gatekeeper()
1370 1426
1371 # Check that gatekeeper indeed sent an email. 1427 # Check that gatekeeper indeed sent an email.
1372 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1428 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1373 mailer_data = GatekeeperTest.decode_param_json( 1429 mailer_data = GatekeeperTest.decode_param_json(
1374 self.url_calls[-1]['params']) 1430 self.url_calls[-1]['params'])
1375 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 1431 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
1376 1432
1377 def testMultiCategory(self): 1433 def testMultiCategory(self):
1378 """Check that steps in categories are inherited by builders.""" 1434 """Check that steps in categories are inherited by builders."""
1379 sys.argv.extend([m.url for m in self.masters]) 1435 sys.argv.extend([m.url for m in self.masters])
1380 sys.argv.extend(['--skip-build-db-update', 1436 sys.argv.extend(['--skip-build-db-update',
1381 '--json', self.gatekeeper_file,
1382 '--email-app-secret-file=%s' % self.email_secret_file]) 1437 '--email-app-secret-file=%s' % self.email_secret_file])
1383 1438
1384 self.masters[0].builders[0].builds[0].steps[2].results = [2, None] 1439 self.masters[0].builders[0].builds[0].steps[2].results = [2, None]
1385 self.add_gatekeeper_category('mycat', {'closing_steps': ['step1']}) 1440 self.add_gatekeeper_category('mycat', {'closing_steps': ['step1']})
1386 self.add_gatekeeper_category('mycat2', {'closing_steps': ['step2']}) 1441 self.add_gatekeeper_category('mycat2', {'closing_steps': ['step2']})
1387 self.add_gatekeeper_section(self.masters[0].url, 1442 self.add_gatekeeper_section(self.masters[0].url,
1388 self.masters[0].builders[0].name, 1443 self.masters[0].builders[0].name,
1389 {'categories': ['mycat', 'mycat2']}) 1444 {'categories': ['mycat', 'mycat2']})
1390 1445
1391 self.call_gatekeeper() 1446 self.call_gatekeeper()
1392 1447
1393 # Check that gatekeeper indeed sent an email. 1448 # Check that gatekeeper indeed sent an email.
1394 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1449 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1395 mailer_data = GatekeeperTest.decode_param_json( 1450 mailer_data = GatekeeperTest.decode_param_json(
1396 self.url_calls[-1]['params']) 1451 self.url_calls[-1]['params'])
1397 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 1452 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
1398 1453
1399 def testAddonCategory(self): 1454 def testAddonCategory(self):
1400 """Check that builders can add-on to categories.""" 1455 """Check that builders can add-on to categories."""
1401 sys.argv.extend([m.url for m in self.masters]) 1456 sys.argv.extend([m.url for m in self.masters])
1402 sys.argv.extend(['--skip-build-db-update', 1457 sys.argv.extend(['--skip-build-db-update',
1403 '--json', self.gatekeeper_file,
1404 '--email-app-secret-file=%s' % self.email_secret_file]) 1458 '--email-app-secret-file=%s' % self.email_secret_file])
1405 1459
1406 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1460 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1407 self.add_gatekeeper_category('mycat', {'closing_steps': ['step2']}) 1461 self.add_gatekeeper_category('mycat', {'closing_steps': ['step2']})
1408 self.add_gatekeeper_section(self.masters[0].url, 1462 self.add_gatekeeper_section(self.masters[0].url,
1409 self.masters[0].builders[0].name, 1463 self.masters[0].builders[0].name,
1410 {'categories': ['mycat'], 1464 {'categories': ['mycat'],
1411 'closing_steps': ['step1']}) 1465 'closing_steps': ['step1']})
1412 1466
1413 self.call_gatekeeper() 1467 self.call_gatekeeper()
1414 1468
1415 # Check that gatekeeper indeed sent an email. 1469 # Check that gatekeeper indeed sent an email.
1416 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1470 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1417 mailer_data = GatekeeperTest.decode_param_json( 1471 mailer_data = GatekeeperTest.decode_param_json(
1418 self.url_calls[-1]['params']) 1472 self.url_calls[-1]['params'])
1419 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 1473 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
1420 1474
1421 def testInheritFromMaster(self): 1475 def testInheritFromMaster(self):
1422 """Check that steps in masters are inherited by builders.""" 1476 """Check that steps in masters are inherited by builders."""
1423 sys.argv.extend([m.url for m in self.masters]) 1477 sys.argv.extend([m.url for m in self.masters])
1424 sys.argv.extend(['--skip-build-db-update', 1478 sys.argv.extend(['--skip-build-db-update',
1425 '--json', self.gatekeeper_file,
1426 '--email-app-secret-file=%s' % self.email_secret_file]) 1479 '--email-app-secret-file=%s' % self.email_secret_file])
1427 1480
1428 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1481 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1429 self.add_gatekeeper_master_config(self.masters[0].url, 1482 self.add_gatekeeper_master_config(self.masters[0].url,
1430 {'sheriff_classes': ['sheriff_android']}) 1483 {'sheriff_classes': ['sheriff_android']})
1431 self.add_gatekeeper_section(self.masters[0].url, 1484 self.add_gatekeeper_section(self.masters[0].url,
1432 self.masters[0].builders[0].name, 1485 self.masters[0].builders[0].name,
1433 {'closing_steps': ['step1']}, 1486 {'closing_steps': ['step1']},
1434 idx=0) 1487 idx=0)
1435 1488
(...skipping 12 matching lines...) Expand all
1448 mailer_data['recipients'].sort() 1501 mailer_data['recipients'].sort()
1449 self.assertEquals(mailer_data['recipients'], 1502 self.assertEquals(mailer_data['recipients'],
1450 ['a_committer@chromium.org', 1503 ['a_committer@chromium.org',
1451 'anothersheriff@google.com', 1504 'anothersheriff@google.com',
1452 'asheriff@google.com']) 1505 'asheriff@google.com'])
1453 1506
1454 def testAddonToMaster(self): 1507 def testAddonToMaster(self):
1455 """Check that steps in masters can be added by builders.""" 1508 """Check that steps in masters can be added by builders."""
1456 sys.argv.extend([m.url for m in self.masters]) 1509 sys.argv.extend([m.url for m in self.masters])
1457 sys.argv.extend(['--skip-build-db-update', 1510 sys.argv.extend(['--skip-build-db-update',
1458 '--json', self.gatekeeper_file,
1459 '--email-app-secret-file=%s' % self.email_secret_file]) 1511 '--email-app-secret-file=%s' % self.email_secret_file])
1460 1512
1461 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1513 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1462 self.add_gatekeeper_master_config(self.masters[0].url, 1514 self.add_gatekeeper_master_config(self.masters[0].url,
1463 {'sheriff_classes': ['sheriff_android']}) 1515 {'sheriff_classes': ['sheriff_android']})
1464 self.add_gatekeeper_section(self.masters[0].url, 1516 self.add_gatekeeper_section(self.masters[0].url,
1465 self.masters[0].builders[0].name, 1517 self.masters[0].builders[0].name,
1466 {'closing_steps': ['step1'], 1518 {'closing_steps': ['step1'],
1467 'sheriff_classes': ['sheriff']}, 1519 'sheriff_classes': ['sheriff']},
1468 idx=0) 1520 idx=0)
(...skipping 20 matching lines...) Expand all
1489 ['a_committer@chromium.org', 1541 ['a_committer@chromium.org',
1490 'anothersheriff2@google.com', 1542 'anothersheriff2@google.com',
1491 'anothersheriff@google.com', 1543 'anothersheriff@google.com',
1492 'asheriff2@google.com', 1544 'asheriff2@google.com',
1493 'asheriff@google.com']) 1545 'asheriff@google.com'])
1494 1546
1495 def testInheritCategoryFromMaster(self): 1547 def testInheritCategoryFromMaster(self):
1496 """Check that steps can inherit categories from masters.""" 1548 """Check that steps can inherit categories from masters."""
1497 sys.argv.extend([m.url for m in self.masters]) 1549 sys.argv.extend([m.url for m in self.masters])
1498 sys.argv.extend(['--skip-build-db-update', 1550 sys.argv.extend(['--skip-build-db-update',
1499 '--json', self.gatekeeper_file,
1500 '--email-app-secret-file=%s' % self.email_secret_file]) 1551 '--email-app-secret-file=%s' % self.email_secret_file])
1501 1552
1502 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1553 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1503 self.add_gatekeeper_category('mycat', {'closing_steps': ['step1']}) 1554 self.add_gatekeeper_category('mycat', {'closing_steps': ['step1']})
1504 self.add_gatekeeper_master_config(self.masters[0].url, 1555 self.add_gatekeeper_master_config(self.masters[0].url,
1505 {'categories': ['mycat']}) 1556 {'categories': ['mycat']})
1506 self.add_gatekeeper_section(self.masters[0].url, 1557 self.add_gatekeeper_section(self.masters[0].url,
1507 self.masters[0].builders[0].name, 1558 self.masters[0].builders[0].name,
1508 {}, 1559 {},
1509 idx=0) 1560 idx=0)
1510 1561
1511 self.call_gatekeeper() 1562 self.call_gatekeeper()
1512 1563
1513 # Check that gatekeeper indeed sent an email. 1564 # Check that gatekeeper indeed sent an email.
1514 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1565 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1515 mailer_data = GatekeeperTest.decode_param_json( 1566 mailer_data = GatekeeperTest.decode_param_json(
1516 self.url_calls[-1]['params']) 1567 self.url_calls[-1]['params'])
1517 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 1568 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
1518 1569
1519 def testMasterSections(self): 1570 def testMasterSections(self):
1520 """Check that master sections work correctly.""" 1571 """Check that master sections work correctly."""
1521 sys.argv.extend([m.url for m in self.masters]) 1572 sys.argv.extend([m.url for m in self.masters])
1522 sys.argv.extend(['--skip-build-db-update', 1573 sys.argv.extend(['--skip-build-db-update',
1523 '--json', self.gatekeeper_file,
1524 '--email-app-secret-file=%s' % self.email_secret_file]) 1574 '--email-app-secret-file=%s' % self.email_secret_file])
1525 1575
1526 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1576 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1527 self.add_gatekeeper_category('mycat', {'closing_steps': ['step1']}) 1577 self.add_gatekeeper_category('mycat', {'closing_steps': ['step1']})
1528 self.add_gatekeeper_master_config(self.masters[0].url, 1578 self.add_gatekeeper_master_config(self.masters[0].url,
1529 {} 1579 {}
1530 ) 1580 )
1531 self.add_gatekeeper_section(self.masters[0].url, 1581 self.add_gatekeeper_section(self.masters[0].url,
1532 self.masters[0].builders[0].name, 1582 self.masters[0].builders[0].name,
1533 {}, 1583 {},
1534 idx=0) 1584 idx=0)
1535 1585
1536 self.add_gatekeeper_section(self.masters[0].url, 1586 self.add_gatekeeper_section(self.masters[0].url,
1537 self.masters[0].builders[0].name, 1587 self.masters[0].builders[0].name,
1538 {'categories': ['mycat']}) 1588 {'categories': ['mycat']})
1539 1589
1540 self.call_gatekeeper() 1590 self.call_gatekeeper()
1541 1591
1542 # Check that gatekeeper indeed sent an email. 1592 # Check that gatekeeper indeed sent an email.
1543 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1593 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1544 mailer_data = GatekeeperTest.decode_param_json( 1594 mailer_data = GatekeeperTest.decode_param_json(
1545 self.url_calls[-1]['params']) 1595 self.url_calls[-1]['params'])
1546 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 1596 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
1547 1597
1548 def testMasterSectionEmails(self): 1598 def testMasterSectionEmails(self):
1549 """Check that master section handles email properly.""" 1599 """Check that master section handles email properly."""
1550 sys.argv.extend([m.url for m in self.masters]) 1600 sys.argv.extend([m.url for m in self.masters])
1551 sys.argv.extend(['--skip-build-db-update', 1601 sys.argv.extend(['--skip-build-db-update',
1552 '--json', self.gatekeeper_file,
1553 '--email-app-secret-file=%s' % self.email_secret_file]) 1602 '--email-app-secret-file=%s' % self.email_secret_file])
1554 1603
1555 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1604 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1556 self.add_gatekeeper_category('mycat', {'closing_steps': ['step1']}) 1605 self.add_gatekeeper_category('mycat', {'closing_steps': ['step1']})
1557 self.add_gatekeeper_master_config(self.masters[0].url, 1606 self.add_gatekeeper_master_config(self.masters[0].url,
1558 {} 1607 {}
1559 ) 1608 )
1560 self.add_gatekeeper_section(self.masters[0].url, 1609 self.add_gatekeeper_section(self.masters[0].url,
1561 self.masters[0].builders[0].name, 1610 self.masters[0].builders[0].name,
1562 {'closing_steps': ['step1'], 1611 {'closing_steps': ['step1'],
(...skipping 10 matching lines...) Expand all
1573 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1622 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1574 mailer_data = GatekeeperTest.decode_param_json( 1623 mailer_data = GatekeeperTest.decode_param_json(
1575 self.url_calls[-1]['params']) 1624 self.url_calls[-1]['params'])
1576 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org', 1625 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org',
1577 'a_watcher@chromium.org']) 1626 'a_watcher@chromium.org'])
1578 1627
1579 def testEmailFilter(self): 1628 def testEmailFilter(self):
1580 """Test that no email is sent if the email isn't in the domain filter.""" 1629 """Test that no email is sent if the email isn't in the domain filter."""
1581 sys.argv.extend([m.url for m in self.masters]) 1630 sys.argv.extend([m.url for m in self.masters])
1582 sys.argv.extend(['--skip-build-db-update', 1631 sys.argv.extend(['--skip-build-db-update',
1583 '--json', self.gatekeeper_file,
1584 '--email-app-secret-file=%s' % self.email_secret_file, 1632 '--email-app-secret-file=%s' % self.email_secret_file,
1585 '--filter-domain=squirrels.net,squirrels.com']) 1633 '--filter-domain=squirrels.net,squirrels.com'])
1586 1634
1587 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1635 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1588 self.add_gatekeeper_section(self.masters[0].url, 1636 self.add_gatekeeper_section(self.masters[0].url,
1589 self.masters[0].builders[0].name, 1637 self.masters[0].builders[0].name,
1590 {'closing_steps': ['step1']}) 1638 {'closing_steps': ['step1']})
1591 1639
1592 urls = self.call_gatekeeper() 1640 urls = self.call_gatekeeper()
1593 self.assertNotIn(self.mailer_url, urls) 1641 self.assertNotIn(self.mailer_url, urls)
1594 1642
1595 def testDisableEmailFilter(self): 1643 def testDisableEmailFilter(self):
1596 """Test that no email is sent if the email isn't in the domain filter.""" 1644 """Test that no email is sent if the email isn't in the domain filter."""
1597 sys.argv.extend([m.url for m in self.masters]) 1645 sys.argv.extend([m.url for m in self.masters])
1598 sys.argv.extend(['--skip-build-db-update', 1646 sys.argv.extend(['--skip-build-db-update',
1599 '--json', self.gatekeeper_file,
1600 '--email-app-secret-file=%s' % self.email_secret_file, 1647 '--email-app-secret-file=%s' % self.email_secret_file,
1601 '--disable-domain-filter', 1648 '--disable-domain-filter',
1602 '--filter-domain=squirrels.net,squirrels.com']) 1649 '--filter-domain=squirrels.net,squirrels.com'])
1603 1650
1604 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1651 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1605 self.add_gatekeeper_section(self.masters[0].url, 1652 self.add_gatekeeper_section(self.masters[0].url,
1606 self.masters[0].builders[0].name, 1653 self.masters[0].builders[0].name,
1607 {'closing_steps': ['step1']}) 1654 {'closing_steps': ['step1']})
1608 1655
1609 self.call_gatekeeper() 1656 self.call_gatekeeper()
1610 1657
1611 # Check that gatekeeper indeed sent an email. 1658 # Check that gatekeeper indeed sent an email.
1612 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url) 1659 self.assertEquals(self.url_calls[-1]['url'], self.mailer_url)
1613 mailer_data = GatekeeperTest.decode_param_json( 1660 mailer_data = GatekeeperTest.decode_param_json(
1614 self.url_calls[-1]['params']) 1661 self.url_calls[-1]['params'])
1615 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org']) 1662 self.assertEquals(mailer_data['recipients'], ['a_committer@chromium.org'])
1616 1663
1617 def testMasterNotConfigured(self): 1664 def testMasterNotConfigured(self):
1618 """Check that gatekeeper fails if a master isn't in config json.""" 1665 """Check that gatekeeper fails if a master isn't in config json."""
1619 1666
1620 sys.argv.extend([m.url for m in self.masters]) 1667 sys.argv.extend([m.url for m in self.masters])
1621 sys.argv.extend(['--skip-build-db-update', 1668 sys.argv.extend(['--skip-build-db-update',
1622 '--json', self.gatekeeper_file,
1623 '--no-email-app']) 1669 '--no-email-app'])
1624 with self.assertRaises(ValueError): 1670 with self.assertRaises(ValueError):
1625 self.call_gatekeeper() 1671 self.call_gatekeeper()
1626 1672
1627 def testSectionWillNotCloseTree(self): 1673 def testSectionWillNotCloseTree(self):
1628 """Test that close_tree=False sections don't call to the status app.""" 1674 """Test that close_tree=False sections don't call to the status app."""
1629 sys.argv.extend([m.url for m in self.masters]) 1675 sys.argv.extend([m.url for m in self.masters])
1630 sys.argv.extend(['--skip-build-db-update', 1676 sys.argv.extend(['--skip-build-db-update',
1631 '--no-email-app', '--set-status', 1677 '--no-email-app', '--set-status',
1632 '--json', self.gatekeeper_file,
1633 '--password-file', self.status_secret_file]) 1678 '--password-file', self.status_secret_file])
1634 1679
1635 self.masters[0].builders[0].builds[0].steps[1].results = [2, None] 1680 self.masters[0].builders[0].builds[0].steps[1].results = [2, None]
1636 self.add_gatekeeper_section(self.masters[0].url, 1681 self.add_gatekeeper_section(self.masters[0].url,
1637 self.masters[0].builders[0].name, 1682 self.masters[0].builders[0].name,
1638 {'closing_steps': ['step1']}) 1683 {'closing_steps': ['step1']})
1639 1684
1640 self.handle_url_str(self.status_url, 'the status') 1685 self.handle_url_str(self.status_url, 'the status')
1641 1686
1642 self.add_gatekeeper_master_section(self.masters[0].url, -1, 1687 self.add_gatekeeper_master_section(self.masters[0].url, -1,
1643 {'close_tree': False}) 1688 {'close_tree': False})
1644 1689
1645 urls = self.call_gatekeeper() 1690 urls = self.call_gatekeeper()
1646 self.assertNotIn(self.status_url, urls) 1691 self.assertNotIn(self.status_url, urls)
1647 1692
1648 def testInvalidConfigIsCaught(self): 1693 def testInvalidConfigIsCaught(self):
1649 sys.argv.extend(['--verify', 1694 sys.argv.extend(['--verify'])
1650 '--json', self.gatekeeper_file])
1651 1695
1652 self.add_gatekeeper_section(self.masters[0].url, 1696 self.add_gatekeeper_section(self.masters[0].url,
1653 self.masters[0].builders[0].name, 1697 self.masters[0].builders[0].name,
1654 {'squirrels': ['yay']}) 1698 {'squirrels': ['yay']})
1655 with self.assertRaises(AssertionError): 1699 with self.assertRaises(AssertionError):
1656 self.call_gatekeeper() 1700 self.call_gatekeeper()
1657 1701
1658 # Check that the checked in gatekeeper.json is valid. 1702 # Check that the checked in gatekeeper.json is valid.
1659 def testCheckedInConfigIsValid(self): 1703 def testCheckedInConfigIsValid(self):
1660 sys.argv.extend(['--verify', 1704 sys.argv.extend(['--verify'])
1661 '--json', 1705 self.call_gatekeeper(
1662 os.path.join(SCRIPT_DIR, os.pardir, 'gatekeeper.json')]) 1706 json=os.path.join(SCRIPT_DIR, os.pardir, 'gatekeeper.json'))
1663 self.call_gatekeeper()
1664 1707
1665 1708
1666 if __name__ == '__main__': 1709 if __name__ == '__main__':
1667 with utils.print_coverage(include=[__file__]): 1710 with utils.print_coverage(include=[__file__]):
1668 unittest.main() 1711 unittest.main()
OLDNEW
« scripts/slave/gatekeeper_ng_db.py ('K') | « scripts/slave/gatekeeper_ng_db.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698