| OLD | NEW |
| 1 # Copyright 2015 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 import webapp2 | |
| 6 | |
| 7 from testing_utils import testing | 5 from testing_utils import testing |
| 8 | 6 |
| 9 from handlers import try_job_result | 7 from handlers import handlers_util |
| 10 from model.wf_analysis import WfAnalysis | 8 from model.wf_analysis import WfAnalysis |
| 11 from model import wf_analysis_status | 9 from model import wf_analysis_status |
| 12 from model.wf_swarming_task import WfSwarmingTask | 10 from model.wf_swarming_task import WfSwarmingTask |
| 13 from model.wf_try_job import WfTryJob | 11 from model.wf_try_job import WfTryJob |
| 14 from waterfall import buildbot | 12 from waterfall import buildbot |
| 13 from waterfall import waterfall_config |
| 15 | 14 |
| 16 | 15 |
| 17 class TryJobResultTest(testing.AppengineTestCase): | 16 class HandlersUtilResultTest(testing.AppengineTestCase): |
| 18 app_module = webapp2.WSGIApplication([ | |
| 19 ('/try-job-result', try_job_result.TryJobResult),], debug=True) | |
| 20 | 17 |
| 21 def setUp(self): | 18 def setUp(self): |
| 22 super(TryJobResultTest, self).setUp() | 19 super(HandlersUtilResultTest, self).setUp() |
| 23 self.master_name = 'm' | 20 self.master_name = 'm' |
| 24 self.builder_name = 'b' | 21 self.builder_name = 'b' |
| 25 self.build_number = 121 | 22 self.build_number = 121 |
| 26 self.mock_current_user(user_email='test@chromium.org', is_admin=True) | 23 |
| 24 def MockedGetSwarmingSettings(): |
| 25 return {'server_host': 'chromium-swarm.appspot.com'} |
| 26 self.mock( |
| 27 waterfall_config, 'GetSwarmingSettings', MockedGetSwarmingSettings) |
| 28 |
| 29 def testGenerateSwarmingTasksDataNoAnalysis(self): |
| 30 data = handlers_util.GenerateSwarmingTasksData( |
| 31 self.master_name, self.builder_name, self.build_number) |
| 32 |
| 33 self.assertEqual({}, data) |
| 34 |
| 35 def testGenerateSwarmingTasksDataReturnEmptyIfNoFailureMap(self): |
| 36 WfAnalysis.Create( |
| 37 self.master_name, self.builder_name, self.build_number).put() |
| 38 |
| 39 data = handlers_util.GenerateSwarmingTasksData( |
| 40 self.master_name, self.builder_name, self.build_number) |
| 41 |
| 42 self.assertEqual({}, data) |
| 43 |
| 44 def testGenerateSwarmingTasksDataReturnEmptyIfNoSwarmingTests(self): |
| 45 analysis = WfAnalysis.Create( |
| 46 self.master_name, self.builder_name, self.build_number) |
| 47 analysis.failure_result_map = { |
| 48 'step1': '%s/%s/%s' % (self.master_name, self.builder_name, 120), |
| 49 'step2': '%s/%s/%s' % ( |
| 50 self.master_name, self.builder_name, self.build_number) |
| 51 } |
| 52 analysis.put() |
| 53 |
| 54 data = handlers_util.GenerateSwarmingTasksData( |
| 55 self.master_name, self.builder_name, self.build_number) |
| 56 |
| 57 self.assertEqual({}, data) |
| 58 |
| 59 def testGenerateSwarmingTasksDataIfNoSwarmingTask(self): |
| 60 analysis = WfAnalysis.Create( |
| 61 self.master_name, self.builder_name, self.build_number) |
| 62 analysis.failure_result_map = { |
| 63 'step1': { |
| 64 'test1': '%s/%s/%s' % (self.master_name, self.builder_name, 120), |
| 65 'test2': '%s/%s/%s' % ( |
| 66 self.master_name, self.builder_name, self.build_number) |
| 67 }, |
| 68 'step2': { |
| 69 'test1': '%s/%s/%s' % (self.master_name, self.builder_name, 120) |
| 70 } |
| 71 } |
| 72 analysis.put() |
| 73 |
| 74 data = handlers_util.GenerateSwarmingTasksData( |
| 75 self.master_name, self.builder_name, self.build_number) |
| 76 |
| 77 expected_data = { |
| 78 'step1': { |
| 79 'swarming_tasks': [], |
| 80 'tests': {} |
| 81 }, |
| 82 'step2': { |
| 83 'swarming_tasks': [], |
| 84 'tests': {} |
| 85 } |
| 86 } |
| 87 self.assertEqual(expected_data, data) |
| 88 |
| 89 def testGenerateSwarmingTasksData(self): |
| 90 analysis = WfAnalysis.Create( |
| 91 self.master_name, self.builder_name, self.build_number) |
| 92 analysis.failure_result_map = { |
| 93 'step1': { |
| 94 'test1': '%s/%s/%s' % (self.master_name, self.builder_name, 120), |
| 95 'test2': '%s/%s/%s' % ( |
| 96 self.master_name, self.builder_name, self.build_number) |
| 97 }, |
| 98 'step2': { |
| 99 'test1': '%s/%s/%s' % ( |
| 100 self.master_name, self.builder_name, self.build_number) |
| 101 } |
| 102 } |
| 103 analysis.put() |
| 104 |
| 105 task0 = WfSwarmingTask.Create( |
| 106 self.master_name, self.builder_name, 120, 'step1') |
| 107 task0.task_id = 'task0' |
| 108 task0.status = wf_analysis_status.ANALYZED |
| 109 task0.put() |
| 110 |
| 111 task1 = WfSwarmingTask.Create( |
| 112 self.master_name, self.builder_name, self.build_number, 'step1') |
| 113 task1.task_id = 'task1' |
| 114 task1.status = wf_analysis_status.ANALYZED |
| 115 task1.put() |
| 116 |
| 117 task2 = WfSwarmingTask.Create( |
| 118 self.master_name, self.builder_name, self.build_number, 'step2') |
| 119 task2.put() |
| 120 |
| 121 data = handlers_util.GenerateSwarmingTasksData( |
| 122 self.master_name, self.builder_name, self.build_number) |
| 123 |
| 124 expected_data = { |
| 125 'step1': { |
| 126 'swarming_tasks': [ |
| 127 { |
| 128 'status': 'Completed', |
| 129 'task_id': 'task1', |
| 130 'task_url': ( |
| 131 'https://chromium-swarm.appspot.com/user/task/task1') |
| 132 }, |
| 133 { |
| 134 'status': 'Completed', |
| 135 'task_id': 'task0', |
| 136 'task_url': ( |
| 137 'https://chromium-swarm.appspot.com/user/task/task0') |
| 138 } |
| 139 ], |
| 140 'tests': { |
| 141 'test1': { |
| 142 'status': 'Completed', |
| 143 'task_id': 'task0', |
| 144 'task_url': ( |
| 145 'https://chromium-swarm.appspot.com/user/task/task0') |
| 146 }, |
| 147 'test2': { |
| 148 'status': 'Completed', |
| 149 'task_id': 'task1', |
| 150 'task_url': ( |
| 151 'https://chromium-swarm.appspot.com/user/task/task1') |
| 152 } |
| 153 } |
| 154 }, |
| 155 'step2': { |
| 156 'swarming_tasks': [ |
| 157 { |
| 158 'status': 'Pending' |
| 159 } |
| 160 ], |
| 161 'tests': { |
| 162 'test1': { |
| 163 'status': 'Pending' |
| 164 } |
| 165 } |
| 166 } |
| 167 } |
| 168 self.assertEqual(expected_data, data) |
| 169 |
| 170 def testGetAllTryJobResultsNoAnalysis(self): |
| 171 data = handlers_util.GetAllTryJobResults( |
| 172 self.master_name, self.builder_name, self.build_number) |
| 173 |
| 174 self.assertEqual({}, data) |
| 27 | 175 |
| 28 def testGetTryJobResultReturnNoneIfNoFailureResultMap(self): | 176 def testGetTryJobResultReturnNoneIfNoFailureResultMap(self): |
| 29 analysis = WfAnalysis.Create( | 177 analysis = WfAnalysis.Create( |
| 30 self.master_name, self.builder_name, self.build_number) | 178 self.master_name, self.builder_name, self.build_number) |
| 31 analysis.put() | 179 analysis.put() |
| 32 | 180 |
| 33 result = try_job_result._GetAllTryJobResults( | 181 result = handlers_util.GetAllTryJobResults( |
| 34 self.master_name, self.builder_name, self.build_number) | 182 self.master_name, self.builder_name, self.build_number) |
| 35 | 183 |
| 36 self.assertEqual({}, result) | 184 self.assertEqual({}, result) |
| 37 | 185 |
| 38 def testGetTryJobResultReturnNoneIfNoTryJob(self): | 186 def testGetTryJobResultReturnNoneIfNoTryJob(self): |
| 39 analysis = WfAnalysis.Create( | 187 analysis = WfAnalysis.Create( |
| 40 self.master_name, self.builder_name, self.build_number) | 188 self.master_name, self.builder_name, self.build_number) |
| 41 analysis.failure_result_map = { | 189 analysis.failure_result_map = { |
| 42 'compile': 'm/b/121' | 190 'compile': 'm/b/121' |
| 43 } | 191 } |
| 44 analysis.put() | 192 analysis.put() |
| 45 | 193 |
| 46 result = try_job_result._GetAllTryJobResults( | 194 result = handlers_util.GetAllTryJobResults( |
| 47 self.master_name, self.builder_name, self.build_number) | 195 self.master_name, self.builder_name, self.build_number) |
| 48 | 196 |
| 49 expected_result = { | 197 expected_result = { |
| 50 'compile': { | 198 'compile': { |
| 51 'step': 'compile', | 199 'step': 'compile', |
| 52 'test': 'N/A', | 200 'test': 'N/A', |
| 53 'try_job_key': 'm/b/121' | 201 'try_job_key': 'm/b/121' |
| 54 } | 202 } |
| 55 } | 203 } |
| 56 | 204 |
| 57 self.assertEqual(expected_result, result) | 205 self.assertEqual(expected_result, result) |
| 58 | 206 |
| 59 def testGetTryJobResultOnlyReturnStatusIfPending(self): | 207 def testGetTryJobResultOnlyReturnStatusIfPending(self): |
| 60 analysis = WfAnalysis.Create( | 208 analysis = WfAnalysis.Create( |
| 61 self.master_name, self.builder_name, self.build_number) | 209 self.master_name, self.builder_name, self.build_number) |
| 62 analysis.failure_result_map = { | 210 analysis.failure_result_map = { |
| 63 'compile': 'm/b/121' | 211 'compile': 'm/b/121' |
| 64 } | 212 } |
| 65 analysis.put() | 213 analysis.put() |
| 66 | 214 |
| 67 try_job = WfTryJob.Create( | 215 try_job = WfTryJob.Create( |
| 68 self.master_name, self.builder_name, self.build_number) | 216 self.master_name, self.builder_name, self.build_number) |
| 69 try_job.put() | 217 try_job.put() |
| 70 | 218 |
| 71 result = try_job_result._GetAllTryJobResults( | 219 result = handlers_util.GetAllTryJobResults( |
| 72 self.master_name, self.builder_name, self.build_number) | 220 self.master_name, self.builder_name, self.build_number) |
| 73 | 221 |
| 74 expected_result = { | 222 expected_result = { |
| 75 'compile': { | 223 'compile': { |
| 76 'step': 'compile', | 224 'step': 'compile', |
| 77 'test': 'N/A', | 225 'test': 'N/A', |
| 78 'try_job_key': 'm/b/121', | 226 'try_job_key': 'm/b/121', |
| 79 'status': 'Pending' | 227 'status': 'Pending' |
| 80 } | 228 } |
| 81 } | 229 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 95 try_job.status = wf_analysis_status.ANALYZING | 243 try_job.status = wf_analysis_status.ANALYZING |
| 96 try_job.compile_results = [ | 244 try_job.compile_results = [ |
| 97 { | 245 { |
| 98 'result': None, | 246 'result': None, |
| 99 'url': ('http://build.chromium.org/p/tryserver.chromium.linux/' | 247 'url': ('http://build.chromium.org/p/tryserver.chromium.linux/' |
| 100 'builders/linux_chromium_variable/builds/121') | 248 'builders/linux_chromium_variable/builds/121') |
| 101 } | 249 } |
| 102 ] | 250 ] |
| 103 try_job.put() | 251 try_job.put() |
| 104 | 252 |
| 105 result = try_job_result._GetAllTryJobResults( | 253 result = handlers_util.GetAllTryJobResults( |
| 106 self.master_name, self.builder_name, self.build_number) | 254 self.master_name, self.builder_name, self.build_number) |
| 107 | 255 |
| 108 expected_result = { | 256 expected_result = { |
| 109 'compile': { | 257 'compile': { |
| 110 'step': 'compile', | 258 'step': 'compile', |
| 111 'test': 'N/A', | 259 'test': 'N/A', |
| 112 'try_job_key': 'm/b/121', | 260 'try_job_key': 'm/b/121', |
| 113 'status': 'Running', | 261 'status': 'Running', |
| 114 'try_job_build_number': 121, | 262 'try_job_build_number': 121, |
| 115 'try_job_url': ('http://build.chromium.org/p/tryserver.chromium.' | 263 'try_job_url': ('http://build.chromium.org/p/tryserver.chromium.' |
| (...skipping 13 matching lines...) Expand all Loading... |
| 129 try_job = WfTryJob.Create( | 277 try_job = WfTryJob.Create( |
| 130 self.master_name, self.builder_name, self.build_number) | 278 self.master_name, self.builder_name, self.build_number) |
| 131 try_job.status = wf_analysis_status.ERROR | 279 try_job.status = wf_analysis_status.ERROR |
| 132 try_job.compile_results = [ | 280 try_job.compile_results = [ |
| 133 { | 281 { |
| 134 'try_job_id': '1' | 282 'try_job_id': '1' |
| 135 } | 283 } |
| 136 ] | 284 ] |
| 137 try_job.put() | 285 try_job.put() |
| 138 | 286 |
| 139 result = try_job_result._GetAllTryJobResults( | 287 result = handlers_util.GetAllTryJobResults( |
| 140 self.master_name, self.builder_name, self.build_number) | 288 self.master_name, self.builder_name, self.build_number) |
| 141 | 289 |
| 142 expected_result = { | 290 expected_result = { |
| 143 'compile': { | 291 'compile': { |
| 144 'step': 'compile', | 292 'step': 'compile', |
| 145 'test': 'N/A', | 293 'test': 'N/A', |
| 146 'try_job_key': 'm/b/121', | 294 'try_job_key': 'm/b/121', |
| 147 'status': 'Error' | 295 'status': 'Error' |
| 148 } | 296 } |
| 149 } | 297 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 174 'compile': { | 322 'compile': { |
| 175 'revision': 'rev2', | 323 'revision': 'rev2', |
| 176 'commit_position': '2', | 324 'commit_position': '2', |
| 177 'review_url': 'url_2' | 325 'review_url': 'url_2' |
| 178 } | 326 } |
| 179 } | 327 } |
| 180 } | 328 } |
| 181 ] | 329 ] |
| 182 try_job.put() | 330 try_job.put() |
| 183 | 331 |
| 184 result = try_job_result._GetAllTryJobResults( | 332 result = handlers_util.GetAllTryJobResults( |
| 185 self.master_name, self.builder_name, self.build_number) | 333 self.master_name, self.builder_name, self.build_number) |
| 186 | 334 |
| 187 expected_result = { | 335 expected_result = { |
| 188 'compile': { | 336 'compile': { |
| 189 'step': 'compile', | 337 'step': 'compile', |
| 190 'test': 'N/A', | 338 'test': 'N/A', |
| 191 'try_job_key': 'm/b/121', | 339 'try_job_key': 'm/b/121', |
| 192 'try_job_build_number': 121, | 340 'try_job_build_number': 121, |
| 193 'status': 'Completed', | 341 'status': 'Completed', |
| 194 'try_job_url': ( | 342 'try_job_url': ( |
| (...skipping 23 matching lines...) Expand all Loading... |
| 218 'result': [ | 366 'result': [ |
| 219 ['rev1', 'passed'], | 367 ['rev1', 'passed'], |
| 220 ['rev2', 'passed'] | 368 ['rev2', 'passed'] |
| 221 ], | 369 ], |
| 222 'url': ('http://build.chromium.org/p/tryserver.chromium.linux/' | 370 'url': ('http://build.chromium.org/p/tryserver.chromium.linux/' |
| 223 'builders/linux_chromium_variable/builds/121') | 371 'builders/linux_chromium_variable/builds/121') |
| 224 } | 372 } |
| 225 ] | 373 ] |
| 226 try_job.put() | 374 try_job.put() |
| 227 | 375 |
| 228 result = try_job_result._GetAllTryJobResults( | 376 result = handlers_util.GetAllTryJobResults( |
| 229 self.master_name, self.builder_name, self.build_number) | 377 self.master_name, self.builder_name, self.build_number) |
| 230 | 378 |
| 231 expected_result = { | 379 expected_result = { |
| 232 'compile': { | 380 'compile': { |
| 233 'step': 'compile', | 381 'step': 'compile', |
| 234 'test': 'N/A', | 382 'test': 'N/A', |
| 235 'try_job_key': 'm/b/121', | 383 'try_job_key': 'm/b/121', |
| 236 'try_job_build_number': 121, | 384 'try_job_build_number': 121, |
| 237 'status': 'Completed', | 385 'status': 'Completed', |
| 238 'try_job_url': ( | 386 'try_job_url': ( |
| 239 'http://build.chromium.org/p/tryserver.chromium.linux/' | 387 'http://build.chromium.org/p/tryserver.chromium.linux/' |
| 240 'builders/linux_chromium_variable/builds/121') | 388 'builders/linux_chromium_variable/builds/121') |
| 241 } | 389 } |
| 242 } | 390 } |
| 243 | 391 |
| 244 self.assertEqual(expected_result, result) | 392 self.assertEqual(expected_result, result) |
| 245 | 393 |
| 246 def testTryJobResultHandler(self): | |
| 247 build_url = buildbot.CreateBuildUrl( | |
| 248 self.master_name, self.builder_name, self.build_number) | |
| 249 response = self.test_app.get('/try-job-result', params={'url': build_url}) | |
| 250 expected_results = {} | |
| 251 | |
| 252 self.assertEqual(200, response.status_int) | |
| 253 self.assertEqual(expected_results, response.json_body) | |
| 254 | |
| 255 def testGetTryJobResultWhenTryJobForTestCompleted(self): | 394 def testGetTryJobResultWhenTryJobForTestCompleted(self): |
| 256 analysis = WfAnalysis.Create( | 395 analysis = WfAnalysis.Create( |
| 257 self.master_name, self.builder_name, self.build_number) | 396 self.master_name, self.builder_name, self.build_number) |
| 258 analysis.failure_result_map = { | 397 analysis.failure_result_map = { |
| 259 'a_test': { | 398 'a_test': { |
| 260 'a_test1': 'm/b/121', | 399 'a_test1': 'm/b/121', |
| 261 'a_test2': 'm/b/121', | 400 'a_test2': 'm/b/121', |
| 262 'a_test3': 'm/b/120', | 401 'a_test3': 'm/b/120', |
| 263 'a_test4': 'm/b/121' | 402 'a_test4': 'm/b/121' |
| 264 }, | 403 }, |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 } | 547 } |
| 409 } | 548 } |
| 410 }, | 549 }, |
| 411 'url': ('http://build.chromium.org/p/tryserver.chromium.linux/' | 550 'url': ('http://build.chromium.org/p/tryserver.chromium.linux/' |
| 412 'builders/linux_chromium_variable/builds/122'), | 551 'builders/linux_chromium_variable/builds/122'), |
| 413 'try_job_id': '2' | 552 'try_job_id': '2' |
| 414 } | 553 } |
| 415 ] | 554 ] |
| 416 try_job_122.put() | 555 try_job_122.put() |
| 417 | 556 |
| 418 result = try_job_result._GetAllTryJobResults( | 557 result = handlers_util.GetAllTryJobResults( |
| 419 self.master_name, self.builder_name, self.build_number) | 558 self.master_name, self.builder_name, self.build_number) |
| 420 | 559 |
| 421 expected_result = { | 560 expected_result = { |
| 422 'a_test-a_test1': { | 561 'a_test-a_test1': { |
| 423 'step': 'a_test', | 562 'step': 'a_test', |
| 424 'test': 'a_test1', | 563 'test': 'a_test1', |
| 425 'try_job_key': 'm/b/121', | 564 'try_job_key': 'm/b/121', |
| 426 'try_job_build_number': 121, | 565 'try_job_build_number': 121, |
| 427 'status': 'Completed', | 566 'status': 'Completed', |
| 428 'try_job_url': ( | 567 'try_job_url': ( |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 'test': 'N/A', | 624 'test': 'N/A', |
| 486 'try_job_key': 'm/b/122', | 625 'try_job_key': 'm/b/122', |
| 487 'try_job_build_number': 122, | 626 'try_job_build_number': 122, |
| 488 'status': 'Completed', | 627 'status': 'Completed', |
| 489 'try_job_url': ( | 628 'try_job_url': ( |
| 490 'http://build.chromium.org/p/tryserver.chromium.linux/' | 629 'http://build.chromium.org/p/tryserver.chromium.linux/' |
| 491 'builders/linux_chromium_variable/builds/122') | 630 'builders/linux_chromium_variable/builds/122') |
| 492 } | 631 } |
| 493 } | 632 } |
| 494 self.assertEqual(expected_result, result) | 633 self.assertEqual(expected_result, result) |
| 634 |
| 635 def testUpdateFlakinessNoTask(self): |
| 636 step_name = 's' |
| 637 failure_key_set = ['m/b/1'] |
| 638 culprits_info = None |
| 639 handlers_util._UpdateFlakiness(step_name, failure_key_set, culprits_info) |
| 640 self.assertIsNone(culprits_info) |
| 641 |
| 642 def testGetCulpritInfoForTryJobResultStep(self): |
| 643 try_job_key = 'm/b/120' |
| 644 culprits_info = { |
| 645 'a_test': { |
| 646 'step': 'a_test', |
| 647 'test': 'N/A', |
| 648 'try_job_key': try_job_key |
| 649 } |
| 650 } |
| 651 |
| 652 try_job_120 = WfTryJob.Create( |
| 653 self.master_name, self.builder_name, 120) |
| 654 try_job_120.status = wf_analysis_status.ANALYZED |
| 655 try_job_120.test_results = [ |
| 656 { |
| 657 'result': { |
| 658 'rev0': { |
| 659 'a_test': { |
| 660 'status': 'failed', |
| 661 'valid': True, |
| 662 'failures': ['a_test3'] |
| 663 } |
| 664 } |
| 665 }, |
| 666 'url': ('http://build.chromium.org/p/tryserver.chromium.linux/' |
| 667 'builders/linux_chromium_variable/builds/120'), |
| 668 'try_job_id': '0', |
| 669 'culprit': { |
| 670 'a_test': { |
| 671 'tests': { |
| 672 'a_test3': { |
| 673 'revision': 'rev0', |
| 674 'commit_position': '0', |
| 675 'review_url': 'url_0' |
| 676 } |
| 677 } |
| 678 } |
| 679 } |
| 680 } |
| 681 ] |
| 682 try_job_120.put() |
| 683 |
| 684 handlers_util._GetCulpritInfoForTryJobResult(try_job_key, culprits_info) |
| 685 |
| 686 expected_culprits_info = { |
| 687 'a_test-a_test3': { |
| 688 'step': 'a_test', |
| 689 'test': 'a_test3', |
| 690 'try_job_key': 'm/b/120', |
| 691 'try_job_build_number': 120, |
| 692 'status': 'Completed', |
| 693 'try_job_url': ( |
| 694 'http://build.chromium.org/p/tryserver.chromium.linux/' |
| 695 'builders/linux_chromium_variable/builds/120'), |
| 696 'revision': 'rev0', |
| 697 'commit_position': '0', |
| 698 'review_url': 'url_0' |
| 699 } |
| 700 } |
| 701 |
| 702 self.assertEqual(expected_culprits_info, culprits_info) |
| OLD | NEW |