| 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 | |
| 6 | |
| 7 from base_handler import BaseHandler | 5 from base_handler import BaseHandler |
| 8 from base_handler import Permission | 6 from base_handler import Permission |
| 9 from model import wf_analysis_status | 7 from handlers import handlers_util |
| 10 from model.wf_analysis import WfAnalysis | |
| 11 from model.wf_swarming_task import WfSwarmingTask | |
| 12 from waterfall import buildbot | 8 from waterfall import buildbot |
| 13 from waterfall import waterfall_config | |
| 14 | 9 |
| 15 | 10 |
| 16 def _GenerateSwarmingTasksData(master_name, builder_name, build_number): | |
| 17 """Collects info for all related swarming tasks. | |
| 18 | |
| 19 Returns: A dict as below: | |
| 20 { | |
| 21 'step1': { | |
| 22 'swarming_tasks': [ | |
| 23 { | |
| 24 'status': 'Completed', | |
| 25 'task_id': 'task1', | |
| 26 'task_url': ( | |
| 27 'https://chromium-swarm.appspot.com/user/task/task1') | |
| 28 }, | |
| 29 { | |
| 30 'status': 'Completed', | |
| 31 'task_id': 'task0', | |
| 32 'task_url': ( | |
| 33 'https://chromium-swarm.appspot.com/user/task/task0') | |
| 34 } | |
| 35 ], | |
| 36 'tests': { | |
| 37 'test1': { | |
| 38 'status': 'Completed', | |
| 39 'task_id': 'task0', | |
| 40 'task_url': ( | |
| 41 'https://chromium-swarm.appspot.com/user/task/task0') | |
| 42 }, | |
| 43 'test2': { | |
| 44 'status': 'Completed', | |
| 45 'task_id': 'task1', | |
| 46 'task_url': ( | |
| 47 'https://chromium-swarm.appspot.com/user/task/task1') | |
| 48 } | |
| 49 } | |
| 50 }, | |
| 51 'step2': { | |
| 52 'swarming_tasks': [ | |
| 53 { | |
| 54 'status': 'Pending' | |
| 55 } | |
| 56 ], | |
| 57 'tests': { | |
| 58 'test1': { | |
| 59 'status': 'Pending' | |
| 60 } | |
| 61 } | |
| 62 } | |
| 63 } | |
| 64 """ | |
| 65 tasks_info = defaultdict(dict) | |
| 66 | |
| 67 analysis = WfAnalysis.Get(master_name, builder_name, build_number) | |
| 68 if not analysis: | |
| 69 return tasks_info | |
| 70 | |
| 71 failure_result_map = analysis.failure_result_map | |
| 72 if failure_result_map: | |
| 73 for step_name, failure in failure_result_map.iteritems(): | |
| 74 if isinstance(failure, dict): | |
| 75 # Only trigger swarming task for swarming test failures. | |
| 76 key_test_map = defaultdict(list) | |
| 77 for test_name, first_failure_key in failure.iteritems(): | |
| 78 key_test_map[first_failure_key].append(test_name) | |
| 79 | |
| 80 tasks_info[step_name]['swarming_tasks'] = [] | |
| 81 tasks_info[step_name]['tests'] = defaultdict(dict) | |
| 82 step_tasks_info = tasks_info[step_name]['swarming_tasks'] | |
| 83 tests = tasks_info[step_name]['tests'] | |
| 84 for key in key_test_map: | |
| 85 referred_build_keys = key.split('/') | |
| 86 task = WfSwarmingTask.Get(*referred_build_keys, step_name=step_name) | |
| 87 if not task: | |
| 88 continue | |
| 89 task_info = { | |
| 90 'status': wf_analysis_status.SWARMING_STATUS_TO_DESCRIPTION.get( | |
| 91 task.status) | |
| 92 } | |
| 93 if task.task_id: | |
| 94 task_info['task_id'] = task.task_id | |
| 95 task_info['task_url'] = 'https://%s/user/task/%s' % ( | |
| 96 waterfall_config.GetSwarmingSettings()['server_host'], | |
| 97 task.task_id) | |
| 98 | |
| 99 step_tasks_info.append(task_info) | |
| 100 for test_name in key_test_map[key]: | |
| 101 tests[test_name] = task_info | |
| 102 | |
| 103 return tasks_info | |
| 104 | |
| 105 class SwarmingTask(BaseHandler): | 11 class SwarmingTask(BaseHandler): |
| 106 PERMISSION_LEVEL = Permission.ANYONE | 12 PERMISSION_LEVEL = Permission.ANYONE |
| 107 | 13 |
| 108 def HandleGet(self): | 14 def HandleGet(self): |
| 109 """Get the information about swarming tasks for failed steps.""" | 15 """Get the information about swarming tasks for failed steps.""" |
| 110 url = self.request.get('url').strip() | 16 url = self.request.get('url').strip() |
| 111 build_keys = buildbot.ParseBuildUrl(url) | 17 build_keys = buildbot.ParseBuildUrl(url) |
| 112 | 18 |
| 113 if not build_keys: # pragma: no cover | 19 if not build_keys: # pragma: no cover |
| 114 return {'data': {}} | 20 return {'data': {}} |
| 115 | 21 |
| 116 data = _GenerateSwarmingTasksData(*build_keys) | 22 data = handlers_util.GenerateSwarmingTasksData(*build_keys) |
| 117 return {'data': data} | 23 return {'data': data} |
| 118 | 24 |
| 119 def HandlePost(self): # pragma: no cover | 25 def HandlePost(self): # pragma: no cover |
| 120 return self.HandleGet() | 26 return self.HandleGet() |
| OLD | NEW |