OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 unittest | 8 import unittest |
9 | 9 |
10 import owners | 10 import owners |
11 from tests import filesystem_mock | 11 from tests import filesystem_mock |
12 | 12 |
13 ben = 'ben@example.com' | 13 ben = 'ben@example.com' |
14 brett = 'brett@example.com' | 14 brett = 'brett@example.com' |
15 darin = 'darin@example.com' | 15 darin = 'darin@example.com' |
16 john = 'john@example.com' | 16 john = 'john@example.com' |
17 ken = 'ken@example.com' | 17 ken = 'ken@example.com' |
18 peter = 'peter@example.com' | 18 peter = 'peter@example.com' |
19 | 19 |
20 def owners_file(*email_addresses, **kwargs): | 20 def owners_file(*email_addresses, **kwargs): |
21 s = '' | 21 s = '' |
| 22 if kwargs.get('comment'): |
| 23 s += '# %s\n' % kwargs.get('comment') |
22 if kwargs.get('noparent'): | 24 if kwargs.get('noparent'): |
23 s = 'set noparent\n' | 25 s += 'set noparent\n' |
24 return s + '\n'.join(email_addresses) + '\n' | 26 return s + '\n'.join(email_addresses) + '\n' |
25 | 27 |
26 | 28 |
27 def test_repo(): | 29 def test_repo(): |
28 return filesystem_mock.MockFileSystem(files={ | 30 return filesystem_mock.MockFileSystem(files={ |
29 '/DEPS' : '', | 31 '/DEPS' : '', |
30 '/OWNERS': owners_file('*'), | 32 '/OWNERS': owners_file(owners.EVERYONE), |
31 '/base/vlog.h': '', | 33 '/base/vlog.h': '', |
32 '/chrome/OWNERS': owners_file(ben, brett), | 34 '/chrome/OWNERS': owners_file(ben, brett), |
33 '/chrome/gpu/OWNERS': owners_file(ken), | 35 '/chrome/gpu/OWNERS': owners_file(ken), |
34 '/chrome/gpu/gpu_channel.h': '', | 36 '/chrome/gpu/gpu_channel.h': '', |
35 '/chrome/renderer/OWNERS': owners_file(peter), | 37 '/chrome/renderer/OWNERS': owners_file(peter), |
36 '/chrome/renderer/gpu/gpu_channel_host.h': '', | 38 '/chrome/renderer/gpu/gpu_channel_host.h': '', |
37 '/chrome/renderer/safe_browsing/scorer.h': '', | 39 '/chrome/renderer/safe_browsing/scorer.h': '', |
38 '/content/OWNERS': owners_file(john, darin, noparent=True), | 40 '/content/OWNERS': owners_file(john, darin, comment='foo', noparent=True), |
39 '/content/content.gyp': '', | 41 '/content/content.gyp': '', |
40 }) | 42 }) |
41 | 43 |
42 | 44 |
43 class OwnersDatabaseTest(unittest.TestCase): | 45 class OwnersDatabaseTest(unittest.TestCase): |
44 def setUp(self): | 46 def setUp(self): |
45 self.repo = test_repo() | 47 self.repo = test_repo() |
46 self.files = self.repo.files | 48 self.files = self.repo.files |
47 self.root = '/' | 49 self.root = '/' |
48 self.fopen = self.repo.open_for_reading | 50 self.fopen = self.repo.open_for_reading |
49 | 51 |
50 def db(self, root=None, fopen=None, os_path=None): | 52 def db(self, root=None, fopen=None, os_path=None): |
51 root = root or self.root | 53 root = root or self.root |
52 fopen = fopen or self.fopen | 54 fopen = fopen or self.fopen |
53 os_path = os_path or self.repo | 55 os_path = os_path or self.repo |
54 return owners.Database(root, fopen, os_path) | 56 return owners.Database(root, fopen, os_path) |
55 | 57 |
56 def assertReviewersFor(self, files, expected_reviewers): | 58 def test_Constructor(self): |
57 db = self.db() | 59 self.assertNotEquals(self.db(), None) |
58 self.assertEquals(db.ReviewersFor(set(files)), set(expected_reviewers)) | |
59 | 60 |
60 def assertCoveredBy(self, files, reviewers): | 61 def assert_CoveredBy(self, files, reviewers): |
61 db = self.db() | 62 db = self.db() |
62 self.assertTrue(db.FilesAreCoveredBy(set(files), set(reviewers))) | 63 self.assertTrue(db.FilesAreCoveredBy(set(files), set(reviewers))) |
63 | 64 |
64 def assertNotCoveredBy(self, files, reviewers, unreviewed_files): | 65 def test_CoveredBy_Everyone(self): |
| 66 self.assert_CoveredBy(['DEPS'], [john]) |
| 67 self.assert_CoveredBy(['DEPS'], [darin]) |
| 68 |
| 69 def test_CoveredBy_Explicit(self): |
| 70 self.assert_CoveredBy(['content/content.gyp'], [john]) |
| 71 self.assert_CoveredBy(['chrome/gpu/OWNERS'], [ken]) |
| 72 |
| 73 def test_CoveredBy_OwnersPropagatesDown(self): |
| 74 self.assert_CoveredBy(['chrome/gpu/OWNERS'], [ben]) |
| 75 self.assert_CoveredBy(['/chrome/renderer/gpu/gpu_channel_host.h'], [peter]) |
| 76 |
| 77 def assert_NotCoveredBy(self, files, reviewers, unreviewed_files): |
65 db = self.db() | 78 db = self.db() |
66 self.assertEquals(db.FilesNotCoveredBy(set(files), set(reviewers)), | 79 self.assertEquals(db.FilesNotCoveredBy(set(files), set(reviewers)), |
67 set(unreviewed_files)) | 80 set(unreviewed_files)) |
68 | 81 |
69 def test_constructor(self): | 82 def test_NotCoveredBy_NeedAtLeastOneReviewer(self): |
70 self.assertNotEquals(self.db(), None) | 83 self.assert_NotCoveredBy(['DEPS'], [], ['DEPS']) |
71 | 84 |
72 def test_owners_for(self): | 85 def test_NotCoveredBy_OwnersPropagatesDown(self): |
73 self.assertReviewersFor(['DEPS'], [owners.ANYONE]) | 86 self.assert_NotCoveredBy( |
74 self.assertReviewersFor(['content/content.gyp'], [john, darin]) | |
75 self.assertReviewersFor(['chrome/gpu/gpu_channel.h'], [ken]) | |
76 | |
77 def test_covered_by(self): | |
78 self.assertCoveredBy(['DEPS'], [john]) | |
79 self.assertCoveredBy(['DEPS'], [darin]) | |
80 self.assertCoveredBy(['content/content.gyp'], [john]) | |
81 self.assertCoveredBy(['chrome/gpu/OWNERS'], [ken]) | |
82 self.assertCoveredBy(['chrome/gpu/OWNERS'], [ben]) | |
83 | |
84 def test_not_covered_by(self): | |
85 self.assertNotCoveredBy(['DEPS'], [], ['DEPS']) | |
86 self.assertNotCoveredBy(['content/content.gyp'], [ben], | |
87 ['content/content.gyp']) | |
88 self.assertNotCoveredBy( | |
89 ['chrome/gpu/gpu_channel.h', 'chrome/renderer/gpu/gpu_channel_host.h'], | |
90 [peter], ['chrome/gpu/gpu_channel.h']) | |
91 self.assertNotCoveredBy( | |
92 ['chrome/gpu/gpu_channel.h', 'chrome/renderer/gpu/gpu_channel_host.h'], | 87 ['chrome/gpu/gpu_channel.h', 'chrome/renderer/gpu/gpu_channel_host.h'], |
93 [ben], []) | 88 [ben], []) |
94 | 89 |
95 def test_comments_in_owners_file(self): | 90 def test_NotCoveredBy_PartialCovering(self): |
96 # pylint: disable=W0212 | 91 self.assert_NotCoveredBy( |
| 92 ['content/content.gyp', 'chrome/renderer/gpu/gpu_channel_host.h'], |
| 93 [peter], ['content/content.gyp']) |
| 94 |
| 95 def test_NotCoveredBy_SetNoParentWorks(self): |
| 96 self.assert_NotCoveredBy(['content/content.gyp'], [ben], |
| 97 ['content/content.gyp']) |
| 98 |
| 99 def assert_ReviewersFor(self, files, expected_reviewers): |
97 db = self.db() | 100 db = self.db() |
98 # Tests that this doesn't raise an error. | 101 self.assertEquals(db.ReviewersFor(set(files)), set(expected_reviewers)) |
99 db._ReadOwnersFile('OWNERS', 'DEPS') | |
100 | 102 |
101 def test_syntax_error_in_owners_file(self): | 103 def test_ReviewersFor_BasicFunctionality(self): |
102 # pylint: disable=W0212 | 104 self.assert_ReviewersFor(['chrome/gpu/gpu_channel.h'], |
| 105 [ken, ben, brett, owners.EVERYONE]) |
| 106 |
| 107 def test_ReviewersFor_SetNoParentWorks(self): |
| 108 self.assert_ReviewersFor(['content/content.gyp'], [john, darin]) |
| 109 |
| 110 def test_ReviewersFor_WildcardDir(self): |
| 111 self.assert_ReviewersFor(['DEPS'], [owners.EVERYONE]) |
| 112 |
| 113 def assert_SyntaxError(self, owners_file_contents): |
103 db = self.db() | 114 db = self.db() |
104 self.files['/foo/OWNERS'] = '{}\n' | 115 self.files['/foo/OWNERS'] = owners_file_contents |
105 self.files['/foo/DEPS'] = '# DEPS\n' | 116 self.files['/foo/DEPS'] = '' |
106 self.assertRaises(owners.SyntaxErrorInOwnersFile, db._ReadOwnersFile, | 117 self.assertRaises(owners.SyntaxErrorInOwnersFile, db.ReviewersFor, |
107 '/foo/OWNERS', '/foo/DEPS') | 118 ['/foo/DEPS']) |
108 | 119 |
109 self.files['/bar/OWNERS'] = 'set myparentislinus\n' | 120 def test_SyntaxError_UnknownToken(self): |
110 self.files['/bar/DEPS'] = '# DEPS\n' | 121 self.assert_SyntaxError('{}\n') |
111 self.assertRaises(owners.SyntaxErrorInOwnersFile, db._ReadOwnersFile, | |
112 '/bar/OWNERS', '/bar/DEPS') | |
113 | 122 |
114 def test_owners_propagates_down(self): | 123 def test_SyntaxError_UnknownSet(self): |
115 self.assertCoveredBy(['/chrome/renderer/gpu/gpu_channel_host.h'], [peter]) | 124 self.assert_SyntaxError('set myfatherisbillgates\n') |
116 | 125 |
117 def test_set_noparent(self): | 126 def test_SyntaxError_BadEmail(self): |
118 self.assertNotCoveredBy(['/content/content.gyp'], [peter], | 127 self.assert_SyntaxError('ben\n') |
119 ['/content/content.gyp']) | |
120 | 128 |
121 | 129 |
122 if __name__ == '__main__': | 130 if __name__ == '__main__': |
123 unittest.main() | 131 unittest.main() |
OLD | NEW |