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

Side by Side Diff: appengine/findit/waterfall/flake/step_mapper.py

Issue 2394013002: [Findit] Hacky solution to map a CQ trybot step to a Waterfall buildbot step. (Closed)
Patch Set: fix nit. Created 4 years, 2 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 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import json
6 import os
7
8 import collections
9 import logging
10
11 from common import cache_decorator
12 from common.http_client_appengine import HttpClientAppEngine as HttpClient
13 from waterfall import buildbot
14 from waterfall import swarming_util
15 from waterfall.flake import trybots
16
17
18 @cache_decorator.Cached(
19 namespace='trybots', cacher=cache_decorator.CompressedMemCacher())
20 def _LoadTrybots(): # pragma: no cover.
21 """Returns the mapping of Commit Queue trybots to Waterfall buildbots."""
22 with open(os.path.join(os.path.dirname(__file__), 'trybots.json'), 'r') as f:
23 return json.load(f)
24
25
26 def _GetMatchingBuildbots(cq_master_name, cq_builder_name): # pragma: no cover.
27 """Returns a list of matching builder/tester buildbots on Waterfall."""
28 trybot_map = _LoadTrybots()
29 builders = trybot_map.get(cq_master_name, {}).get('builders', {})
30 return builders.get(cq_builder_name, {}).get('bot_ids', [])
31
32
33 def _GetMatchingWaterfallBuildStep(
34 cq_build_step, http_client): # pragma: no cover.
35 """Returns the matching Waterfall build step of the given CQ one.
36
37 Args:
38 cq_build_step (BuildStep): A build step on Commit Queue.
39 http_client (RetryHttpClient): A http client to send http requests.
40
41 Returns:
42 (master_name, builder_name, build_number, step_name)
43 or
44 None
45 """
46 no_matching_result = (None, None, None, None)
47
48 def GetTagValue(tag_name, tags):
49 """Returns the value of a tag in a Swarming task."""
50 tag_name_prefix = '%s:' % tag_name
51 for tag in tags:
52 if tag.startswith(tag_name_prefix):
53 return tag[len(tag_name_prefix):]
54 return None
55
56 # 1. Map a cq trybot to the matching waterfall buildbots.
57 buildbots = _GetMatchingBuildbots(
58 cq_build_step.master_name, cq_build_step.builder_name)
59 if not buildbots:
60 logging.info('%s/%s has no matching Waterfall buildbot',
61 cq_build_step.master_name, cq_build_step.builder_name)
62 return no_matching_result # No matching Waterfall buildbots.
63
64 # 2. Get "name" of the CQ trybot step in the tags of a Swarming task.
65 tasks = swarming_util.ListSwarmingTasksDataByTags(
66 cq_build_step.master_name, cq_build_step.builder_name,
67 cq_build_step.build_number, http_client,
68 {'stepname': cq_build_step.step_name})
69 if not tasks:
70 logging.info(
71 '%s/%s/%s is not Swarmed yet.',
72 cq_build_step.master_name, cq_build_step.builder_name,
73 cq_build_step.build_step)
74 return no_matching_result # Not on Swarm yet.
75
76 # Name of the step in the tags of a Swarming task.
77 # Can't use step name, as cq one is with "(with patch)" while waterfall one
78 # without.
79 name = GetTagValue('name', tasks[0].get('tags', []))
80 if not name:
81 logging.error(
82 'Swarming task has no name tag: %s' % tasks[0].get('task_id'))
83 return no_matching_result # No name of the step.
84
85 for bot in buildbots:
86 wf_master_name = bot['mastername']
87 # Assume Swarmed gtests run on tester bot instead of the builder bot.
88 wf_builder_name = bot.get('tester') or bot.get('buildername')
89 # TODO: cache and throttle QPS to the same master.
90 # 3. Retrieve latest completed build cycle on the buildbot.
91 builds = buildbot.GetRecentCompletedBuilds(
92 wf_master_name, wf_builder_name, http_client)
93 if not builds:
94 logging.error('Failed to retrieve recent builds on %s', wf_master_name)
chanli 2016/10/07 01:08:37 There is logging at GetRecentCompletedBuilds side
stgao 2016/10/07 01:19:33 Good catch. Removed here.
95 return # No recent builds for the buildbot.
chanli 2016/10/07 01:04:52 return no_matching_result? Or maybe just continue
stgao 2016/10/07 01:19:33 Good catch! Let's continue with next configuration
96
97 # 4. Check whether there is matching step.
chanli 2016/10/07 01:04:52 I think we should. If a test is os specifically fl
stgao 2016/10/07 01:19:33 Done.
98 # TODO: we might have to check OS or dimension too.
99 tasks = swarming_util.ListSwarmingTasksDataByTags(
100 wf_master_name, wf_builder_name, builds[0], http_client, {'name': name})
101 if tasks: # One matching buildbot is found.
102 wf_step_name = GetTagValue('stepname', tasks[0].get('tags', []))
103 return wf_master_name, wf_builder_name, builds[0], wf_step_name
104
105 return no_matching_result
106
107
108 def FindMatchingWaterfallStep(build_step): # pragma: no cover.
chanli 2016/10/07 01:04:52 Is there any return value for this function? Or do
stgao 2016/10/07 01:19:33 No return value. Information will be updated direc
109 """Finds the matching Waterfall step and checks whether it is supported.
110
111 Only Swarmed and gtest-based steps are supported at the moment.
112
113 Args:
114 build_step (BuildStep): A build step on Waterfall or Commit Queue. It
115 will be updated with the matching Waterfall step and whether it is
116 Swarmed and supported.
117 """
118 # TODO (chanli): re-implement this hack after step metadata is added.
119
120 build_step.swarmed = False
121 build_step.supported = False
122
123 wf_master_name = None
124 wf_builder_name = None
125 wf_build_number = None
126 wf_step_name = None
127
128 http_client = HttpClient()
129
130 if not build_step.master_name.startswith('tryserver.'):
131 wf_master_name = build_step.master_name
132 wf_builder_name = build_step.builder_name
133 wf_build_number = build_step.build_number
134 wf_step_name = build_step.step_name
135 else:
136 step_info = _GetMatchingWaterfallBuildStep(build_step, http_client)
137 wf_master_name, wf_builder_name, wf_build_number, wf_step_name = step_info
138
139 build_step.wf_master_name = wf_master_name
140 build_step.wf_builder_name = wf_builder_name
141 build_step.wf_build_number = wf_build_number
142 build_step.wf_step_name = wf_step_name
143
144 if not build_step.has_matching_waterfall_step:
145 return
146
147 # Query Swarming for isolated data.
148 step_isolated_data = swarming_util.GetIsolatedDataForStep(
149 build_step.master_name, build_step.builder_name, build_step.build_number,
150 build_step.step_name, http_client)
151 build_step.swarmed = len(step_isolated_data) > 0
152
153 if build_step.swarmed:
154 # Retrieve a sample output from Isolate.
155 output = swarming_util.RetrieveShardedTestResultsFromIsolatedServer(
156 step_isolated_data[:1], http_client)
157 if output:
158 # Guess from the format.
159 build_step.supported = (
160 isinstance(output, dict) and
161 isinstance(output.get('all_tests'), list) and
162 isinstance(output.get('per_iteration_data'), list) and
163 all(isinstance(i, dict) for i in output.get('per_iteration_data'))
164 )
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698