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

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/common/net/buildbot/buildbot_unittest.py

Issue 1953463002: Empty webkitpy/common/net/buildbot/__init__.py and update imports. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove the net/buildbot/ subdirectory; move the files into net/ and fix pylint warnings Created 4 years, 7 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
OLDNEW
(Empty)
1 # Copyright (C) 2009 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
12 # distribution.
13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 import unittest
30
31 from webkitpy.common.net.layouttestresults import LayoutTestResults
32 from webkitpy.common.net.buildbot import BuildBot, Builder, Build
33 from webkitpy.layout_tests.models import test_results
34 from webkitpy.layout_tests.models import test_failures
35 from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup
36
37
38 class BuilderTest(unittest.TestCase):
39
40 def _mock_test_result(self, testname):
41 return test_results.TestResult(testname, [test_failures.FailureTextMisma tch()])
42
43 def _install_fetch_build(self, failure):
44 def _mock_fetch_build(build_number):
45 build = Build(
46 builder=self.builder,
47 build_number=build_number,
48 revision=build_number + 1000,
49 is_green=build_number < 4
50 )
51 return build
52 self.builder._fetch_build = _mock_fetch_build
53
54 def setUp(self):
55 self.buildbot = BuildBot()
56 self.builder = Builder(u"Test Builder \u2661", self.buildbot)
57 self._install_fetch_build(lambda build_number: ["test1", "test2"])
58
59 def test_latest_layout_test_results(self):
60 self.builder.fetch_layout_test_results = lambda results_url: LayoutTestR esults(None)
61 self.builder.accumulated_results_url = lambda: "http://dummy_url.org"
62 self.assertTrue(self.builder.latest_layout_test_results())
63
64 def test_build_caching(self):
65 self.assertEqual(self.builder.build(10), self.builder.build(10))
66
67 def test_build_and_revision_for_filename(self):
68 expectations = {
69 "r47483 (1)/": (47483, 1),
70 "r47483 (1).zip": (47483, 1),
71 "random junk": None,
72 }
73 for filename, revision_and_build in expectations.items():
74 self.assertEqual(self.builder._revision_and_build_for_filename(filen ame), revision_and_build)
75
76 def test_file_info_list_to_revision_to_build_list(self):
77 file_info_list = [
78 {"filename": "r47483 (1)/"},
79 {"filename": "r47483 (1).zip"},
80 {"filename": "random junk"},
81 ]
82 builds_and_revisions_list = [(47483, 1), (47483, 1)]
83 self.assertEqual(self.builder._file_info_list_to_revision_to_build_list( file_info_list), builds_and_revisions_list)
84
85 def test_fetch_build(self):
86 buildbot = BuildBot()
87 builder = Builder(u"Test Builder \u2661", buildbot)
88
89 def mock_fetch_build_dictionary(self, build_number):
90 build_dictionary = {
91 "sourceStamp": {
92 "revision": None, # revision=None means a trunk build start ed from the force-build button on the builder page.
93 },
94 "number": int(build_number),
95 # Intentionally missing the 'results' key, meaning it's a "pass" build.
96 }
97 return build_dictionary
98 buildbot._fetch_build_dictionary = mock_fetch_build_dictionary
99 self.assertIsNotNone(builder._fetch_build(1))
100
101 def test_results_url(self):
102 builder = BuildBot().builder_with_name('WebKit Mac10.8 (dbg)')
103 self.assertEqual(builder.results_url(),
104 'https://storage.googleapis.com/chromium-layout-test-ar chives/WebKit_Mac10_8__dbg_')
105
106 def test_accumulated_results_url(self):
107 builder = BuildBot().builder_with_name('WebKit Mac10.8 (dbg)')
108 self.assertEqual(builder.accumulated_results_url(),
109 'https://storage.googleapis.com/chromium-layout-test-ar chives/WebKit_Mac10_8__dbg_/results/layout-test-results')
110
111
112 class BuildBotTest(unittest.TestCase):
113
114 _example_one_box_status = '''
115 <table>
116 <tr>
117 <td class="box"><a href="builders/Windows%20Debug%20%28Tests%29">Windows Deb ug (Tests)</a></td>
118 <td align="center" class="LastBuild box success"><a href="builders/Windows %20Debug%20%28Tests%29/builds/3693">47380</a><br />build<br />successful</td>
119 <td align="center" class="Activity building">building<br />ETA in<br />~ 1 4 mins<br />at 13:40</td>
120 <tr>
121 <td class="box"><a href="builders/SnowLeopard%20Intel%20Release">SnowLeopard Intel Release</a></td>
122 <td class="LastBuild box" >no build</td>
123 <td align="center" class="Activity building">building<br />< 1 min</td>
124 <tr>
125 <td class="box"><a href="builders/Qt%20Linux%20Release">Qt Linux Release</a> </td>
126 <td align="center" class="LastBuild box failure"><a href="builders/Qt%20Li nux%20Release/builds/654">47383</a><br />failed<br />compile-webkit</td>
127 <td align="center" class="Activity idle">idle<br />3 pending</td>
128 <tr>
129 <td class="box"><a href="builders/Qt%20Windows%2032-bit%20Debug">Qt Windows 32-bit Debug</a></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>
131 <td align="center" class="Activity building">building<br />ETA in<br />~ 5 mins<br />at 08:25</td>
132 </table>
133 '''
134 _expected_example_one_box_parsings = [
135 {
136 'is_green': True,
137 'build_number': 3693,
138 'name': u'Windows Debug (Tests)',
139 'built_revision': 47380,
140 'activity': 'building',
141 'pending_builds': 0,
142 },
143 {
144 'is_green': False,
145 'build_number': None,
146 'name': u'SnowLeopard Intel Release',
147 'built_revision': None,
148 'activity': 'building',
149 'pending_builds': 0,
150 },
151 {
152 'is_green': False,
153 'build_number': 654,
154 'name': u'Qt Linux Release',
155 'built_revision': 47383,
156 'activity': 'idle',
157 'pending_builds': 3,
158 },
159 {
160 'is_green': True,
161 'build_number': 2090,
162 'name': u'Qt Windows 32-bit Debug',
163 'built_revision': 60563,
164 'activity': 'building',
165 'pending_builds': 0,
166 },
167 ]
168
169 def test_status_parsing(self):
170 buildbot = BuildBot()
171
172 soup = BeautifulSoup(self._example_one_box_status)
173 status_table = soup.find("table")
174 input_rows = status_table.findAll('tr')
175
176 for x in range(len(input_rows)):
177 status_row = input_rows[x]
178 expected_parsing = self._expected_example_one_box_parsings[x]
179
180 builder = buildbot._parse_builder_status_from_row(status_row)
181
182 # Make sure we aren't parsing more or less than we expect
183 self.assertEqual(builder.keys(), expected_parsing.keys())
184
185 for key, expected_value in expected_parsing.items():
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)))
188
189 def test_builder_with_name(self):
190 buildbot = BuildBot()
191
192 builder = buildbot.builder_with_name("Test Builder")
193 self.assertEqual(builder.name(), "Test Builder")
194 self.assertEqual(builder.url(), "http://build.chromium.org/p/chromium.we bkit/builders/Test%20Builder")
195 self.assertEqual(builder.url_encoded_name(), "Test%20Builder")
196 self.assertEqual(builder.results_url(), "https://storage.googleapis.com/ chromium-layout-test-archives/Test_Builder")
197
198 # Override _fetch_build_dictionary function to not touch the network.
199 def mock_fetch_build_dictionary(self, build_number):
200 build_dictionary = {
201 "sourceStamp": {
202 "revision": 2 * build_number,
203 },
204 "number": int(build_number),
205 "results": build_number % 2, # 0 means pass
206 }
207 return build_dictionary
208 buildbot._fetch_build_dictionary = mock_fetch_build_dictionary
209
210 build = builder.build(10)
211 self.assertEqual(build.builder(), builder)
212 self.assertEqual(build.url(), "http://build.chromium.org/p/chromium.webk it/builders/Test%20Builder/builds/10")
213 self.assertEqual(build.results_url(), "https://storage.googleapis.com/ch romium-layout-test-archives/Test_Builder/r20%20%2810%29")
214 self.assertEqual(build.revision(), 20)
215 self.assertTrue(build.is_green())
216
217 build = build.previous_build()
218 self.assertEqual(build.builder(), builder)
219 self.assertEqual(build.url(), "http://build.chromium.org/p/chromium.webk it/builders/Test%20Builder/builds/9")
220 self.assertEqual(build.results_url(), "https://storage.googleapis.com/ch romium-layout-test-archives/Test_Builder/r18%20%289%29")
221 self.assertEqual(build.revision(), 18)
222 self.assertFalse(build.is_green())
223
224 self.assertIsNone(builder.build(None))
225
226 _example_directory_listing = '''
227 <h1>Directory listing for /results/SnowLeopard Intel Leaks/</h1>
228
229 <table>
230 <tr class="alt">
231 <th>Filename</th>
232 <th>Size</th>
233 <th>Content type</th>
234 <th>Content encoding</th>
235 </tr>
236 <tr class="directory ">
237 <td><a href="r47483%20%281%29/"><b>r47483 (1)/</b></a></td>
238 <td><b></b></td>
239 <td><b>[Directory]</b></td>
240 <td><b></b></td>
241 </tr>
242 <tr class="file alt">
243 <td><a href="r47484%20%282%29.zip">r47484 (2).zip</a></td>
244 <td>89K</td>
245 <td>[application/zip]</td>
246 <td></td>
247 </tr>
248 '''
249 _expected_files = [
250 {
251 "filename": "r47483 (1)/",
252 "size": "",
253 "type": "[Directory]",
254 "encoding": "",
255 },
256 {
257 "filename": "r47484 (2).zip",
258 "size": "89K",
259 "type": "[application/zip]",
260 "encoding": "",
261 },
262 ]
263
264 def test_parse_build_to_revision_map(self):
265 buildbot = BuildBot()
266 files = buildbot._parse_twisted_directory_listing(self._example_director y_listing)
267 self.assertEqual(self._expected_files, files)
268
269 _fake_builder_page = '''
270 <body>
271 <div class="content">
272 <h1>Some Builder</h1>
273 <p>(<a href="../waterfall?show=Some Builder">view in waterfall</a>)</p>
274 <div class="column">
275 <h2>Recent Builds:</h2>
276 <table class="info">
277 <tr>
278 <th>Time</th>
279 <th>Revision</th>
280 <th>Result</th> <th>Build #</th>
281 <th>Info</th>
282 </tr>
283 <tr class="alt">
284 <td>Jan 10 15:49</td>
285 <td><span class="revision" title="Revision 104643"><a href="http://trac. webkit.org/changeset/104643">104643</a></span></td>
286 <td class="success">failure</td> <td><a href=".../37604">#37604</a></ td>
287 <td class="left">Build successful</td>
288 </tr>
289 <tr class="">
290 <td>Jan 10 15:32</td>
291 <td><span class="revision" title="Revision 104636"><a href="http://trac. webkit.org/changeset/104636">104636</a></span></td>
292 <td class="success">failure</td> <td><a href=".../37603">#37603</a></ td>
293 <td class="left">Build successful</td>
294 </tr>
295 <tr class="alt">
296 <td>Jan 10 15:18</td>
297 <td><span class="revision" title="Revision 104635"><a href="http://trac. webkit.org/changeset/104635">104635</a></span></td>
298 <td class="success">success</td> <td><a href=".../37602">#37602</a></ td>
299 <td class="left">Build successful</td>
300 </tr>
301 <tr class="">
302 <td>Jan 10 14:51</td>
303 <td><span class="revision" title="Revision 104633"><a href="http://trac. webkit.org/changeset/104633">104633</a></span></td>
304 <td class="failure">failure</td> <td><a href=".../37601">#37601</a></ td>
305 <td class="left">Failed compile-webkit</td>
306 </tr>
307 </table>
308 </body>'''
309 _fake_builder_page_without_success = '''
310 <body>
311 <table>
312 <tr class="alt">
313 <td>Jan 10 15:49</td>
314 <td><span class="revision" title="Revision 104643"><a href="http://trac. webkit.org/changeset/104643">104643</a></span></td>
315 <td class="success">failure</td>
316 </tr>
317 <tr class="">
318 <td>Jan 10 15:32</td>
319 <td><span class="revision" title="Revision 104636"><a href="http://trac. webkit.org/changeset/104636">104636</a></span></td>
320 <td class="success">failure</td>
321 </tr>
322 <tr class="alt">
323 <td>Jan 10 15:18</td>
324 <td><span class="revision" title="Revision 104635"><a href="http://trac. webkit.org/changeset/104635">104635</a></span></td>
325 <td class="success">failure</td>
326 </tr>
327 <tr class="">
328 <td>Jan 10 11:58</td>
329 <td><span class="revision" title="Revision ??"><a href="http://trac.we bkit.org/changeset/%3F%3F">??</a></span></td>
330 <td class="retry">retry</td>
331 </tr>
332 <tr class="">
333 <td>Jan 10 14:51</td>
334 <td><span class="revision" title="Revision 104633"><a href="http://trac. webkit.org/changeset/104633">104633</a></span></td>
335 <td class="failure">failure</td>
336 </tr>
337 </table>
338 </body>'''
339
340 def test_revisions_for_builder(self):
341 buildbot = BuildBot()
342 buildbot._fetch_builder_page = lambda builder: builder.page
343 builder_with_success = Builder('Some builder', None)
344 builder_with_success.page = self._fake_builder_page
345 self.assertEqual(buildbot._revisions_for_builder(builder_with_success), [
346 (104643, False), (104636, False), (104635, True), (1046 33, False)])
347
348 builder_without_success = Builder('Some builder', None)
349 builder_without_success.page = self._fake_builder_page_without_success
350 self.assertEqual(buildbot._revisions_for_builder(builder_without_success ), [
351 (104643, False), (104636, False), (104635, False), (104 633, False)])
352
353 def test_find_green_revision(self):
354 buildbot = BuildBot()
355 self.assertEqual(buildbot._find_green_revision({
356 'Builder 1': [(1, True), (3, True)],
357 'Builder 2': [(1, True), (3, False)],
358 'Builder 3': [(1, True), (3, True)],
359 }), 1)
360 self.assertEqual(buildbot._find_green_revision({
361 'Builder 1': [(1, False), (3, True)],
362 'Builder 2': [(1, True), (3, True)],
363 'Builder 3': [(1, True), (3, True)],
364 }), 3)
365 self.assertEqual(buildbot._find_green_revision({
366 'Builder 1': [(1, True), (2, True)],
367 'Builder 2': [(1, False), (2, True), (3, True)],
368 'Builder 3': [(1, True), (3, True)],
369 }), None)
370 self.assertEqual(buildbot._find_green_revision({
371 'Builder 1': [(1, True), (2, True)],
372 'Builder 2': [(1, True), (2, True), (3, True)],
373 'Builder 3': [(1, True), (3, True)],
374 }), 2)
375 self.assertEqual(buildbot._find_green_revision({
376 'Builder 1': [(1, False), (2, True)],
377 'Builder 2': [(1, True), (3, True)],
378 'Builder 3': [(1, True), (3, True)],
379 }), None)
380 self.assertEqual(buildbot._find_green_revision({
381 'Builder 1': [(1, True), (3, True)],
382 'Builder 2': [(1, False), (2, True), (3, True), (4, True)],
383 'Builder 3': [(2, True), (4, True)],
384 }), 3)
385 self.assertEqual(buildbot._find_green_revision({
386 'Builder 1': [(1, True), (3, True)],
387 'Builder 2': [(1, False), (2, True), (3, True), (4, False)],
388 'Builder 3': [(2, True), (4, True)],
389 }), None)
390 self.assertEqual(buildbot._find_green_revision({
391 'Builder 1': [(1, True), (3, True)],
392 'Builder 2': [(1, False), (2, True), (3, True), (4, False)],
393 'Builder 3': [(2, True), (3, True), (4, True)],
394 }), 3)
395 self.assertEqual(buildbot._find_green_revision({
396 'Builder 1': [(1, True), (2, True)],
397 'Builder 2': [],
398 'Builder 3': [(1, True), (2, True)],
399 }), None)
400 self.assertEqual(buildbot._find_green_revision({
401 'Builder 1': [(1, True), (3, False), (5, True), (10, True), (12, Fal se)],
402 'Builder 2': [(1, True), (3, False), (7, True), (9, True), (12, Fals e)],
403 'Builder 3': [(1, True), (3, True), (7, True), (11, False), (12, Tru e)],
404 }), 7)
405
406 def _fetch_build(self, build_number):
407 if build_number == 5:
408 return "correct build"
409 return "wrong build"
410
411 def _fetch_revision_to_build_map(self):
412 return {'r5': 5, 'r2': 2, 'r3': 3}
413
414 def test_latest_cached_build(self):
415 b = Builder('builder', BuildBot())
416 b._fetch_build = self._fetch_build
417 b._fetch_revision_to_build_map = self._fetch_revision_to_build_map
418 self.assertEqual("correct build", b.latest_cached_build())
419
420 def results_url(self):
421 return "some-url"
422
423 def test_results_zip_url(self):
424 b = Build(None, 123, 123, False)
425 b.results_url = self.results_url
426 self.assertEqual("some-url.zip", b.results_zip_url())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698