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

Side by Side Diff: scripts/slave/get_swarm_results.py

Issue 10035003: Split up Each Swarm Test into Two Steps (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 8 years, 8 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5 # get_swarm_results.py: Retrieves and output swarm test results for a given
6 # test request name.
7
8 import json # pylint: disable=F0401
M-A Ruel 2012/04/17 20:16:00 You shouldn't need to disable the pylint warning,
csharp 2012/04/18 18:20:29 Done.
9 import optparse
10 import sys
11 import time
12 import urllib
13 import urllib2
14
15 DESCRIPTION = """This script takes in a test name and retrives all the output
M-A Ruel 2012/04/17 20:16:00 Make that a docstring, e.g. move it around line 7.
csharp 2012/04/18 18:20:29 Done.
16 that the swarm server has produced for tests with that name. This is expected to
17 be called as a build step."""
18
M-A Ruel 2012/04/17 20:16:00 2 lines between file level symbols
csharp 2012/04/18 18:20:29 Done.
19 def _get_first_number(line):
20 for part in line.split():
21 if part.isdigit():
22 return int(part)
23
24 print 'No number in :'
25 print line
26 return 0
27
28 class TestSummary(object):
29 def __init__(self):
30 self.test_passed_count = 0
31 self.failed_tests = []
32 self.disabled_test_count = 0
33 self.ignored_test_count = 0
34
35 def AddSummaryData(self, buf):
36 lines = buf.splitlines()
37
38 for line in lines:
39 if '[ PASSED ]' in line:
40 self.test_passed_count += _get_first_number(line)
41 elif '[ FAILED ]' in line:
42 if ', listed below' not in line:
43 self.failed_tests.append(line)
44 elif 'DISABLED' in line:
45 self.disabled_test_count += _get_first_number(line)
46 elif 'failures' in line:
47 self.ignored_test_count += _get_first_number(line)
48
49 def Output(self):
50 output = []
51
52 output.append('[ PASSED ] %i tests.' % self.test_passed_count)
53 if self.failed_tests:
54 output.append('[ FAILED ] failed tests listed below:')
55 output.extend(self.failed_tests)
56 output.append('%i FAILED TESTS' % len(self.failed_tests))
57
58 if self.disabled_test_count:
59 output.append('%i DISABLED TESTS' % self.disabled_test_count)
60
61 if self.ignored_test_count:
62 output.append('%i tests with ignored failures (FAILS prefix)' %
63 self.ignored_test_count)
64
65 return output
66
67
68 # TODO(csharp) The sharing_supervisor.py also has test parsing code, they should
69 # be shared.
70 def TestRunOutput(output):
71 """Go through the given output and only return the output from the Test Run
72 Step.
73 """
74 test_run_output = []
75
76 in_step = False
77 step_name = ''
78 for line in output.splitlines():
79 if in_step:
80 if '[ OK ] ' + step_name in line:
81 break
82 else:
83 test_run_output.append(line)
84 elif '[ RUN ] ' in line and 'Run Test' in line:
85 in_step = True
86 i = len('[ RUN ] ')
87 step_name = line[i:]
88
89 return '\n'.join(test_run_output)
M-A Ruel 2012/04/17 20:16:00 Technically, it's better to use splitlines(True) a
csharp 2012/04/18 18:20:29 Done.
90
91
92 def main():
93 """Retrieve the given swarm test results from the swarm server and print it
94 to stdout.
95
96 Args:
97 test_name: The name of the test to retrieve output for.
98 """
99 # Parses arguments
100 parser = optparse.OptionParser(usage='%prog [options] test_name',
101 description=DESCRIPTION)
M-A Ruel 2012/04/17 20:16:00 description=sys.modules[__name__].__doc__
csharp 2012/04/18 18:20:29 Done.
102 parser.add_option('-n', '--hostname', default='localhost',
103 help='Specify the hostname of the Swarm server. '
104 'Defaults to %default')
105 parser.add_option('-p', '--port', type='int', default=8080,
106 help='Specify the port of the Swarm server. '
107 'Defaults to %default')
108 parser.add_option('-v', '--verbose', action='store_true',
109 help='Print verbose logging')
110 (options, args) = parser.parse_args()
111 if not args:
112 parser.error('Must specify one test name.')
113 elif len(args) > 1:
114 parser.error('Must specify only one test name.')
115 test_name = args[0]
116
117 swarm_base_url = 'http://%s:%d' % (options.hostname, options.port)
118 key_data = urllib.urlencode([('name', test_name)])
119 test_keys_url = '%s/get_matching_test_cases?%s' % (swarm_base_url,
120 key_data)
121 result = urllib2.urlopen(test_keys_url).read()
122
123 if 'No matching' in result:
124 print('Error: Unable to find any tests with the name, %s, on swarm server',
125 test_name)
126 return 1
127
128 test_keys = result.split()
M-A Ruel 2012/04/17 20:16:00 Oh, I guess eventually it'd make sense to use a pr
csharp 2012/04/18 18:20:29 TODO added
129
130 # Get the swarm results.
M-A Ruel 2012/04/17 20:16:00 Can you move that out of main into it's own functi
csharp 2012/04/18 18:20:29 Done.
131 summary_total = TestSummary()
132 hostnames = ['unknown'] * len(test_keys)
133 exit_codes = [1] * len(test_keys)
134 for index in range(len(test_keys)):
135 result_url = '%s/get_result?r=%s' % (swarm_base_url, test_keys[index])
136 while True:
137 output = None
138 try:
139 output = urllib2.urlopen(result_url).read()
140 except urllib2.HTTPError, e:
141 print 'Calling %s threw %s' % (result_url, e)
142 break
143
144 try:
145 test_outputs = json.loads(output)
146 except (ValueError, TypeError), e:
147 print 'Unable to get results for shard %d' % index
148 print e
149 break
150
151 if test_outputs['output']:
152 test_exit_codes = test_outputs['exit_codes'].split(',')
153 exit_codes[index] = int(max(test_exit_codes))
154 hostnames[index] = test_outputs['hostname']
155
156 print
157 print '================================================================'
158 print 'Begin output from shard index %s (%s)' % (index,
159 hostnames[index])
160 print '================================================================'
161 print
162
163 cleaned_output = TestRunOutput(test_outputs['output'])
164 summary_index = cleaned_output.rfind('[ PASSED ]')
165 summary_total.AddSummaryData(cleaned_output[summary_index:])
166 sys.stdout.write(cleaned_output[:summary_index - 1])
167
168 print
169 print '================================================================'
170 print 'End output from shard index %s (%s). Return %d' % (
171 index, hostnames[index], exit_codes[index])
172 print '================================================================'
173 print
174
175 if exit_codes[index] == 0:
176 # If the test passed, delete the key since it is no longer needed.
177 remove_key_url = '%s/cleanup_results' % swarm_base_url
178 key_encoding = urllib.urlencode([('r', test_keys[index])])
179 urllib2.urlopen(remove_key_url,
180 key_encoding)
181 break
182 else:
183 # Test is not yet done, wait a bit before checking again.
184 time.sleep(0.5)
185
186 print '\n'.join(summary_total.Output())
187 print
188
189 if options.verbose:
190 print 'All tests completed:'
191 for i in range(options.num_shards):
192 print 'Shard index %s (%s): Exit code: %d' % (i,
193 hostnames[i], exit_codes[i])
194
195 return max(exit_codes)
196
197 if __name__ == '__main__':
198 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698