blob: 5035b7ccd6595edeca905de2003d684bd15e9893 [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Format a JSON test list."""
import argparse
import collections
import json
import sys
def ReorderDictKey(obj, key_order=None):
if key_order is None:
key_order = lambda x: x
if callable(key_order):
key_order = list(sorted(obj.iterkeys(), key=key_order))
elif not all(k in key_order for k in obj):
raise ValueError('Some keys of %r is not inside order %r.' % (obj,
key_order))
return collections.OrderedDict((k, obj[k]) for k in key_order if k in obj)
def ReorderDictKeyInObject(obj, path, key_order=None):
paths = path.split('.')
last = paths.pop()
for p in paths:
if p not in obj:
return
obj = obj[p]
if last in obj:
obj[last] = ReorderDictKey(obj[last], key_order)
_COMMENT_PREFIX = '__comment_'
def ConstantOrder(constant):
if constant.startswith(_COMMENT_PREFIX):
return (constant[len(_COMMENT_PREFIX):], 1)
return (constant, 0)
_TEST_OBJECT_KEY_ORDER = [
'__replace__', '__delete__', 'inherit', 'pytest_name', 'id', 'label',
'teardown', 'run_if', 'exclusive_resources', 'disable_services',
'enable_services', 'allow_reboot', 'parallel', 'layout', 'iterations',
'retries', 'action_on_failure', 'child_action_on_failure', 'disable_abort',
'require_run', '__comment', 'locals', 'subtests', 'args'
]
def RecursiveFormatTestObject(test_obj):
if isinstance(test_obj, basestring):
return test_obj
test_obj = ReorderDictKey(test_obj, _TEST_OBJECT_KEY_ORDER)
if 'subtests' in test_obj:
test_obj['subtests'] = [
RecursiveFormatTestObject(v) for v in test_obj['subtests']
]
return test_obj
def Format(test_list):
test_list = ReorderDictKey(
test_list,
key_order=[
'__comment', 'inherit', 'label', 'constants', 'options',
'definitions', 'tests', 'override_args'
])
ReorderDictKeyInObject(test_list, 'options')
ReorderDictKeyInObject(test_list, 'constants', key_order=ConstantOrder)
ReorderDictKeyInObject(test_list, 'definitions')
if 'definitions' in test_list:
test_list['definitions'] = collections.OrderedDict(
(k, RecursiveFormatTestObject(v))
for k, v in test_list['definitions'].iteritems())
if 'tests' in test_list:
test_list['tests'] = [
RecursiveFormatTestObject(test_obj) for test_obj in test_list['tests']
]
ReorderDictKeyInObject(test_list, 'override_args')
return test_list
def main():
parser = argparse.ArgumentParser(description='Format a JSON test list.')
parser.add_argument(
'-i', '--inplace', dest='inplace', action='store_true',
help='Update the JSON test list inplace.')
parser.add_argument('test_list', help='The test list to be formatted.')
options = parser.parse_args()
with open(options.test_list, 'r') as fp:
input_test_list = json.load(fp, object_pairs_hook=collections.OrderedDict)
output_test_list = Format(input_test_list)
def _WriteTestList(fp, test_list):
json.dump(
test_list, fp, indent=2, separators=(',', ': '), ensure_ascii=True)
fp.write('\n')
if options.inplace:
with open(options.test_list, 'w') as fp:
_WriteTestList(fp, output_test_list)
else:
_WriteTestList(sys.stdout, output_test_list)
if __name__ == '__main__':
main()