From f56d95b67c18955ba0fe7578c0394329df35ebf6 Mon Sep 17 00:00:00 2001 From: Haitham Shami Date: Mon, 17 May 2021 10:47:19 -0700 Subject: [PATCH] update command line argument parser (#19) * update command line argument parser * update with PR feedback --- src/azure-iot-edge-installer.sh | 18 ++-- src/utils.sh | 95 ++++++++++++++----- tests/unit-tests/test-cmd-parser.sh | 91 ++++++++++-------- .../test-install-container-management.sh | 2 +- tests/unit-tests/test-install-edge-runtime.sh | 2 +- tests/unit-tests/test-logger.sh | 88 ++++++++--------- .../unit-tests/test-validate-post-install.sh | 70 +++++++------- 7 files changed, 207 insertions(+), 159 deletions(-) diff --git a/src/azure-iot-edge-installer.sh b/src/azure-iot-edge-installer.sh index ee95018..68264fa 100644 --- a/src/azure-iot-edge-installer.sh +++ b/src/azure-iot-edge-installer.sh @@ -88,18 +88,10 @@ log_init VERSION_TAG="v0.0.0-rc0" # add flag:variable_name dictionary entries -add_option_args -v "VERBOSE_LOGGING" -add_option_args --verbose "VERBOSE_LOGGING" -add_option_args -dp "DEVICE_PROVISIONING" -add_option_args --device-provisioning "DEVICE_PROVISIONING" -add_option_args -ap "AZURE_CLOUD_IDENTITY_PROVIDER" -add_option_args --azure-cloud-identity-provider "AZURE_CLOUD_IDENTITY_PROVIDER" -add_option_args -s "SCOPE_ID" -add_option_args --scope-id "SCOPE_ID" -add_option_args -r "REGISTRATION_ID" -add_option_args --registration-id "REGISTRATION_ID" -add_option_args -k "SYMMETRIC_KEY" -add_option_args --symmetric-key "SYMMETRIC_KEY" +add_option_args "VERBOSE_LOGGING" -v --verbose +add_option_args "SCOPE_ID" -s --scope-id +add_option_args "REGISTRATION_ID" -r --registration-id +add_option_args "SYMMETRIC_KEY" -k --symmetric-key # parse command line inputs and fetch output from parser declare -A parsed_cmds="$(cmd_parser $@)" @@ -116,6 +108,8 @@ fi if [[ "${parsed_cmds["SCOPE_ID"]}" == "" || "${parsed_cmds["REGISTRATION_ID"]}" == "" || "${parsed_cmds["SYMMETRIC_KEY"]}" == "" ]]; then echo Missing argument + echo defined: "'"${!parsed_cmds[@]}"'" + echo given: "'"${parsed_cmds[@]}"'" echo Usage exit 1 fi diff --git a/src/utils.sh b/src/utils.sh index 105a91c..dd95aa9 100644 --- a/src/utils.sh +++ b/src/utils.sh @@ -3,56 +3,101 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -VERSION_TAG="v0.0.0-rc0" +VERSION_TAG="v0.0.1" # create flag:variable_name dictionary declare -A flag_to_variable_dict -add_option_args() { +###################################### +# add_option_args +# +# declare a valid command-line argument(s) +# +# ARGUMENTS: +# OPTION_NAME The name of the argument (e.g "VERBOSE") +# a list of one or more argument switches (e.g "-v", "--verbose") +# OUTPUTS: +# Write output to stdout +# RETURN: +# +###################################### + +function add_option_args() { if [[ $# > 1 ]]; then - local option_flag=$1; shift - local var_name=$1; shift - flag_to_variable_dict[$option_flag]=$var_name + local option_name=$1; shift + while [ $# -ne 0 ]; + do + flag_to_variable_dict[$1]=$option_name + shift + done fi } -# generic command line parser -function cmd_parser() { - # create flag:variable_name dictionary - declare -A parsed_cmd +###################################### +# clear_option_args +# +# clears the list of valid command-line arguments +# +# ARGUMENTS: +# +# OUTPUTS: +# +# RETURN: +# +###################################### - for arg in "$@" +function clear_option_args() { + flag_to_variable_dict=() +} + +function cmd_parser() { + # create flag:variable_name dictionary and initialize to empty string + declare -A parsed_cmd + for key in ${!flag_to_variable_dict[*]}; do - if [[ $arg == -* ]]; + parsed_cmd[${flag_to_variable_dict[$key]}]="" + done + + while [ $# -ne 0 ]; + do + if [[ $1 == -* ]]; then - # iterate over all the keys in dictionary - local valid_arg="false" - for k in ${!flag_to_variable_dict[*]}; + local valid_argument=false + # for each key in the dictionary + for key in ${!flag_to_variable_dict[*]}; do - # if arg==key, then we store into flag_to_val_dict - if [ "$arg" == "$k" ]; - then - # set parsed_cmd, which is varname:value - parsed_cmd[${flag_to_variable_dict[$k]}]=$2 - valid_arg="true" + if [ "$1" == "$key" ] + then + valid_argument=true + if [[ $# == 1 || $2 == -* ]]; + then + parsed_cmd[${flag_to_variable_dict[$key]}]=true + else + parsed_cmd[${flag_to_variable_dict[$key]}]=$2 + shift + fi break fi done # found an unknown argument - if [[ "$valid_arg" == "false" ]]; + if [[ "$valid_argument" == "false" ]]; then parsed_cmd=() break fi + else + parsed_cmd=() + break fi - shift # Remove argument name from processing + + shift done # view content of entire dictionary echo '(' - for key in "${!parsed_cmd[@]}"; + for key in "${!parsed_cmd[@]}"; do echo "[$key]=${parsed_cmd[$key]}" done @@ -121,9 +166,7 @@ export -f log_init log_error log_info log_warn log_debug ###################################### # prepare_apt # -# installs Azure IoT Edge Runtime 1.2 -# generates the edge's configuration file from template and -# fills in the DPS provisioning section from provided parameters +# adds the needed microsoft sources list and key to the apt repository # # ARGUMENTS: # OS_PLATFORM - a string specifying the location of specific platform files diff --git a/tests/unit-tests/test-cmd-parser.sh b/tests/unit-tests/test-cmd-parser.sh index b372e17..aa67f17 100644 --- a/tests/unit-tests/test-cmd-parser.sh +++ b/tests/unit-tests/test-cmd-parser.sh @@ -1,40 +1,51 @@ -#!/usr/bin/env bash - -# import utils.sh -source ../../src/utils.sh - -# unit test to test all illegal flags, output should be empty -test_illegal_flags() { - # parse sample input to parser - declare -A parsed_cmds="$(cmd_parser -illegal val -t anotherillegalval -z yetanotherillegalval)" - - # compare output, should be empty - if [ "${parsed_cmds[*]}" != "" ]; then - echo "Failed to pass unit test 'test_illegal_flags' in test-cmd-parser.sh. Non-empty result: ${parsed_cmds[*]}" - fi -} - -test_all_legal_flags() { - # parse sample input to parser - declare -A parsed_cmds="$(cmd_parser -dp 1 -ap 5 -s 2 -r 4 -k 3 -v 6)" - - # compare output, should be 123456 - if [ "${parsed_cmds[*]}" != "1 2 3 4 5 6" ]; then - echo "Failed to pass unit test 'test_all_legal_flags' in test-cmd-parser.sh. Non-empty result: ${parsed_cmds[*]}" - fi -} - -test_extra_arguments() { - # parse sample input to parser - declare -A parsed_cmds="$(cmd_parser illegalinput 0 -ap 4 -s 1 -r 3 more -extra -k 2)" - - # compare output, should be 1 2 3 4 - if [ "${parsed_cmds[*]}" != "1 2 3 4" ]; then - echo "Failed to pass unit test 'test_extra_arguments' in test-cmd-parser.sh. Non-empty result: ${parsed_cmds[*]}" - fi -} - -# run all tests -test_illegal_flags -test_all_legal_flags -test_extra_arguments \ No newline at end of file +#!/usr/bin/env bash + +# import utils.sh +source ../../src/utils.sh + +# add flag:variable_name dictionary entries +add_option_args "VERBOSE_LOGGING" -v --verbose +add_option_args "SCOPE_ID" -s --scope-id +add_option_args "REGISTRATION_ID" -r --registration-id +add_option_args "SYMMETRIC_KEY" -k --symmetric-key +add_option_args "DEVICE_PROVISIONING" -dp +add_option_args "AZURE_CLOUD_ID" -ap + +# unit test to test all illegal flags, output should be empty +test_illegal_flags() { + # parse sample input to parser + declare -A parsed_cmds="$(cmd_parser -illegal val -t anotherillegalval -z yetanotherillegalval)" + + # compare output, should be empty + if [ "${parsed_cmds[*]}" != "" ]; + then + echo "Failed to pass unit test 'test_illegal_flags' in test-cmd-parser.sh. Non-empty result: ${parsed_cmds[*]}" + fi +} + +test_all_legal_flags() { + # parse sample input to parser + declare -A parsed_cmds="$(cmd_parser -dp 1 -ap 5 -s 2 -r 4 -k 3 -v 6)" + + # compare output, should be 123456 + if [[ "${parsed_cmds['DEVICE_PROVISIONING']}" != "1" || "${parsed_cmds['AZURE_CLOUD_ID']}" != "5" || "${parsed_cmds['SCOPE_ID']}" != "2" || "${parsed_cmds['REGISTRATION_ID']}" != "4" || "${parsed_cmds['SYMMETRIC_KEY']}" != "3" || "${parsed_cmds['VERBOSE_LOGGING']}" != "6" ]]; + then + echo "Failed to pass unit test 'test_all_legal_flags' in test-cmd-parser.sh. Non-empty result: ${parsed_cmds[*]}" + fi +} + +test_extra_arguments() { + # parse sample input to parser + declare -A parsed_cmds="$(cmd_parser illegalinput 0 -ap 4 -s 1 -r 3 more -extra -k 2)" + + # compare output, should be 1 2 3 4 + if [ "${parsed_cmds[*]}" != "" ]; + then + echo "Failed to pass unit test 'test_extra_arguments' in test-cmd-parser.sh" + fi +} + +# run all tests +test_illegal_flags +test_all_legal_flags +test_extra_arguments diff --git a/tests/unit-tests/test-install-container-management.sh b/tests/unit-tests/test-install-container-management.sh index 5f008fd..fa2fcac 100644 --- a/tests/unit-tests/test-install-container-management.sh +++ b/tests/unit-tests/test-install-container-management.sh @@ -1,2 +1,2 @@ -#script +#script echo "Running test-install-container-management.sh" \ No newline at end of file diff --git a/tests/unit-tests/test-install-edge-runtime.sh b/tests/unit-tests/test-install-edge-runtime.sh index 0571b68..472f327 100644 --- a/tests/unit-tests/test-install-edge-runtime.sh +++ b/tests/unit-tests/test-install-edge-runtime.sh @@ -1,2 +1,2 @@ -#script to install edge runtime 1.2 +#script to install edge runtime 1.2 echo "Running test-install-edge-runtime.sh" \ No newline at end of file diff --git a/tests/unit-tests/test-logger.sh b/tests/unit-tests/test-logger.sh index aea03e7..aa47e8e 100644 --- a/tests/unit-tests/test-logger.sh +++ b/tests/unit-tests/test-logger.sh @@ -1,45 +1,45 @@ -#!/usr/bin/env bash - -exec 3>&1 - -# bring in the utils library -source ../../src/utils.sh -source ../test_utils.sh - -log_init -assert_file $OUTPUT_FILE - -WC_L=`wc -l "$OUTPUT_FILE"` -WC=${WC_L% *} -assert_eq 0 $WC - -log_error "%s %d %.3f" one 2 12.3042 -log_error "two three" -WC_L=`wc -l "$OUTPUT_FILE"` -WC=${WC_L% *} -assert_eq 2 $WC - -log_warn "%s %d %.3f" one 2 12.3042 -log_warn "two three" -WC_L=`wc -l "$OUTPUT_FILE"` -WC=${WC_L% *} -assert_eq 4 $WC - -log_info "%s %d %.3f" one 2 12.3042 -log_info "two three" -WC_L=`wc -l "$OUTPUT_FILE"` -WC=${WC_L% *} -assert_eq 6 $WC - -STRVAL1="One" -INTVAL1=45 -FLOATVAL1=2453.56890 -log_info "---------------------------------------------" -log_info "'%s' ;" "$STRVAL1" -log_info "%.2f" $FLOATVAL1 -WC_L=`wc -l "$OUTPUT_FILE"` -WC=${WC_L% *} -assert_eq 9 $WC - -show_test_totals +#!/usr/bin/env bash + +exec 3>&1 + +# bring in the utils library +source ../../src/utils.sh +source ../test_utils.sh + +log_init +assert_file $OUTPUT_FILE + +WC_L=`wc -l "$OUTPUT_FILE"` +WC=${WC_L% *} +assert_eq 0 $WC + +log_error "%s %d %.3f" one 2 12.3042 +log_error "two three" +WC_L=`wc -l "$OUTPUT_FILE"` +WC=${WC_L% *} +assert_eq 2 $WC + +log_warn "%s %d %.3f" one 2 12.3042 +log_warn "two three" +WC_L=`wc -l "$OUTPUT_FILE"` +WC=${WC_L% *} +assert_eq 4 $WC + +log_info "%s %d %.3f" one 2 12.3042 +log_info "two three" +WC_L=`wc -l "$OUTPUT_FILE"` +WC=${WC_L% *} +assert_eq 6 $WC + +STRVAL1="One" +INTVAL1=45 +FLOATVAL1=2453.56890 +log_info "---------------------------------------------" +log_info "'%s' ;" "$STRVAL1" +log_info "%.2f" $FLOATVAL1 +WC_L=`wc -l "$OUTPUT_FILE"` +WC=${WC_L% *} +assert_eq 9 $WC + +show_test_totals rm $OUTPUT_FILE \ No newline at end of file diff --git a/tests/unit-tests/test-validate-post-install.sh b/tests/unit-tests/test-validate-post-install.sh index 16ab2a3..341a25e 100644 --- a/tests/unit-tests/test-validate-post-install.sh +++ b/tests/unit-tests/test-validate-post-install.sh @@ -1,36 +1,36 @@ -#!/usr/bin/env bash - -source src/validate-post-install.sh -source tests/test_utils.sh - -test_service_running() { - is_service_running "servicenameA" "servicenameA Running" - assert_eq 0 $? -} - -test_service_ready() { - is_service_running "servicenameA" "servicenameA Ready" - assert_eq 0 $? -} - -test_service_not_running() { - is_service_running "servicenameA" "servicenameA Failed" - assert_eq 1 $? -} - -test_service_missing() { - is_service_running "servicenameA" "servicenameB Running" - assert_eq 1 $? -} - -test_service_casesensitive() { - is_service_running "servicenameA" "servicenameA ruNNing" - assert_eq 0 $? -} - -# run tests -test_service_running -test_service_ready -test_service_not_running -test_service_missing +#!/usr/bin/env bash + +source src/validate-post-install.sh +source tests/test_utils.sh + +test_service_running() { + is_service_running "servicenameA" "servicenameA Running" + assert_eq 0 $? +} + +test_service_ready() { + is_service_running "servicenameA" "servicenameA Ready" + assert_eq 0 $? +} + +test_service_not_running() { + is_service_running "servicenameA" "servicenameA Failed" + assert_eq 1 $? +} + +test_service_missing() { + is_service_running "servicenameA" "servicenameB Running" + assert_eq 1 $? +} + +test_service_casesensitive() { + is_service_running "servicenameA" "servicenameA ruNNing" + assert_eq 0 $? +} + +# run tests +test_service_running +test_service_ready +test_service_not_running +test_service_missing test_service_casesensitive \ No newline at end of file