diff options
author | Ivo Stoilov (GitHub) <istoilov@luxoft.com> | 2016-12-09 17:03:29 +0200 |
---|---|---|
committer | Ivo Stoilov (GitHub) <istoilov@luxoft.com> | 2016-12-09 17:10:55 +0200 |
commit | 39502608ebfe0fb7de869f5bca86cacdcbefc79b (patch) | |
tree | 7c16bde902ef33aca4c98c27641ab14d85f739fa /tools | |
parent | dd03531ec3e755e836d6778e417aed370a7aa4b0 (diff) | |
download | sdl_core-39502608ebfe0fb7de869f5bca86cacdcbefc79b.tar.gz |
Move some useful scripts
Move changes from check_style.sh
Move show_disabled.sh script
Move api_compare.py script
Related taks APPLINK-30589
Diffstat (limited to 'tools')
-rw-r--r-- | tools/infrastructure/api_compare.py | 468 | ||||
-rwxr-xr-x | tools/infrastructure/check_style.sh | 20 | ||||
-rwxr-xr-x | tools/infrastructure/show_disabled.sh | 27 |
3 files changed, 513 insertions, 2 deletions
diff --git a/tools/infrastructure/api_compare.py b/tools/infrastructure/api_compare.py new file mode 100644 index 0000000000..0129119673 --- /dev/null +++ b/tools/infrastructure/api_compare.py @@ -0,0 +1,468 @@ +#!/usr/bin/env python + +import json +import sys +import errno +import argparse +import xml.etree.ElementTree as ElementTree +from collections import namedtuple + +reload(sys) +# Enable Utf-8 support. Needed if script will be run under Windows +sys.setdefaultencoding('utf-8') + + +class colors: + """Class defining colorful output. + Works under UNIX ONLY as Windows does not support ANSI escape sequences + """ + HEADER = '\033[95m' + BLUE = '\033[94m' + GREEN = '\033[92m' + WARN = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + + +def simple_values_comparison(mobile_attribute_value, hmi_attribute_value): + """Simple attribute value comparison""" + return mobile_attribute_value == hmi_attribute_value + + +def parse_command_line_args(): + """Function adds and parses command line arguments""" + parser = argparse.ArgumentParser() + parser.add_argument( + "--mobile_api_file", + type=str, default="MOBILE_API.xml", + help='Enter mobile api file name! ("MOBILE_API.xml" by default)' + ) + parser.add_argument( + "--hmi_api_file", + type=str, default="HMI_API.xml", + help='Enter hmi api file name! ("HMI_API.xml" by default)' + ) + parser.add_argument( + "-o", "--output", + type=str, default="console", + choices=['xml', 'json', 'console'], + help='Choose report type! ("console" by default)' + ) + parser.add_argument( + "--full_info", + action="store_true", + help='Enter this parameter to get full detailed info!' + ) + args = parser.parse_args() + return args + + +def json_to_xml(json_obj, line_padding=" "): + """Function which converts json to xml format""" + result_list = list() + json_obj_type = type(json_obj) + if json_obj_type is list: + for sub_elem in json_obj: + result_list.append(json_to_xml(sub_elem, line_padding)) + return "\n".join(result_list) + if json_obj_type is dict: + for tag_name in json_obj: + sub_obj = json_obj[tag_name] + result_list.append("%s<%s>" % (line_padding, tag_name)) + result_list.append(json_to_xml(sub_obj, "\t" + line_padding)) + result_list.append("%s</%s>" % (line_padding, tag_name)) + return "\n".join(result_list) + return "%s%s" % (line_padding, json_obj) + + +def dict_to_json(summary_result): + """Function converts python dictionary to json format""" + return json.dumps( + summary_result, sort_keys=True, indent=4, separators=(',', ': ')) + + +def set_build_status(comparison_result): + """Function sets up build status depend on comparison result""" + if len(comparison_result) > 0: + sys.exit(errno.EPERM) + else: + return + + +def get_rpc_params(function): + """Function which gets all params from specified RPC""" + params = {} + for function_tag in function: # loop over function tags + if function_tag.tag == 'param': + name = function_tag.attrib['name'] + params[name] = function_tag.attrib + return params + + +Rpc = namedtuple("rpc", ["rpc_name", "rpc_type"]) + + +def extract_functions(interface, functions): + """Function extracting rpcs from passed interface""" + for child in interface: + if child.tag == 'function': + rpc_name = child.attrib['name'] + rpc_type = child.attrib['messagetype'] + key = Rpc(rpc_name=rpc_name, rpc_type=rpc_type) + params = get_rpc_params(child) + if key in functions: + functions[key].update(params) + else: + functions[key] = params + + +def filter_params(rpc, params_to_filter, filter): + "Function filters rpc parameters according passed filter" + filtered = [] + for param in params_to_filter: + # Filter only keys which present in filter + if param not in filter: + filtered.append(param) + else: + filter_func = filter[param] + if filter_func(rpc): + filtered.append(param) + return filtered + + +def create_result_section(param, result): + """Function creating appropriate section in result dictionary""" + if param not in result: + result[param] = {} + if "HMI_API" not in result[param]: + result[param]["HMI_API"] = {} + if "Mobile_API" not in result[param]: + result[param]["Mobile_API"] = {} + mob_api_result_section = result[param]["Mobile_API"] + hmi_api_result_section = result[param]["HMI_API"] + return mob_api_result_section, hmi_api_result_section + + +def compare_params(param, mob_param_attrs, hmi_param_attrs): + """Function comparing mobile and hmi parameter attributes""" + result = {} + mob_param_attrs = dict(mob_param_attrs) + hmi_param_attrs = dict(hmi_param_attrs) + for compare_rule in global_compare_rules: + condition = compare_rule[0] + rule = compare_rule[1] + if (condition(mob_param_attrs, hmi_param_attrs)): + mobile_res, hmi_res = rule( + mob_param_attrs, hmi_param_attrs) + if len(mobile_res) > 0 or len(hmi_res) > 0: + m_res, h_res = create_result_section(param, result) + m_res.update(mobile_res) + h_res.update(hmi_res) + return result + + +def fill_summary_result(rpc_name, area, value, summary_result): + """Function filling summary comparison result""" + if rpc_name not in summary_result: + summary_result[rpc_name] = {} + rpc = summary_result[rpc_name] + if type(value) is not dict: + rpc[area] = value + elif type(value) is dict: + if area not in rpc: + rpc[area] = {} + rpc[area].update(value) + + +def get_common_params(rpc_name, mob_api_functions, hmi_api_functions): + """Function calculates common parameters from mobile and hmi apis + for specified rpc + """ + hmi_params = hmi_api_functions[rpc_name] + mob_params = mob_api_functions[rpc_name] + mob_keys = mob_params.keys() + hmi_keys = hmi_params.keys() + return list(set(mob_keys).intersection(set(hmi_keys))) + + +def get_diff(common_params, rpc_name, hmi_params, mob_params, summary_result): + """Function which gets difference between parameters + and writes to summary result + """ + for param in common_params: + mob_items = sorted(mob_params[param].items()) + hmi_items = sorted(hmi_params[param].items()) + diff_res = compare_params(param, mob_items, hmi_items) + area = "Attributes difference:" + if len(diff_res) > 0: + fill_summary_result(rpc_name, area, + diff_res, summary_result + ) + + +def print_parameters(common_params, hmi_params, mob_params): + """Function which prints parameters in mobile, hmi api + and common parameters + """ + print "Parameters to check: ", common_params, "\n" + for param in common_params: + mob_items = sorted(mob_params[param].items()) + hmi_items = sorted(hmi_params[param].items()) + print colors.UNDERLINE + colors.BOLD + param + colors.ENDC, ":" + print "In Mobile API :\t", dict(mob_items) + print "In HMI API :\t", dict(hmi_items) + + +def print_full_info(hmi_absent_params, hmi_params, + mob_absent_params, mob_params, rpc_name): + """Function prints full detailed info about every rpc""" + print "\n" + "---" * 60 + "\n" + rpc_color = colors.BOLD + colors.HEADER + print rpc_color + rpc_name + colors.ENDC + print colors.BOLD + "\nMobile API: " + colors.ENDC + print "Parameters quantity: ", len(mob_params) + print "Parameters list: ", sorted(mob_params.keys()) + print colors.BOLD + "HMI API: " + colors.ENDC + print "Parameters quantity: ", len(hmi_params) + print "Parameters list: ", sorted(hmi_params.keys()) + print "\n" + print("{}Parameters absent in Mobile APIs: {}{}". + format(colors.WARN, mob_absent_params, colors.ENDC)) + print("{}Parameters absent in HMI APIs: {}{}". + format(colors.WARN, hmi_absent_params, colors.ENDC)) + print "\n" + + +def console_print(summary_result): + """Function which prints summary result to console""" + for rpc_name in sorted(summary_result.keys()): + print "\n" + "---" * 60 + print colors.HEADER + rpc_name + colors.ENDC + for problematic_item in summary_result[rpc_name]: + item = summary_result[rpc_name][problematic_item] + if len(item) > 0: + print colors.UNDERLINE + problematic_item + colors.ENDC + if type(item) is not dict: + print("{}{}{}".format(colors.WARN, item, colors.ENDC)) + elif type(item) is dict: + for param in item.keys(): + item_print = colors.UNDERLINE + param + colors.ENDC + print "{} {}".format("Parameter name: ", item_print) + res_val = item[param] + for key in res_val: + print key, ":", colors.FAIL, res_val[key], colors.ENDC + + +def print_summary_info(summary_result, args): + """Function which prints summary comparison info(if any). + Output type depends on command line args + """ + summary_color = colors.UNDERLINE + colors.BOLD + colors.BLUE + print "\n" + print summary_color, "SUMMARY COMPARISON RESULT:\n", colors.ENDC + if len(summary_result) == 0: + print colors.BOLD + " === NO PROBLEMS FOUND ===" + colors.ENDC + return + if args.output == "console": + console_print(summary_result) + if args.output == "json": + json_summary_result = dict_to_json(summary_result) + print json_summary_result + if args.output == "xml": + json_summary_result = dict_to_json(summary_result) + temp = json.loads(json_summary_result) + xml_summary_result = json_to_xml(temp) + print xml_summary_result + + +def handle_absent_params(area, absent_params, rpc_name, summary_result): + """Function which writes absent parameters(if any) + to summary result + """ + if len(absent_params) > 0: + fill_summary_result( + rpc_name, area, + absent_params, + summary_result + ) + + +def get_absent_hmi_params(hmi_params, mob_params, rpc): + """Function caculates absent parameters in hmi api""" + hmi_absent_params = set(mob_params.keys()) - set(hmi_params.keys()) + hmi_absent_params = filter_params( + rpc, hmi_absent_params, exclude_redundant_from_hmi_rpc_filter) + return hmi_absent_params + + +def get_absent_mob_params(hmi_params, mob_params, rpc): + """Function caculates absent parameters in mobile api""" + mob_absent_params = set(hmi_params.keys()) - set(mob_params.keys()) + mob_absent_params = filter_params( + rpc, mob_absent_params, exclude_params_from_mob_rpc) + return mob_absent_params + + +def get_rpc_for_handle(rpc_name, hmi_params, mob_params): + """Function creates rpc with all parameters to check""" + rpc = type('', (), {})() # empty object + rpc.mobile_params = mob_params + rpc.hmi_params = hmi_params + rpc.rpc_name = rpc_name.rpc_name + rpc.rpc_type = rpc_name.rpc_type + return rpc + + +def check_array_mandatory_param(attributes): + """Function checks presence of "array" mandatory parameters""" + result = {} + minsize_exists = "minsize" in attributes + if not minsize_exists: + attributes["minsize"] = None + result["array"] = attributes["array"] + result["minsize"] = attributes["minsize"] + maxsize_exists = "maxsize" in attributes + if not maxsize_exists: + attributes["maxsize"] = None + result["array"] = attributes["array"] + result["maxsize"] = attributes["maxsize"] + return result + + +def array_compare_rule(mob_param_attributes, hmi_param_attributes): + """Function checks presence of necessary parameters + if "array"="true" field presents + """ + attr = "array" + mobile_result = {} + if attr in mob_param_attributes and mob_param_attributes[attr] == "true": + mobile_result = check_array_mandatory_param(mob_param_attributes) + hmi_result = {} + if attr in hmi_param_attributes and hmi_param_attributes[attr] == "true": + hmi_result = check_array_mandatory_param(hmi_param_attributes) + return mobile_result, hmi_result + + +def string_compare_rule(mob_param_attributes, hmi_param_attributes): + """Function checks presence of "minlength"="1" in HMI_API if + "minlength" is omitted in MobileAPI. + Should be checked only for "type"="String" + """ + attr = "minlength" + if attr not in mob_param_attributes: + if attr not in hmi_param_attributes: + return {attr: None}, {attr: None} + elif hmi_param_attributes[attr] != "1": + return {attr: None}, {attr: hmi_param_attributes[attr]} + else: + mob_param_attributes[attr] = "1" + return {}, {} + + +def all_compare_rule(mob_param_attributes, hmi_param_attributes): + """Function used for all common arrtibutes comparison""" + mobile_result = {} + hmi_result = {} + attr_names = mob_param_attributes.keys() + hmi_param_attributes.keys() + attr_names = set(attr_names) + for attr_name in attr_names: + mobile_attribute_value = None + hmi_attribute_value = None + compare_func = simple_values_comparison + if attr_name in attributes_comparison_rules: + # Get appropriate comparison function from attributes comparison + # rules + compare_func = attributes_comparison_rules[attr_name] + if attr_name in mob_param_attributes: + mobile_attribute_value = mob_param_attributes[attr_name] + if attr_name in hmi_param_attributes: + hmi_attribute_value = hmi_param_attributes[attr_name] + values_equal = compare_func( + mobile_attribute_value, hmi_attribute_value) + if not values_equal: + hmi_result[attr_name] = hmi_attribute_value + mobile_result[attr_name] = mobile_attribute_value + return mobile_result, hmi_result + + +global_compare_rules = [ + # Comparison rule when attribute "type" = "String" + (lambda mob_param_attributes, hmi_param_attributes: + mob_param_attributes["type"] == "String", string_compare_rule), + # Comparison rule when attribute "array" = "true" + (lambda mob_param_attributes, hmi_param_attributes: + 'array' in mob_param_attributes.keys() + + hmi_param_attributes.keys(), array_compare_rule), + # Common comparison function for all attributes + (lambda mob_param_attributes, hmi_param_attributes: + True, all_compare_rule) +] + +attributes_comparison_rules = { + # If "mandatory" field is omitted i MobileApi + # it must be present in HMI_API as "mandatory"="true" by default + 'mandatory': lambda mobile_attribute_value, hmi_attribute_value: + True if mobile_attribute_value is None and hmi_attribute_value == "true" + else mobile_attribute_value == hmi_attribute_value, + # type <Common.<Struct/Enum> at HMI_API (MOBILE_APi has no <Common.>) + 'type': lambda mobile_attribute_value, hmi_attribute_value: + True if ("Common." + mobile_attribute_value) == hmi_attribute_value + else mobile_attribute_value == hmi_attribute_value +} + +# Parameters in HMI_API which should be excluded from comparison +exclude_redundant_from_hmi_rpc_filter = { + 'resultCode': lambda rpc: rpc.rpc_type != "response", + 'info': lambda rpc: rpc.rpc_type != "response", + 'success': lambda rpc: rpc.rpc_type != "response" +} + +# Parameters in MOBILE_API which should be excluded from comparison +exclude_params_from_mob_rpc = { + 'type': (lambda rpc: rpc.rpc_name not in ["AddCommand", "DeleteCommand"]), + 'appID': (lambda rpc: False), + 'grammarID': (lambda rpc: False)} + + +def main(): + args = parse_command_line_args() + mobile_api_tree = ElementTree.parse(args.mobile_api_file) + mob_api_functions = {} + extract_functions(mobile_api_tree.getroot(), mob_api_functions) + + hmi_api_tree = ElementTree.parse(args.hmi_api_file) + hmi_api_functions = {} + for interface in hmi_api_tree.getroot(): + extract_functions(interface, hmi_api_functions) + summary_result = {} + for rpc_name in sorted(mob_api_functions.keys()): + if rpc_name in hmi_api_functions: + hmi_params = hmi_api_functions[rpc_name] + mob_params = mob_api_functions[rpc_name] + rpc = get_rpc_for_handle(rpc_name, hmi_params, mob_params) + mob_absent_params = get_absent_mob_params( + hmi_params, mob_params, rpc) + hmi_absent_params = get_absent_hmi_params( + hmi_params, mob_params, rpc) + common_params = get_common_params( + rpc_name, mob_api_functions, hmi_api_functions) + + rpc_name = str(rpc_name.rpc_name + " " + rpc_name.rpc_type) + if args.full_info: + print_full_info(hmi_absent_params, hmi_params, + mob_absent_params, mob_params, rpc_name) + print_parameters(common_params, hmi_params, mob_params) + handle_absent_params("Missed in Mobile APIs:", mob_absent_params, + rpc_name, summary_result) + handle_absent_params("Missed in HMI APIs:", hmi_absent_params, + rpc_name, summary_result) + get_diff(common_params, rpc_name, hmi_params, + mob_params, summary_result) + print_summary_info(summary_result, args) + set_build_status(summary_result) + + +if __name__ == '__main__': + main() diff --git a/tools/infrastructure/check_style.sh b/tools/infrastructure/check_style.sh index f42a048b34..647427e793 100755 --- a/tools/infrastructure/check_style.sh +++ b/tools/infrastructure/check_style.sh @@ -27,15 +27,31 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +FORMATER=clang-format-3.6 +INSTALL_CMD="sudo apt-get install -f $FORMATER" + +if [ "$1" = "--help" ] +then + echo "" + echo "Script checks c++ code style in all .h .cc and .cpp files" + echo "Uses $FORMATER as base tool. Install it with : $INSTALL_CMD" + echo "Usage: `basename $0` [option]" + echo " --fix Fix files format indirectly" + echo " --help Display this information" + exit 0 +fi + +command -v $FORMATER >/dev/null 2>&1 || { echo >&2 "$FORMATER is not installed. Use following: $INSTALL_CMD"; exit 1; } + FILE_NAMES=$(find src -name \*.h -print -o -name \*.cpp -print -o -name \*.cc -print | grep -v 3rd_party) check_style() { - clang-format-3.6 -style=file $1 | diff $1 - + $FORMATER -style=file $1 | diff $1 - } fix_style() { - clang-format-3.6 -style=file -i $1 + $FORMATER -style=file -i $1 } if [ "$1" = "--fix" ] diff --git a/tools/infrastructure/show_disabled.sh b/tools/infrastructure/show_disabled.sh new file mode 100755 index 0000000000..7444755017 --- /dev/null +++ b/tools/infrastructure/show_disabled.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# Variable to store total amount of disabled unit tests +total_disabled=0 + +echo "" +echo "===== DISABLED Unit-tests amount ===== " +echo "" + +# Getting the list of all UT executables +for test_file in $(ctest -N | awk '{print $3}'); do + full_path=`find . -name $test_file -type f 2>/dev/null` + if [ $full_path ] ; then + # Count amount of disabled tests cases + count_of_disabled=$(${full_path} --gtest_list_tests | grep DISABLED | wc -l) + if [ 0 != $count_of_disabled ] ; then + let "total_disabled = $total_disabled + $count_of_disabled" + echo $count_of_disabled " : " $test_file; + fi + fi +done +echo "" +echo "TOTAL AMOUNT OF DISABLED TESTS : " $total_disabled; + +exit 0 + + |