OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 return | 96 return |
97 | 97 |
98 args.remove('--gtest_output=' + current_value) | 98 args.remove('--gtest_output=' + current_value) |
99 return args | 99 return args |
100 | 100 |
101 | 101 |
102 def AppendToXML(final_xml, generic_path, shard): | 102 def AppendToXML(final_xml, generic_path, shard): |
103 """Combine the shard xml file with the final xml file.""" | 103 """Combine the shard xml file with the final xml file.""" |
104 | 104 |
105 path = generic_path + str(shard) | 105 path = generic_path + str(shard) |
106 with open(path) as shard_xml_file: | 106 |
107 shard_xml = minidom.parse(shard_xml_file) | 107 try: |
| 108 with open(path) as shard_xml_file: |
| 109 shard_xml = minidom.parse(shard_xml_file) |
| 110 except IOError: |
| 111 # If the shard crashed, gtest will not have generated an xml file. |
| 112 return final_xml |
108 | 113 |
109 if not final_xml: | 114 if not final_xml: |
110 # Out final xml is empty, let's prepopulate it with the first one we see. | 115 # Out final xml is empty, let's prepopulate it with the first one we see. |
111 return shard_xml | 116 return shard_xml |
112 | 117 |
113 shard_node = shard_xml.documentElement | 118 shard_node = shard_xml.documentElement |
114 final_node = final_xml.documentElement | 119 final_node = final_xml.documentElement |
115 | 120 |
116 testcases = shard_node.getElementsByTagName('testcase') | 121 testcases = shard_node.getElementsByTagName('testcase') |
117 final_testcases = final_node.getElementsByTagName('testcase') | 122 final_testcases = final_node.getElementsByTagName('testcase') |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 | 367 |
363 # All the shards are done. Merge all the XML files and generate the | 368 # All the shards are done. Merge all the XML files and generate the |
364 # main one. | 369 # main one. |
365 output_arg = GetGTestOutput(self.gtest_args) | 370 output_arg = GetGTestOutput(self.gtest_args) |
366 if output_arg: | 371 if output_arg: |
367 xml, xml_path = output_arg.split(':', 1) | 372 xml, xml_path = output_arg.split(':', 1) |
368 assert(xml == 'xml') | 373 assert(xml == 'xml') |
369 final_xml = None | 374 final_xml = None |
370 for i in range(start_point, start_point + self.num_shards_to_run): | 375 for i in range(start_point, start_point + self.num_shards_to_run): |
371 final_xml = AppendToXML(final_xml, xml_path, i) | 376 final_xml = AppendToXML(final_xml, xml_path, i) |
372 with open(xml_path, 'w') as final_file: | 377 |
373 final_xml.writexml(final_file) | 378 if final_xml: |
| 379 with open(xml_path, 'w') as final_file: |
| 380 final_xml.writexml(final_file) |
374 | 381 |
375 num_failed = len(self.failed_shards) | 382 num_failed = len(self.failed_shards) |
376 if num_failed > 0: | 383 if num_failed > 0: |
377 self.failed_shards.sort() | 384 self.failed_shards.sort() |
378 self.WriteText(sys.stdout, | 385 self.WriteText(sys.stdout, |
379 "\nFAILED SHARDS: %s\n" % str(self.failed_shards), | 386 "\nFAILED SHARDS: %s\n" % str(self.failed_shards), |
380 "\x1b[1;5;31m") | 387 "\x1b[1;5;31m") |
381 else: | 388 else: |
382 self.WriteText(sys.stdout, "\nALL SHARDS PASSED!\n", "\x1b[1;5;32m") | 389 self.WriteText(sys.stdout, "\nALL SHARDS PASSED!\n", "\x1b[1;5;32m") |
383 self.PrintSummary(self.failed_tests) | 390 self.PrintSummary(self.failed_tests) |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 # shard and run the whole test | 627 # shard and run the whole test |
621 ss = ShardingSupervisor( | 628 ss = ShardingSupervisor( |
622 args[0], num_shards_to_run, num_runs, options.color, | 629 args[0], num_shards_to_run, num_runs, options.color, |
623 options.original_order, options.prefix, options.retry_percent, | 630 options.original_order, options.prefix, options.retry_percent, |
624 options.timeout, options.total_slaves, options.slave_index, gtest_args) | 631 options.timeout, options.total_slaves, options.slave_index, gtest_args) |
625 return ss.ShardTest() | 632 return ss.ShardTest() |
626 | 633 |
627 | 634 |
628 if __name__ == "__main__": | 635 if __name__ == "__main__": |
629 sys.exit(main()) | 636 sys.exit(main()) |
OLD | NEW |