diff --git a/test/iscsi_tgt/iscsijson/json_config.sh b/test/iscsi_tgt/iscsijson/json_config.sh index 02d69d345..cec662b7e 100755 --- a/test/iscsi_tgt/iscsijson/json_config.sh +++ b/test/iscsi_tgt/iscsijson/json_config.sh @@ -33,7 +33,7 @@ $rpc_py load_config < $base_iscsi_config $rpc_py save_config > $last_iscsi_config timing_exit iscsi_json_config_restart_spdk -diff $base_iscsi_config $last_iscsi_config +json_diff $base_iscsi_config $last_iscsi_config $clear_config_py clear_config kill_targets diff --git a/test/json_config/common.sh b/test/json_config/common.sh index 979f4fb66..c0cbfd25a 100644 --- a/test/json_config/common.sh +++ b/test/json_config/common.sh @@ -60,6 +60,28 @@ function kill_targets() { fi } +# Compare two JSON files. +# +# NOTE: Order of objects in JSON can change by just doing loads -> dumps so all JSON objects (not arrays) are sorted by +# config_filter.py script. Sorted output is used to compare JSON output. +# +function json_diff() +{ + local tmp_file_1=$(mktemp ${1}.XXX) + local tmp_file_2=$(mktemp ${2}.XXX) + local ret=0 + + cat $1 | $JSON_DIR/config_filter.py -method "sort" > $tmp_file_1 + cat $2 | $JSON_DIR/config_filter.py -method "sort" > $tmp_file_2 + + if ! diff -u $tmp_file_1 $tmp_file_2; then + ret=1 + fi + + rm $tmp_file_1 $tmp_file_2 + return $ret +} + # This function test if json config was properly saved and loaded. # 1. Get a list of bdevs and save it to the file "base_bdevs". # 2. Save only configuration of the running spdk_tgt to the file "base_json_config" @@ -88,8 +110,9 @@ function test_json_config() { $rpc_py load_config < $base_json_config $rpc_py get_bdevs | jq '.|sort_by(.name)' > $last_bdevs $rpc_py save_config | $JSON_DIR/config_filter.py -method "delete_global_parameters" > $last_json_config - diff $base_json_config $last_json_config - diff $base_bdevs $last_bdevs + + json_diff $base_json_config $last_json_config + json_diff $base_bdevs $last_bdevs remove_config_files_after_test_json_config } @@ -196,7 +219,8 @@ function test_global_params() { $rpc_py load_config < $full_config $rpc_py save_config > $full_config python $JSON_DIR/config_filter.py -method "delete_configs" < $full_config > $last_json_config - diff $base_json_config $last_json_config + + json_diff $base_json_config $last_json_config rm $base_json_config $last_json_config rm $full_config } diff --git a/test/json_config/config_filter.py b/test/json_config/config_filter.py index 75b400f43..3ee59a7d0 100755 --- a/test/json_config/config_filter.py +++ b/test/json_config/config_filter.py @@ -2,6 +2,22 @@ import sys import json import argparse +from collections import OrderedDict + + +def sort_json_object(o): + if isinstance(o, dict): + sorted_o = OrderedDict() + """ Order of keys in JSON object is irrelevant but we need to pick one + to be able to compare JSONS. """ + for key in sorted(o.keys()): + sorted_o[key] = sort_json_object(o[key]) + return sorted_o + if isinstance(o, list): + """ Keep list in the same orded but sort each item """ + return [sort_json_object(item) for item in o] + else: + return o def filter_methods(do_remove_global_rpcs): @@ -41,5 +57,12 @@ if __name__ == "__main__": args = parser.parse_args() if args.method == "delete_global_parameters": filter_methods(True) - if args.method == "delete_configs": + elif args.method == "delete_configs": filter_methods(False) + elif args.method == "sort": + """ Wrap input into JSON object so any input is possible here + like output from get_bdevs RPC method""" + o = json.loads('{ "the_object": ' + sys.stdin.read() + ' }') + print(json.dumps(sort_json_object(o)['the_object'], indent=2)) + else: + raise ValueError("Invalid method '{}'".format(args.method)) diff --git a/test/nvmf/nvmfjson/json_config.sh b/test/nvmf/nvmfjson/json_config.sh index d2bde33f7..bc624d21f 100755 --- a/test/nvmf/nvmfjson/json_config.sh +++ b/test/nvmf/nvmfjson/json_config.sh @@ -23,7 +23,7 @@ function test_subsystems() { $rpc_py load_config < $base_nvmf_config $rpc_py save_config > $last_nvmf_config - diff $base_nvmf_config $last_nvmf_config + json_diff $base_nvmf_config $last_nvmf_config clear_nvmf_subsystem_config kill_targets