OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Shards a given test suite and runs the shards in parallel. | 6 """Shards a given test suite and runs the shards in parallel. |
7 | 7 |
8 ShardingSupervisor is called to process the command line options and creates | 8 ShardingSupervisor is called to process the command line options and creates |
9 the specified number of worker threads. These threads then run each shard of | 9 the specified number of worker threads. These threads then run each shard of |
10 the test in a separate process and report on the results. When all the shards | 10 the test in a separate process and report on the results. When all the shards |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 | 116 |
117 if not final_xml: | 117 if not final_xml: |
118 # Out final xml is empty, let's prepopulate it with the first one we see. | 118 # Out final xml is empty, let's prepopulate it with the first one we see. |
119 return shard_xml | 119 return shard_xml |
120 | 120 |
121 shard_node = shard_xml.documentElement | 121 shard_node = shard_xml.documentElement |
122 final_node = final_xml.documentElement | 122 final_node = final_xml.documentElement |
123 | 123 |
124 testcases = shard_node.getElementsByTagName('testcase') | 124 testcases = shard_node.getElementsByTagName('testcase') |
125 final_testcases = final_node.getElementsByTagName('testcase') | 125 final_testcases = final_node.getElementsByTagName('testcase') |
126 | |
127 final_testsuites = final_node.getElementsByTagName('testsuite') | |
128 final_testsuites_by_name = {} | |
129 for final_testsuite in final_testsuites: | |
130 final_testsuites_by_name[final_testsuite.getAttribute('name')] = \ | |
M-A Ruel
2012/07/10 14:26:50
final_testsuites_by_name = dict(
(suite.getAttri
Mihai Parparita -not on Chrome
2012/07/10 20:15:16
Done.
| |
131 final_testsuite | |
132 | |
126 for testcase in testcases: | 133 for testcase in testcases: |
127 name = testcase.getAttribute('name') | 134 name = testcase.getAttribute('name') |
128 classname = testcase.getAttribute('classname') | 135 classname = testcase.getAttribute('classname') |
129 failures = testcase.getElementsByTagName('failure') | 136 failures = testcase.getElementsByTagName('failure') |
130 status = testcase.getAttribute('status') | 137 status = testcase.getAttribute('status') |
131 elapsed = testcase.getAttribute('time') | 138 elapsed = testcase.getAttribute('time') |
132 | 139 |
133 # don't bother updating the final xml if there is no data. | 140 # don't bother updating the final xml if there is no data. |
134 if status == 'notrun': | 141 if status == 'notrun': |
135 continue | 142 continue |
136 | 143 |
137 # Look in our final xml to see if it's there. | 144 # Look in our final xml to see if it's there. |
138 # There has to be a better way... | 145 # There has to be a better way... |
146 merged_into_final_testcase = False | |
139 for final_testcase in final_testcases: | 147 for final_testcase in final_testcases: |
140 final_name = final_testcase.getAttribute('name') | 148 final_name = final_testcase.getAttribute('name') |
141 final_classname = final_testcase.getAttribute('classname') | 149 final_classname = final_testcase.getAttribute('classname') |
142 if final_name == name and final_classname == classname: | 150 if final_name == name and final_classname == classname: |
143 # We got the same entry. | 151 # We got the same entry. |
144 final_testcase.setAttribute('status', status) | 152 final_testcase.setAttribute('status', status) |
145 final_testcase.setAttribute('time', elapsed) | 153 final_testcase.setAttribute('time', elapsed) |
146 for failure in failures: | 154 for failure in failures: |
147 final_testcase.appendChild(failure) | 155 final_testcase.appendChild(failure) |
156 merged_into_final_testcase = True | |
157 | |
158 # We couldn't find an existing testcase to merge the results into, so we | |
159 # copy the node into the existing test suite. | |
160 if not merged_into_final_testcase: | |
161 testsuite = testcase.parentNode | |
162 final_testsuite = final_testsuites_by_name[testsuite.getAttribute('name')] | |
nsylvain
2012/07/10 20:16:08
is it possible that the testsuite is not in the fi
Mihai Parparita -not on Chrome
2012/07/10 20:18:57
That didn't seem to be the case with the data that
| |
163 final_testsuite.appendChild(testcase) | |
148 | 164 |
149 return final_xml | 165 return final_xml |
150 | 166 |
151 | 167 |
152 def RunShard(test, total_shards, index, gtest_args, stdout, stderr): | 168 def RunShard(test, total_shards, index, gtest_args, stdout, stderr): |
153 """Runs a single test shard in a subprocess. | 169 """Runs a single test shard in a subprocess. |
154 | 170 |
155 Returns: | 171 Returns: |
156 The Popen object representing the subprocess handle. | 172 The Popen object representing the subprocess handle. |
157 """ | 173 """ |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
281 shard_output: Buffer that stores the output from each shard. | 297 shard_output: Buffer that stores the output from each shard. |
282 test_counter: Stores the total number of tests run. | 298 test_counter: Stores the total number of tests run. |
283 total_slaves: Total number of slaves running this test. | 299 total_slaves: Total number of slaves running this test. |
284 slave_index: Current slave to run tests for. | 300 slave_index: Current slave to run tests for. |
285 | 301 |
286 If total_slaves is set, we run only a subset of the tests. This is meant to be | 302 If total_slaves is set, we run only a subset of the tests. This is meant to be |
287 used when we want to shard across machines as well as across cpus. In that | 303 used when we want to shard across machines as well as across cpus. In that |
288 case the number of shards to execute will be the same, but they will be | 304 case the number of shards to execute will be the same, but they will be |
289 smaller, as the total number of shards in the test suite will be multiplied | 305 smaller, as the total number of shards in the test suite will be multiplied |
290 by 'total_slaves'. | 306 by 'total_slaves'. |
291 | 307 |
292 For example, if you are on a quad core machine, the sharding supervisor by | 308 For example, if you are on a quad core machine, the sharding supervisor by |
293 default will use 20 shards for the whole suite. However, if you set | 309 default will use 20 shards for the whole suite. However, if you set |
294 total_slaves to 2, it will split the suite in 40 shards and will only run | 310 total_slaves to 2, it will split the suite in 40 shards and will only run |
295 shards [0-19] or shards [20-39] depending if you set slave_index to 0 or 1. | 311 shards [0-19] or shards [20-39] depending if you set slave_index to 0 or 1. |
296 """ | 312 """ |
297 | 313 |
298 SHARD_COMPLETED = object() | 314 SHARD_COMPLETED = object() |
299 | 315 |
300 def __init__(self, test, num_shards_to_run, num_runs, color, original_order, | 316 def __init__(self, test, num_shards_to_run, num_runs, color, original_order, |
301 prefix, retry_percent, timeout, total_slaves, slave_index, | 317 prefix, retry_percent, timeout, total_slaves, slave_index, |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
645 # shard and run the whole test | 661 # shard and run the whole test |
646 ss = ShardingSupervisor( | 662 ss = ShardingSupervisor( |
647 test, num_shards_to_run, num_runs, options.color, | 663 test, num_shards_to_run, num_runs, options.color, |
648 options.original_order, options.prefix, options.retry_percent, | 664 options.original_order, options.prefix, options.retry_percent, |
649 options.timeout, options.total_slaves, options.slave_index, gtest_args) | 665 options.timeout, options.total_slaves, options.slave_index, gtest_args) |
650 return ss.ShardTest() | 666 return ss.ShardTest() |
651 | 667 |
652 | 668 |
653 if __name__ == "__main__": | 669 if __name__ == "__main__": |
654 sys.exit(main()) | 670 sys.exit(main()) |
OLD | NEW |