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