OLD | NEW |
1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 from collections import defaultdict | 5 from collections import defaultdict |
6 import copy | 6 import copy |
7 | 7 |
8 from common.dependency import Dependency | 8 from common.dependency import Dependency |
9 from common.dependency import DependencyRoll | 9 from common.dependency import DependencyRoll |
10 from common import chrome_dependency_fetcher | 10 from common import chrome_dependency_fetcher |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 CallStackFormatType.DEFAULT, LanguageType.CPP), | 114 CallStackFormatType.DEFAULT, LanguageType.CPP), |
115 CallStack(1, [], | 115 CallStack(1, [], |
116 CallStackFormatType.DEFAULT, LanguageType.CPP)] | 116 CallStackFormatType.DEFAULT, LanguageType.CPP)] |
117 DUMMY_REPORT = CrashReport(None, None, None, Stacktrace(DUMMY_CALLSTACKS, | 117 DUMMY_REPORT = CrashReport(None, None, None, Stacktrace(DUMMY_CALLSTACKS, |
118 DUMMY_CALLSTACKS[0]), | 118 DUMMY_CALLSTACKS[0]), |
119 (None, None)) | 119 (None, None)) |
120 | 120 |
121 | 121 |
122 class ChangelistClassifierTest(CrashTestSuite): | 122 class ChangelistClassifierTest(CrashTestSuite): |
123 | 123 |
| 124 @property |
| 125 def _mock_http_gitiles_repo_factory(self): |
| 126 # N.B., we must return a lambda rather than taking ``repo_url`` |
| 127 # as an additional argument to the method/property, to ensure that |
| 128 # things have the right arity when this is eventually called. That |
| 129 # is, we want a function of ``repo_url`` which closes over ``self``, |
| 130 # rather than a function taking two arguments at once. |
| 131 return lambda repo_url: GitilesRepository( |
| 132 self.GetMockHttpClient(), repo_url) |
| 133 |
124 def setUp(self): | 134 def setUp(self): |
125 super(ChangelistClassifierTest, self).setUp() | 135 super(ChangelistClassifierTest, self).setUp() |
126 | 136 |
127 repository = GitilesRepository(self.GetMockHttpClient()) | |
128 | |
129 # TODO(crbug.com/677224): should replace this with an actual factory. | |
130 def MutateTheRepo(dep_url): # pragma: no cover | |
131 """A factory function for returning ``Repository`` objects. | |
132 | |
133 The current definition captures the functionality of before | |
134 we factored out this factory method. That is, it's not really a | |
135 "factory" but rather mutates the main repo object in place. In | |
136 the future this should be changed to do the right thing instead. | |
137 """ | |
138 repository.repo_url = dep_url | |
139 return repository | |
140 | |
141 self.changelist_classifier = changelist_classifier.ChangelistClassifier( | 137 self.changelist_classifier = changelist_classifier.ChangelistClassifier( |
142 repository, MutateTheRepo, 7) | 138 self._mock_http_gitiles_repo_factory, 7) |
143 | 139 |
144 def testSkipAddedAndDeletedRegressionRolls(self): | 140 def testSkipAddedAndDeletedRegressionRolls(self): |
145 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 141 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
146 'GetDependency', lambda *_: {}) | 142 'GetDependency', lambda *_: {}) |
147 dep_rolls = { | 143 dep_rolls = { |
148 'src/dep': DependencyRoll('src/dep1', 'https://url_dep1', None, '9'), | 144 'src/dep': DependencyRoll('src/dep1', 'https://url_dep1', None, '9'), |
149 'src/': DependencyRoll('src/', ('https://chromium.googlesource.com/' | 145 'src/': DependencyRoll('src/', ('https://chromium.googlesource.com/' |
150 'chromium/src.git'), '4', '5') | 146 'chromium/src.git'), '4', '5') |
151 } | 147 } |
152 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 148 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 def _MockGetChangeLogs(_, start_rev, end_rev): | 204 def _MockGetChangeLogs(_, start_rev, end_rev): |
209 if start_rev == '4' and end_rev == '5': | 205 if start_rev == '4' and end_rev == '5': |
210 return [DUMMY_CHANGELOG1, DUMMY_CHANGELOG2, DUMMY_CHANGELOG3] | 206 return [DUMMY_CHANGELOG1, DUMMY_CHANGELOG2, DUMMY_CHANGELOG3] |
211 | 207 |
212 return [] | 208 return [] |
213 | 209 |
214 self.mock(GitilesRepository, 'GetChangeLogs', _MockGetChangeLogs) | 210 self.mock(GitilesRepository, 'GetChangeLogs', _MockGetChangeLogs) |
215 | 211 |
216 dep_file_to_changelogs, ignore_cls = ( | 212 dep_file_to_changelogs, ignore_cls = ( |
217 changelist_classifier.GetChangeLogsForFilesGroupedByDeps( | 213 changelist_classifier.GetChangeLogsForFilesGroupedByDeps( |
218 regression_deps_rolls, stack_deps, | 214 regression_deps_rolls, |
219 GitilesRepository(self.GetMockHttpClient()))) | 215 stack_deps, |
| 216 self._mock_http_gitiles_repo_factory)) |
220 dep_file_to_changelogs_json = defaultdict(lambda: defaultdict(list)) | 217 dep_file_to_changelogs_json = defaultdict(lambda: defaultdict(list)) |
221 for dep, file_to_changelogs in dep_file_to_changelogs.iteritems(): | 218 for dep, file_to_changelogs in dep_file_to_changelogs.iteritems(): |
222 for file_path, changelogs in file_to_changelogs.iteritems(): | 219 for file_path, changelogs in file_to_changelogs.iteritems(): |
223 for changelog in changelogs: | 220 for changelog in changelogs: |
224 dep_file_to_changelogs_json[dep][file_path].append(changelog.ToDict()) | 221 dep_file_to_changelogs_json[dep][file_path].append(changelog.ToDict()) |
225 | 222 |
226 expected_dep_file_to_changelogs_json = { | 223 expected_dep_file_to_changelogs_json = { |
227 'src/': { | 224 'src/': { |
228 'a.cc': [DUMMY_CHANGELOG1.ToDict()], | 225 'a.cc': [DUMMY_CHANGELOG1.ToDict()], |
229 'f.cc': [DUMMY_CHANGELOG3.ToDict()] | 226 'f.cc': [DUMMY_CHANGELOG3.ToDict()] |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 'project_path': 'src/', | 318 'project_path': 'src/', |
322 'author': 'r@chromium.org', | 319 'author': 'r@chromium.org', |
323 'time': 'Thu Mar 31 21:24:43 2016', | 320 'time': 'Thu Mar 31 21:24:43 2016', |
324 'reasons': None, | 321 'reasons': None, |
325 'confidence': None, | 322 'confidence': None, |
326 'changed_files': None | 323 'changed_files': None |
327 }] | 324 }] |
328 | 325 |
329 suspects = changelist_classifier.FindSuspects( | 326 suspects = changelist_classifier.FindSuspects( |
330 dep_file_to_changelogs, dep_file_to_stack_infos, stack_deps, | 327 dep_file_to_changelogs, dep_file_to_stack_infos, stack_deps, |
331 lambda repo_url: GitilesRepository(self.GetMockHttpClient(), repo_url)) | 328 self._mock_http_gitiles_repo_factory) |
332 self.assertListEqual([suspect.ToDict() for suspect in suspects], | 329 self.assertListEqual([suspect.ToDict() for suspect in suspects], |
333 expected_suspects) | 330 expected_suspects) |
334 | 331 |
335 # TODO(http://crbug.com/659346): why do these mocks give coverage | 332 # TODO(http://crbug.com/659346): why do these mocks give coverage |
336 # failures? That's almost surely hiding a bug in the tests themselves. | 333 # failures? That's almost surely hiding a bug in the tests themselves. |
337 def testFindItForCrashNoRegressionRange(self): # pragma: no cover | 334 def testFindItForCrashNoRegressionRange(self): # pragma: no cover |
338 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 335 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
339 'GetDependencyRollsDict', lambda *_: {}) | 336 'GetDependencyRollsDict', lambda *_: {}) |
340 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 337 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
341 'GetDependency', lambda *_: {}) | 338 'GetDependency', lambda *_: {}) |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 return [suspect1, suspect2] | 495 return [suspect1, suspect2] |
499 | 496 |
500 self.mock(changelist_classifier, 'FindSuspects', _MockFindSuspects) | 497 self.mock(changelist_classifier, 'FindSuspects', _MockFindSuspects) |
501 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 498 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
502 'GetDependencyRollsDict', | 499 'GetDependencyRollsDict', |
503 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) | 500 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) |
504 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 501 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
505 'GetDependency', lambda *_: {}) | 502 'GetDependency', lambda *_: {}) |
506 | 503 |
507 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), []) | 504 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), []) |
OLD | NEW |