OLD | NEW |
1 # Copyright (C) 2009 Google Inc. All rights reserved. | 1 # Copyright (C) 2009 Google Inc. All rights reserved. |
2 # | 2 # |
3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
5 # met: | 5 # met: |
6 # | 6 # |
7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
(...skipping 18 matching lines...) Expand all Loading... |
29 import unittest | 29 import unittest |
30 | 30 |
31 from webkitpy.common.net.layouttestresults import LayoutTestResults | 31 from webkitpy.common.net.layouttestresults import LayoutTestResults |
32 from webkitpy.common.net.buildbot import BuildBot, Builder, Build | 32 from webkitpy.common.net.buildbot import BuildBot, Builder, Build |
33 from webkitpy.layout_tests.models import test_results | 33 from webkitpy.layout_tests.models import test_results |
34 from webkitpy.layout_tests.models import test_failures | 34 from webkitpy.layout_tests.models import test_failures |
35 from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup | 35 from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup |
36 | 36 |
37 | 37 |
38 class BuilderTest(unittest.TestCase): | 38 class BuilderTest(unittest.TestCase): |
| 39 |
39 def _mock_test_result(self, testname): | 40 def _mock_test_result(self, testname): |
40 return test_results.TestResult(testname, [test_failures.FailureTextMisma
tch()]) | 41 return test_results.TestResult(testname, [test_failures.FailureTextMisma
tch()]) |
41 | 42 |
42 def _install_fetch_build(self, failure): | 43 def _install_fetch_build(self, failure): |
43 def _mock_fetch_build(build_number): | 44 def _mock_fetch_build(build_number): |
44 build = Build( | 45 build = Build( |
45 builder=self.builder, | 46 builder=self.builder, |
46 build_number=build_number, | 47 build_number=build_number, |
47 revision=build_number + 1000, | 48 revision=build_number + 1000, |
48 is_green=build_number < 4 | 49 is_green=build_number < 4 |
49 ) | 50 ) |
50 return build | 51 return build |
51 self.builder._fetch_build = _mock_fetch_build | 52 self.builder._fetch_build = _mock_fetch_build |
52 | 53 |
53 def setUp(self): | 54 def setUp(self): |
54 self.buildbot = BuildBot() | 55 self.buildbot = BuildBot() |
55 self.builder = Builder(u"Test Builder \u2661", self.buildbot) | 56 self.builder = Builder(u"Test Builder \u2661", self.buildbot) |
56 self._install_fetch_build(lambda build_number: ["test1", "test2"]) | 57 self._install_fetch_build(lambda build_number: ["test1", "test2"]) |
57 | 58 |
58 def test_latest_layout_test_results(self): | 59 def test_latest_layout_test_results(self): |
59 self.builder.fetch_layout_test_results = lambda results_url: LayoutTestR
esults(None) | 60 self.builder.fetch_layout_test_results = lambda results_url: LayoutTestR
esults(None) |
60 self.builder.accumulated_results_url = lambda: "http://dummy_url.org" | 61 self.builder.accumulated_results_url = lambda: "http://dummy_url.org" |
61 self.assertTrue(self.builder.latest_layout_test_results()) | 62 self.assertTrue(self.builder.latest_layout_test_results()) |
62 | 63 |
63 def test_build_caching(self): | 64 def test_build_caching(self): |
64 self.assertEqual(self.builder.build(10), self.builder.build(10)) | 65 self.assertEqual(self.builder.build(10), self.builder.build(10)) |
65 | 66 |
66 def test_build_and_revision_for_filename(self): | 67 def test_build_and_revision_for_filename(self): |
67 expectations = { | 68 expectations = { |
68 "r47483 (1)/" : (47483, 1), | 69 "r47483 (1)/": (47483, 1), |
69 "r47483 (1).zip" : (47483, 1), | 70 "r47483 (1).zip": (47483, 1), |
70 "random junk": None, | 71 "random junk": None, |
71 } | 72 } |
72 for filename, revision_and_build in expectations.items(): | 73 for filename, revision_and_build in expectations.items(): |
73 self.assertEqual(self.builder._revision_and_build_for_filename(filen
ame), revision_and_build) | 74 self.assertEqual(self.builder._revision_and_build_for_filename(filen
ame), revision_and_build) |
74 | 75 |
75 def test_file_info_list_to_revision_to_build_list(self): | 76 def test_file_info_list_to_revision_to_build_list(self): |
76 file_info_list = [ | 77 file_info_list = [ |
77 {"filename": "r47483 (1)/"}, | 78 {"filename": "r47483 (1)/"}, |
78 {"filename": "r47483 (1).zip"}, | 79 {"filename": "r47483 (1).zip"}, |
79 {"filename": "random junk"}, | 80 {"filename": "random junk"}, |
80 ] | 81 ] |
81 builds_and_revisions_list = [(47483, 1), (47483, 1)] | 82 builds_and_revisions_list = [(47483, 1), (47483, 1)] |
82 self.assertEqual(self.builder._file_info_list_to_revision_to_build_list(
file_info_list), builds_and_revisions_list) | 83 self.assertEqual(self.builder._file_info_list_to_revision_to_build_list(
file_info_list), builds_and_revisions_list) |
83 | 84 |
84 def test_fetch_build(self): | 85 def test_fetch_build(self): |
85 buildbot = BuildBot() | 86 buildbot = BuildBot() |
86 builder = Builder(u"Test Builder \u2661", buildbot) | 87 builder = Builder(u"Test Builder \u2661", buildbot) |
87 | 88 |
88 def mock_fetch_build_dictionary(self, build_number): | 89 def mock_fetch_build_dictionary(self, build_number): |
89 build_dictionary = { | 90 build_dictionary = { |
90 "sourceStamp": { | 91 "sourceStamp": { |
91 "revision": None, # revision=None means a trunk build start
ed from the force-build button on the builder page. | 92 "revision": None, # revision=None means a trunk build start
ed from the force-build button on the builder page. |
92 }, | 93 }, |
93 "number": int(build_number), | 94 "number": int(build_number), |
94 # Intentionally missing the 'results' key, meaning it's a "pass"
build. | 95 # Intentionally missing the 'results' key, meaning it's a "pass"
build. |
95 } | 96 } |
96 return build_dictionary | 97 return build_dictionary |
97 buildbot._fetch_build_dictionary = mock_fetch_build_dictionary | 98 buildbot._fetch_build_dictionary = mock_fetch_build_dictionary |
98 self.assertIsNotNone(builder._fetch_build(1)) | 99 self.assertIsNotNone(builder._fetch_build(1)) |
99 | 100 |
100 def test_results_url(self): | 101 def test_results_url(self): |
101 builder = BuildBot().builder_with_name('WebKit Mac10.8 (dbg)') | 102 builder = BuildBot().builder_with_name('WebKit Mac10.8 (dbg)') |
102 self.assertEqual(builder.results_url(), | 103 self.assertEqual(builder.results_url(), |
(...skipping 23 matching lines...) Expand all Loading... |
126 <td align="center" class="Activity idle">idle<br />3 pending</td> | 127 <td align="center" class="Activity idle">idle<br />3 pending</td> |
127 <tr> | 128 <tr> |
128 <td class="box"><a href="builders/Qt%20Windows%2032-bit%20Debug">Qt Windows
32-bit Debug</a></td> | 129 <td class="box"><a href="builders/Qt%20Windows%2032-bit%20Debug">Qt Windows
32-bit Debug</a></td> |
129 <td align="center" class="LastBuild box failure"><a href="builders/Qt%20Wi
ndows%2032-bit%20Debug/builds/2090">60563</a><br />failed<br />failed<br />slave
<br />lost</td> | 130 <td align="center" class="LastBuild box failure"><a href="builders/Qt%20Wi
ndows%2032-bit%20Debug/builds/2090">60563</a><br />failed<br />failed<br />slave
<br />lost</td> |
130 <td align="center" class="Activity building">building<br />ETA in<br />~ 5
mins<br />at 08:25</td> | 131 <td align="center" class="Activity building">building<br />ETA in<br />~ 5
mins<br />at 08:25</td> |
131 </table> | 132 </table> |
132 ''' | 133 ''' |
133 _expected_example_one_box_parsings = [ | 134 _expected_example_one_box_parsings = [ |
134 { | 135 { |
135 'is_green': True, | 136 'is_green': True, |
136 'build_number' : 3693, | 137 'build_number': 3693, |
137 'name': u'Windows Debug (Tests)', | 138 'name': u'Windows Debug (Tests)', |
138 'built_revision': 47380, | 139 'built_revision': 47380, |
139 'activity': 'building', | 140 'activity': 'building', |
140 'pending_builds': 0, | 141 'pending_builds': 0, |
141 }, | 142 }, |
142 { | 143 { |
143 'is_green': False, | 144 'is_green': False, |
144 'build_number' : None, | 145 'build_number': None, |
145 'name': u'SnowLeopard Intel Release', | 146 'name': u'SnowLeopard Intel Release', |
146 'built_revision': None, | 147 'built_revision': None, |
147 'activity': 'building', | 148 'activity': 'building', |
148 'pending_builds': 0, | 149 'pending_builds': 0, |
149 }, | 150 }, |
150 { | 151 { |
151 'is_green': False, | 152 'is_green': False, |
152 'build_number' : 654, | 153 'build_number': 654, |
153 'name': u'Qt Linux Release', | 154 'name': u'Qt Linux Release', |
154 'built_revision': 47383, | 155 'built_revision': 47383, |
155 'activity': 'idle', | 156 'activity': 'idle', |
156 'pending_builds': 3, | 157 'pending_builds': 3, |
157 }, | 158 }, |
158 { | 159 { |
159 'is_green': True, | 160 'is_green': True, |
160 'build_number' : 2090, | 161 'build_number': 2090, |
161 'name': u'Qt Windows 32-bit Debug', | 162 'name': u'Qt Windows 32-bit Debug', |
162 'built_revision': 60563, | 163 'built_revision': 60563, |
163 'activity': 'building', | 164 'activity': 'building', |
164 'pending_builds': 0, | 165 'pending_builds': 0, |
165 }, | 166 }, |
166 ] | 167 ] |
167 | 168 |
168 def test_status_parsing(self): | 169 def test_status_parsing(self): |
169 buildbot = BuildBot() | 170 buildbot = BuildBot() |
170 | 171 |
171 soup = BeautifulSoup(self._example_one_box_status) | 172 soup = BeautifulSoup(self._example_one_box_status) |
172 status_table = soup.find("table") | 173 status_table = soup.find("table") |
173 input_rows = status_table.findAll('tr') | 174 input_rows = status_table.findAll('tr') |
174 | 175 |
175 for x in range(len(input_rows)): | 176 for x in range(len(input_rows)): |
176 status_row = input_rows[x] | 177 status_row = input_rows[x] |
177 expected_parsing = self._expected_example_one_box_parsings[x] | 178 expected_parsing = self._expected_example_one_box_parsings[x] |
178 | 179 |
179 builder = buildbot._parse_builder_status_from_row(status_row) | 180 builder = buildbot._parse_builder_status_from_row(status_row) |
180 | 181 |
181 # Make sure we aren't parsing more or less than we expect | 182 # Make sure we aren't parsing more or less than we expect |
182 self.assertEqual(builder.keys(), expected_parsing.keys()) | 183 self.assertEqual(builder.keys(), expected_parsing.keys()) |
183 | 184 |
184 for key, expected_value in expected_parsing.items(): | 185 for key, expected_value in expected_parsing.items(): |
185 self.assertEqual(builder[key], expected_value, ("Builder %d pars
e failure for key: %s: Actual='%s' Expected='%s'" % (x, key, builder[key], expec
ted_value))) | 186 self.assertEqual(builder[key], expected_value, ("Builder %d pars
e failure for key: %s: Actual='%s' Expected='%s'" % ( |
| 187 x, key, builder[key], expected_value))) |
186 | 188 |
187 def test_builder_with_name(self): | 189 def test_builder_with_name(self): |
188 buildbot = BuildBot() | 190 buildbot = BuildBot() |
189 | 191 |
190 builder = buildbot.builder_with_name("Test Builder") | 192 builder = buildbot.builder_with_name("Test Builder") |
191 self.assertEqual(builder.name(), "Test Builder") | 193 self.assertEqual(builder.name(), "Test Builder") |
192 self.assertEqual(builder.url(), "http://build.chromium.org/p/chromium.we
bkit/builders/Test%20Builder") | 194 self.assertEqual(builder.url(), "http://build.chromium.org/p/chromium.we
bkit/builders/Test%20Builder") |
193 self.assertEqual(builder.url_encoded_name(), "Test%20Builder") | 195 self.assertEqual(builder.url_encoded_name(), "Test%20Builder") |
194 self.assertEqual(builder.results_url(), "https://storage.googleapis.com/
chromium-layout-test-archives/Test_Builder") | 196 self.assertEqual(builder.results_url(), "https://storage.googleapis.com/
chromium-layout-test-archives/Test_Builder") |
195 | 197 |
196 # Override _fetch_build_dictionary function to not touch the network. | 198 # Override _fetch_build_dictionary function to not touch the network. |
197 def mock_fetch_build_dictionary(self, build_number): | 199 def mock_fetch_build_dictionary(self, build_number): |
198 build_dictionary = { | 200 build_dictionary = { |
199 "sourceStamp": { | 201 "sourceStamp": { |
200 "revision" : 2 * build_number, | 202 "revision": 2 * build_number, |
201 }, | 203 }, |
202 "number" : int(build_number), | 204 "number": int(build_number), |
203 "results" : build_number % 2, # 0 means pass | 205 "results": build_number % 2, # 0 means pass |
204 } | 206 } |
205 return build_dictionary | 207 return build_dictionary |
206 buildbot._fetch_build_dictionary = mock_fetch_build_dictionary | 208 buildbot._fetch_build_dictionary = mock_fetch_build_dictionary |
207 | 209 |
208 build = builder.build(10) | 210 build = builder.build(10) |
209 self.assertEqual(build.builder(), builder) | 211 self.assertEqual(build.builder(), builder) |
210 self.assertEqual(build.url(), "http://build.chromium.org/p/chromium.webk
it/builders/Test%20Builder/builds/10") | 212 self.assertEqual(build.url(), "http://build.chromium.org/p/chromium.webk
it/builders/Test%20Builder/builds/10") |
211 self.assertEqual(build.results_url(), "https://storage.googleapis.com/ch
romium-layout-test-archives/Test_Builder/r20%20%2810%29") | 213 self.assertEqual(build.results_url(), "https://storage.googleapis.com/ch
romium-layout-test-archives/Test_Builder/r20%20%2810%29") |
212 self.assertEqual(build.revision(), 20) | 214 self.assertEqual(build.revision(), 20) |
213 self.assertTrue(build.is_green()) | 215 self.assertTrue(build.is_green()) |
(...skipping 25 matching lines...) Expand all Loading... |
239 </tr> | 241 </tr> |
240 <tr class="file alt"> | 242 <tr class="file alt"> |
241 <td><a href="r47484%20%282%29.zip">r47484 (2).zip</a></td> | 243 <td><a href="r47484%20%282%29.zip">r47484 (2).zip</a></td> |
242 <td>89K</td> | 244 <td>89K</td> |
243 <td>[application/zip]</td> | 245 <td>[application/zip]</td> |
244 <td></td> | 246 <td></td> |
245 </tr> | 247 </tr> |
246 ''' | 248 ''' |
247 _expected_files = [ | 249 _expected_files = [ |
248 { | 250 { |
249 "filename" : "r47483 (1)/", | 251 "filename": "r47483 (1)/", |
250 "size" : "", | 252 "size": "", |
251 "type" : "[Directory]", | 253 "type": "[Directory]", |
252 "encoding" : "", | 254 "encoding": "", |
253 }, | 255 }, |
254 { | 256 { |
255 "filename" : "r47484 (2).zip", | 257 "filename": "r47484 (2).zip", |
256 "size" : "89K", | 258 "size": "89K", |
257 "type" : "[application/zip]", | 259 "type": "[application/zip]", |
258 "encoding" : "", | 260 "encoding": "", |
259 }, | 261 }, |
260 ] | 262 ] |
261 | 263 |
262 def test_parse_build_to_revision_map(self): | 264 def test_parse_build_to_revision_map(self): |
263 buildbot = BuildBot() | 265 buildbot = BuildBot() |
264 files = buildbot._parse_twisted_directory_listing(self._example_director
y_listing) | 266 files = buildbot._parse_twisted_directory_listing(self._example_director
y_listing) |
265 self.assertEqual(self._expected_files, files) | 267 self.assertEqual(self._expected_files, files) |
266 | 268 |
267 _fake_builder_page = ''' | 269 _fake_builder_page = ''' |
268 <body> | 270 <body> |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 <td class="failure">failure</td> | 335 <td class="failure">failure</td> |
334 </tr> | 336 </tr> |
335 </table> | 337 </table> |
336 </body>''' | 338 </body>''' |
337 | 339 |
338 def test_revisions_for_builder(self): | 340 def test_revisions_for_builder(self): |
339 buildbot = BuildBot() | 341 buildbot = BuildBot() |
340 buildbot._fetch_builder_page = lambda builder: builder.page | 342 buildbot._fetch_builder_page = lambda builder: builder.page |
341 builder_with_success = Builder('Some builder', None) | 343 builder_with_success = Builder('Some builder', None) |
342 builder_with_success.page = self._fake_builder_page | 344 builder_with_success.page = self._fake_builder_page |
343 self.assertEqual(buildbot._revisions_for_builder(builder_with_success),
[(104643, False), (104636, False), (104635, True), (104633, False)]) | 345 self.assertEqual(buildbot._revisions_for_builder(builder_with_success),
[ |
| 346 (104643, False), (104636, False), (104635, True), (1046
33, False)]) |
344 | 347 |
345 builder_without_success = Builder('Some builder', None) | 348 builder_without_success = Builder('Some builder', None) |
346 builder_without_success.page = self._fake_builder_page_without_success | 349 builder_without_success.page = self._fake_builder_page_without_success |
347 self.assertEqual(buildbot._revisions_for_builder(builder_without_success
), [(104643, False), (104636, False), (104635, False), (104633, False)]) | 350 self.assertEqual(buildbot._revisions_for_builder(builder_without_success
), [ |
| 351 (104643, False), (104636, False), (104635, False), (104
633, False)]) |
348 | 352 |
349 def test_find_green_revision(self): | 353 def test_find_green_revision(self): |
350 buildbot = BuildBot() | 354 buildbot = BuildBot() |
351 self.assertEqual(buildbot._find_green_revision({ | 355 self.assertEqual(buildbot._find_green_revision({ |
352 'Builder 1': [(1, True), (3, True)], | 356 'Builder 1': [(1, True), (3, True)], |
353 'Builder 2': [(1, True), (3, False)], | 357 'Builder 2': [(1, True), (3, False)], |
354 'Builder 3': [(1, True), (3, True)], | 358 'Builder 3': [(1, True), (3, True)], |
355 }), 1) | 359 }), 1) |
356 self.assertEqual(buildbot._find_green_revision({ | 360 self.assertEqual(buildbot._find_green_revision({ |
357 'Builder 1': [(1, False), (3, True)], | 361 'Builder 1': [(1, False), (3, True)], |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 b._fetch_revision_to_build_map = self._fetch_revision_to_build_map | 417 b._fetch_revision_to_build_map = self._fetch_revision_to_build_map |
414 self.assertEqual("correct build", b.latest_cached_build()) | 418 self.assertEqual("correct build", b.latest_cached_build()) |
415 | 419 |
416 def results_url(self): | 420 def results_url(self): |
417 return "some-url" | 421 return "some-url" |
418 | 422 |
419 def test_results_zip_url(self): | 423 def test_results_zip_url(self): |
420 b = Build(None, 123, 123, False) | 424 b = Build(None, 123, 123, False) |
421 b.results_url = self.results_url | 425 b.results_url = self.results_url |
422 self.assertEqual("some-url.zip", b.results_zip_url()) | 426 self.assertEqual("some-url.zip", b.results_zip_url()) |
OLD | NEW |