Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(819)

Unified Diff: scripts/slave/recipe_modules/swarming/results_merger.py

Issue 2375663003: Add json test results format support for SwarmingIsolatedScriptTest (Closed)
Patch Set: Add no cover Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: scripts/slave/recipe_modules/swarming/results_merger.py
diff --git a/scripts/slave/recipe_modules/swarming/results_merger.py b/scripts/slave/recipe_modules/swarming/results_merger.py
new file mode 100644
index 0000000000000000000000000000000000000000..0fb21ae421990e019e4285a4ceab923ac8e5e44e
--- /dev/null
+++ b/scripts/slave/recipe_modules/swarming/results_merger.py
@@ -0,0 +1,111 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import copy
+
+
+def merge_test_results(shard_results_list):
+ """ Merge list of results.
+
+ Args:
+ shard_results_list: list of results to merge. All the results must have the
+ same format. Supported format are simplified JSON format & Chromium JSON
+ test results format version 3 (see
+ https://www.chromium.org/developers/the-json-test-results-format)
+
+ Returns:
+ a dictionary that represent the merged results. Its format follow the same
+ format of all results in |shard_results_list|.
+ """
+ if 'seconds_since_epoch' in shard_results_list[0]:
+ return _merge_json_test_result_format(shard_results_list)
+ else:
+ return _merge_simplified_json_format(shard_results_list)
+
+
+def _merge_simplified_json_format(shard_results_list):
+ # This code is specialized to the "simplified" JSON format that used to be
+ # the standard for recipes.
+
+ # These are the only keys we pay attention to in the output JSON.
+ merged_results = {
+ 'successes': [],
+ 'failures': [],
+ 'valid': True,
+ }
+
+ for result_json in shard_results_list:
+ successes = result_json.get('successes', [])
+ failures = result_json.get('failures', [])
+ valid = result_json.get('valid', True)
+
+ if (not isinstance(successes, list) or not isinstance(failures, list) or
+ not isinstance(valid, bool)):
+ raise Exception(
+ 'Unexpected value type in %s' % result_json) # pragma: no cover
+
+ merged_results['successes'].extend(successes)
+ merged_results['failures'].extend(failures)
+ merged_results['valid'] = merged_results['valid'] and valid
+ return merged_results
+
+
+def _merge_json_test_result_format(shard_results_list):
+ # This code is specialized to the Chromium JSON test results format version 3:
+ # https://www.chromium.org/developers/the-json-test-results-format
+
+ # These are required fields for the JSON test result format version 3.
+ merged_results = {
+ 'tests': {},
+ 'interrupted': False,
+ 'path_delimiter': '',
+ 'version': 3,
+ 'seconds_since_epoch': float('inf'),
+ 'num_failures_by_type': {
+ }
+ }
+ # To make sure that we don't mutate existing shard_results_list.
+ shard_results_list = copy.deepcopy(shard_results_list)
+ for result_json in shard_results_list:
+ if not ('tests' in result_json and
+ 'interrupted' in result_json and
+ 'path_delimiter' in result_json and
+ 'version' in result_json and
+ 'seconds_since_epoch' in result_json and
+ 'num_failures_by_type' in result_json):
+ raise Exception('Invalid json test results')
+
+ # Traverse the result_json's test trie & merged_results's test tries in
+ # DFS order & add the n to merged['tests'].
+ curr_result_nodes_queue = [result_json['tests']]
+ merged_results_nodes_queue = [merged_results['tests']]
+ while curr_result_nodes_queue:
+ curr_node = curr_result_nodes_queue.pop()
+ merged_node = merged_results_nodes_queue.pop()
+ for k, v in curr_node.iteritems():
+ if k in merged_node:
+ curr_result_nodes_queue.append(v)
+ merged_results_nodes_queue.append(merged_node[k])
+ else:
+ merged_node[k] = v
+
+ # Update the rest of the fields for merged_results.
+ merged_results['interrupted'] |= result_json['interrupted']
+ if not merged_results['path_delimiter']:
+ merged_results['path_delimiter'] = result_json['path_delimiter']
+ elif merged_results['path_delimiter'] != result_json['path_delimiter']:
+ raise Exception( # pragma: no cover - covered by results_merger_unittest
+ 'Incosistent path delimiter: %s %s' %
+ (merged_results['path_delimiter'],
+ result_json['path_delimiter']))
+ if result_json['version'] != 3:
+ raise Exception( # pragma: no cover - covered by results_merger_unittest
+ 'Only version 3 of json test result format is supported')
+ merged_results['seconds_since_epoch'] = min(
+ merged_results['seconds_since_epoch'],
+ result_json['seconds_since_epoch'])
+ for result_type, count in result_json['num_failures_by_type'].iteritems():
+ merged_results['num_failures_by_type'].setdefault(result_type, 0)
+ merged_results['num_failures_by_type'][result_type] += count
+ return merged_results
« no previous file with comments | « scripts/slave/recipe_modules/swarming/api.py ('k') | scripts/slave/recipe_modules/swarming/tests/results_merger_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698