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

Side by Side Diff: tests/owners_unittest.py

Issue 1085993004: Implement support for file: includes in OWNERS files. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: minor cleanups Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « testing_support/filesystem_mock.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 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 owners.py.""" 6 """Unit tests for owners.py."""
7 7
8 import os 8 import os
9 import sys 9 import sys
10 import unittest 10 import unittest
(...skipping 12 matching lines...) Expand all
23 peter = 'peter@example.com' 23 peter = 'peter@example.com'
24 tom = 'tom@example.com' 24 tom = 'tom@example.com'
25 25
26 26
27 def owners_file(*email_addresses, **kwargs): 27 def owners_file(*email_addresses, **kwargs):
28 s = '' 28 s = ''
29 if kwargs.get('comment'): 29 if kwargs.get('comment'):
30 s += '# %s\n' % kwargs.get('comment') 30 s += '# %s\n' % kwargs.get('comment')
31 if kwargs.get('noparent'): 31 if kwargs.get('noparent'):
32 s += 'set noparent\n' 32 s += 'set noparent\n'
33 if kwargs.get('file'):
34 s += 'file:%s\n' % kwargs.get('file')
33 s += '\n'.join(kwargs.get('lines', [])) + '\n' 35 s += '\n'.join(kwargs.get('lines', [])) + '\n'
34 return s + '\n'.join(email_addresses) + '\n' 36 return s + '\n'.join(email_addresses) + '\n'
35 37
36 38
37 def test_repo(): 39 def test_repo():
38 return filesystem_mock.MockFileSystem(files={ 40 return filesystem_mock.MockFileSystem(files={
39 '/DEPS' : '', 41 '/DEPS' : '',
40 '/OWNERS': owners_file(owners.EVERYONE), 42 '/OWNERS': owners_file(owners.EVERYONE),
41 '/base/vlog.h': '', 43 '/base/vlog.h': '',
42 '/chrome/OWNERS': owners_file(ben, brett), 44 '/chrome/OWNERS': owners_file(ben, brett),
43 '/chrome/browser/OWNERS': owners_file(brett), 45 '/chrome/browser/OWNERS': owners_file(brett),
44 '/chrome/browser/defaults.h': '', 46 '/chrome/browser/defaults.h': '',
45 '/chrome/gpu/OWNERS': owners_file(ken), 47 '/chrome/gpu/OWNERS': owners_file(ken),
46 '/chrome/gpu/gpu_channel.h': '', 48 '/chrome/gpu/gpu_channel.h': '',
47 '/chrome/renderer/OWNERS': owners_file(peter), 49 '/chrome/renderer/OWNERS': owners_file(peter),
48 '/chrome/renderer/gpu/gpu_channel_host.h': '', 50 '/chrome/renderer/gpu/gpu_channel_host.h': '',
49 '/chrome/renderer/safe_browsing/scorer.h': '', 51 '/chrome/renderer/safe_browsing/scorer.h': '',
50 '/content/OWNERS': owners_file(john, darin, comment='foo', noparent=True), 52 '/content/OWNERS': owners_file(john, darin, comment='foo', noparent=True),
51 '/content/content.gyp': '', 53 '/content/content.gyp': '',
52 '/content/bar/foo.cc': '', 54 '/content/bar/foo.cc': '',
53 '/content/baz/OWNERS': owners_file(brett), 55 '/content/baz/OWNERS': owners_file(brett),
54 '/content/baz/froboz.h': '', 56 '/content/baz/froboz.h': '',
55 '/content/baz/ugly.cc': '', 57 '/content/baz/ugly.cc': '',
56 '/content/baz/ugly.h': '', 58 '/content/baz/ugly.h': '',
59 '/content/garply/OWNERS': owners_file(file='test/OWNERS'),
60 '/content/garply/foo.cc': '',
61 '/content/garply/test/OWNERS': owners_file(peter),
62 '/content/qux/OWNERS': owners_file(peter, file='//content/baz/OWNERS'),
63 '/content/qux/foo.cc': '',
57 '/content/views/OWNERS': owners_file(ben, john, owners.EVERYONE, 64 '/content/views/OWNERS': owners_file(ben, john, owners.EVERYONE,
58 noparent=True), 65 noparent=True),
59 '/content/views/pie.h': '', 66 '/content/views/pie.h': '',
60 }) 67 })
61 68
62 69
63 class _BaseTestCase(unittest.TestCase): 70 class _BaseTestCase(unittest.TestCase):
64 def setUp(self): 71 def setUp(self):
65 self.repo = test_repo() 72 self.repo = test_repo()
66 self.files = self.repo.files 73 self.files = self.repo.files
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 # This test ensures the mock relpath has the arguments in the right 209 # This test ensures the mock relpath has the arguments in the right
203 # order; this should probably live someplace else. 210 # order; this should probably live someplace else.
204 self.assertEquals(self.repo.relpath('foo/bar.c', 'foo/'), 'bar.c') 211 self.assertEquals(self.repo.relpath('foo/bar.c', 'foo/'), 'bar.c')
205 self.assertEquals(self.repo.relpath('/bar.c', '/'), 'bar.c') 212 self.assertEquals(self.repo.relpath('/bar.c', '/'), 'bar.c')
206 213
207 def test_per_file_glob_across_dirs_not_allowed(self): 214 def test_per_file_glob_across_dirs_not_allowed(self):
208 self.files['/OWNERS'] = 'per-file content/*=john@example.org\n' 215 self.files['/OWNERS'] = 'per-file content/*=john@example.org\n'
209 self.assertRaises(owners.SyntaxErrorInOwnersFile, 216 self.assertRaises(owners.SyntaxErrorInOwnersFile,
210 self.db().files_not_covered_by, ['DEPS'], [brett]) 217 self.db().files_not_covered_by, ['DEPS'], [brett])
211 218
219 def test_file_include_absolute_path(self):
220 self.assert_files_not_covered_by(['content/qux/foo.cc'], [brett], [])
221 self.assert_files_not_covered_by(['content/qux/bar.cc'], [peter], [])
222 self.assert_files_not_covered_by(['content/qux/baz.cc'],
223 [tom], ['content/qux/baz.cc'])
224
225 def test_file_include_relative_path(self):
226 self.assert_files_not_covered_by(['content/garply/foo.cc'], [peter], [])
227 self.assert_files_not_covered_by(['content/garply/bar.cc'], [darin], [])
228 self.assert_files_not_covered_by(['content/garply/baz.cc'],
229 [tom], ['content/garply/baz.cc'])
230
231 def test_file_include_per_file_absolute_path(self):
232 self.files['/content/qux/OWNERS'] = owners_file(peter,
233 lines=['per-file foo.*=file://content/baz/OWNERS'])
234
235 self.assert_files_not_covered_by(['content/qux/foo.cc'], [brett], [])
236 self.assert_files_not_covered_by(['content/qux/baz.cc'],
237 [brett], ['content/qux/baz.cc'])
238
239 def test_file_include_per_file_relative_path(self):
240 self.files['/content/garply/OWNERS'] = owners_file(brett,
241 lines=['per-file foo.*=file:test/OWNERS'])
242
243 self.assert_files_not_covered_by(['content/garply/foo.cc'], [peter], [])
244 self.assert_files_not_covered_by(['content/garply/baz.cc'],
245 [peter], ['content/garply/baz.cc'])
246
247 def test_file_include_recursive(self):
248 self.files['/content/baz/OWNERS'] = owners_file(file='//chrome/gpu/OWNERS')
249 self.assert_files_not_covered_by(['content/qux/foo.cc'], [ken], [])
250
251 def test_file_include_recursive_loop(self):
252 self.files['/content/baz/OWNERS'] = owners_file(brett,
253 file='//content/qux/OWNERS')
254 self.test_file_include_absolute_path()
255
256 def test_file_include_different_filename(self):
257 self.files['/owners/garply'] = owners_file(peter)
258 self.files['/content/garply/OWNERS'] = owners_file(john,
259 lines=['per-file foo.*=file://owners/garply'])
260
261 self.assert_files_not_covered_by(['content/garply/foo.cc'], [peter], [])
262
212 def assert_syntax_error(self, owners_file_contents): 263 def assert_syntax_error(self, owners_file_contents):
213 db = self.db() 264 db = self.db()
214 self.files['/foo/OWNERS'] = owners_file_contents 265 self.files['/foo/OWNERS'] = owners_file_contents
215 self.files['/foo/DEPS'] = '' 266 self.files['/foo/DEPS'] = ''
216 try: 267 try:
217 db.reviewers_for(['foo/DEPS'], None) 268 db.reviewers_for(['foo/DEPS'], None)
218 self.fail() # pragma: no cover 269 self.fail() # pragma: no cover
219 except owners.SyntaxErrorInOwnersFile, e: 270 except owners.SyntaxErrorInOwnersFile, e:
220 self.assertTrue(str(e).startswith('/foo/OWNERS:1')) 271 self.assertTrue(str(e).startswith('/foo/OWNERS:1'))
221 272
222 def test_syntax_error__unknown_token(self): 273 def test_syntax_error__unknown_token(self):
223 self.assert_syntax_error('{}\n') 274 self.assert_syntax_error('{}\n')
224 275
225 def test_syntax_error__unknown_set(self): 276 def test_syntax_error__unknown_set(self):
226 self.assert_syntax_error('set myfatherisbillgates\n') 277 self.assert_syntax_error('set myfatherisbillgates\n')
227 278
228 def test_syntax_error__bad_email(self): 279 def test_syntax_error__bad_email(self):
229 self.assert_syntax_error('ben\n') 280 self.assert_syntax_error('ben\n')
230 281
282 def test_syntax_error__invalid_absolute_file(self):
283 self.assert_syntax_error('file://foo/bar/baz\n')
284
285 def test_syntax_error__invalid_relative_file(self):
286 self.assert_syntax_error('file:foo/bar/baz\n')
287
231 288
232 class ReviewersForTest(_BaseTestCase): 289 class ReviewersForTest(_BaseTestCase):
233 def assert_reviewers_for(self, files, potential_suggested_reviewers, 290 def assert_reviewers_for(self, files, potential_suggested_reviewers,
234 author=None): 291 author=None):
235 db = self.db() 292 db = self.db()
236 suggested_reviewers = db.reviewers_for(set(files), author) 293 suggested_reviewers = db.reviewers_for(set(files), author)
237 self.assertTrue(suggested_reviewers in 294 self.assertTrue(suggested_reviewers in
238 [set(suggestion) for suggestion in potential_suggested_reviewers]) 295 [set(suggestion) for suggestion in potential_suggested_reviewers])
239 296
240 def test_reviewers_for__basic_functionality(self): 297 def test_reviewers_for__basic_functionality(self):
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 self.assert_reviewers_for(['chrome/OWNERS', 372 self.assert_reviewers_for(['chrome/OWNERS',
316 'chrome/renderer/gpu/gpu_channel_host.h'], 373 'chrome/renderer/gpu/gpu_channel_host.h'],
317 [[ben, ken], 374 [[ben, ken],
318 [brett, ken]]) 375 [brett, ken]])
319 376
320 def test_reviewers_for__author_is_known(self): 377 def test_reviewers_for__author_is_known(self):
321 # We should never suggest ken as a reviewer for his own changes. 378 # We should never suggest ken as a reviewer for his own changes.
322 self.assert_reviewers_for(['chrome/gpu/gpu_channel.h'], 379 self.assert_reviewers_for(['chrome/gpu/gpu_channel.h'],
323 [[ben], [brett]], author=ken) 380 [[ben], [brett]], author=ken)
324 381
382 def test_reviewers_file_includes__absolute(self):
383 self.assert_reviewers_for(['content/qux/foo.cc'],
384 [[peter], [brett], [john], [darin]])
385
386 def test_reviewers_file_includes__relative(self):
387 self.assert_reviewers_for(['content/garply/foo.cc'],
388 [[peter], [john], [darin]])
389
390 def test_reviewers_file_includes__per_file(self):
391 self.files['/content/garply/OWNERS'] = owners_file(brett,
392 lines=['per-file foo.*=file:test/OWNERS'])
393
394 self.assert_reviewers_for(['content/garply/foo.cc'],
395 [[brett], [peter]])
396 self.assert_reviewers_for(['content/garply/bar.cc'],
397 [[brett]])
398
399 def test_reviewers_file_includes__per_file_noparent(self):
400 self.files['/content/garply/OWNERS'] = owners_file(brett,
401 lines=['per-file foo.*=set noparent',
402 'per-file foo.*=file:test/OWNERS'])
403
404 self.assert_reviewers_for(['content/garply/foo.cc'],
405 [[peter]])
406 self.assert_reviewers_for(['content/garply/bar.cc'],
407 [[brett]])
408
325 409
326 class LowestCostOwnersTest(_BaseTestCase): 410 class LowestCostOwnersTest(_BaseTestCase):
327 # Keep the data in the test_lowest_cost_owner* methods as consistent with 411 # Keep the data in the test_lowest_cost_owner* methods as consistent with
328 # test_repo() where possible to minimize confusion. 412 # test_repo() where possible to minimize confusion.
329 413
330 def check(self, possible_owners, dirs, *possible_lowest_cost_owners): 414 def check(self, possible_owners, dirs, *possible_lowest_cost_owners):
331 suggested_owner = owners.Database.lowest_cost_owner(possible_owners, dirs) 415 suggested_owner = owners.Database.lowest_cost_owner(possible_owners, dirs)
332 self.assertTrue(suggested_owner in possible_lowest_cost_owners) 416 self.assertTrue(suggested_owner in possible_lowest_cost_owners)
333 417
334 def test_one_dir_with_owner(self): 418 def test_one_dir_with_owner(self):
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 ('chrome/browser', 2)], 476 ('chrome/browser', 2)],
393 ken: [('chrome/gpu', 1)], 477 ken: [('chrome/gpu', 1)],
394 peter: [('chrome/renderer', 1)], 478 peter: [('chrome/renderer', 1)],
395 brett: [('chrome/browser', 1)]}, 479 brett: [('chrome/browser', 1)]},
396 ['chrome/gpu', 'chrome/renderer', 480 ['chrome/gpu', 'chrome/renderer',
397 'chrome/browser'], 481 'chrome/browser'],
398 ben) 482 ben)
399 483
400 if __name__ == '__main__': 484 if __name__ == '__main__':
401 unittest.main() 485 unittest.main()
OLDNEW
« no previous file with comments | « testing_support/filesystem_mock.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698