OLD | NEW |
(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 |
| 6 def merge_test_results(shard_results_list): |
| 7 """ Merge list of results. |
| 8 |
| 9 Args: |
| 10 shard_results_list: list of results to merge. All the results must have the |
| 11 same format. Supported format are simplified JSON format & Chromium JSON |
| 12 test results format version 3 (see |
| 13 https://www.chromium.org/developers/the-json-test-results-format) |
| 14 |
| 15 Returns: |
| 16 a |
| 17 """ |
| 18 if 'seconds_since_epoch' in shard_results_list[0]: |
| 19 return _merge_json_test_result_format(shard_results_list) |
| 20 else: |
| 21 return _merge_simplified_json_format(shard_results_list) |
| 22 |
| 23 |
| 24 def _merge_simplified_test_result_format(self, shard_results_list): |
| 25 # This code is specialized to the "simplified" JSON format that used to be |
| 26 # the standard for recipes. |
| 27 |
| 28 # These are the only keys we pay attention to in the output JSON. |
| 29 merged_results = { |
| 30 'successes': [], |
| 31 'failures': [], |
| 32 'valid': True, |
| 33 } |
| 34 |
| 35 for result_json in shard_results_list: |
| 36 for key in merged_results: |
| 37 if key in result_json: |
| 38 if isinstance(merged_results[key], list): |
| 39 merged_results[key].extend(result_json[key]) |
| 40 elif isinstance(merged_results[key], bool): |
| 41 merged_results[key] = merged_results[key] and result_json[key] |
| 42 else: |
| 43 raise Exception( |
| 44 'Unknown key type ' + type(merged_results[key]) + |
| 45 ' when handling key ' + key + '.') # pragma: no cover |
| 46 return merged_results |
| 47 |
| 48 def _merge_json_test_result_format(shard_results_list): |
| 49 # This code is specialized to the Chromium JSON test results format version 3: |
| 50 # https://www.chromium.org/developers/the-json-test-results-format |
| 51 |
| 52 # These are required fields for the JSON test result format version 3. |
| 53 merged_results = { |
| 54 'tests': {}, |
| 55 'interrupted': False, |
| 56 'path_delimiter': '', |
| 57 'version': 3, |
| 58 'seconds_since_epoch': float('inf'), |
| 59 'num_failures_by_type': { |
| 60 } |
| 61 } |
| 62 for result_json in shard_results_list: |
| 63 if not ('tests' in result_json and |
| 64 'interrupted' in result_json and |
| 65 'path_delimiter' in result_json and |
| 66 'version' in result_json and |
| 67 'seconds_since_epoch' in result_json and |
| 68 'num_failures_by_type' in result_json): |
| 69 raise Exception('Invalid json test results') |
| 70 |
| 71 # Traverse the result_json's test trie & merged_results's test tries in |
| 72 # DFS order & add the n to merged['tests']. |
| 73 curr_result_nodes_queue = [result_json['tests']] |
| 74 merged_results_nodes_queue = [merged_results['tests']] |
| 75 while curr_result_nodes_queue: |
| 76 curr_node = curr_result_nodes_queue.pop() |
| 77 merged_node = merged_results_nodes_queue.pop() |
| 78 for k, v in curr_node.iteritems(): |
| 79 if k in merged_node: |
| 80 curr_result_nodes_queue.append(v) |
| 81 merged_results_nodes_queue.append(merged_node[k]) |
| 82 else: |
| 83 merged_node[k] = v |
| 84 |
| 85 # Update the rest of the fields for merged_results. |
| 86 merged_results['interrupted'] |= result_json['interrupted'] |
| 87 if not merged_results['path_delimiter']: |
| 88 merged_results['path_delimiter'] = result_json['path_delimiter'] |
| 89 elif merged_results['path_delimiter'] != result_json['path_delimiter']: |
| 90 raise Exception( |
| 91 'Incosistent path delimiter: %s %s' % |
| 92 (merged_results['path_delimiter'], |
| 93 result_json['path_delimiter'])) |
| 94 if result_json['version'] != 3: |
| 95 raise Exception( |
| 96 'Only version 3 of json test result format is supported') |
| 97 merged_results['seconds_since_epoch'] = min( |
| 98 merged_results['seconds_since_epoch'], |
| 99 result_json['seconds_since_epoch']) |
| 100 for result_type, count in result_json['num_failures_by_type'].iteritems(): |
| 101 merged_results['num_failures_by_type'].setdefault(result_type, 0) |
| 102 merged_results['num_failures_by_type'][result_type] += count |
| 103 return merged_results |
OLD | NEW |