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