AT_BANNER([appctl bashcomp unit tests]) m4_define([GET_FORMAT], [ echo "$@" | grep -A 1 -- "Command format" | tail -n+2 ]) m4_define([GET_EXPAN], [ echo "$@" | grep -- "available completions for keyword" \ | sed -e 's/^[ ]*//g;s/[ ]*$//g' ]) m4_define([GET_AVAIL], [ echo "$@" | sed -e '1,/Available/d' | tail -n+2 ]) m4_define([GET_COMP_STR], [ echo "available completions for keyword \"$1\": $2" \ | sed -e 's/[ ]*$//g' ]) AT_SETUP([appctl-bashcomp - basic verification]) AT_SKIP_IF([test -z ${BASH_VERSION+x}]) OVS_VSWITCHD_START # complete ovs-appctl [TAB] # complete ovs-dpctl [TAB] # complete ovs-ofctl [TAB] # complete ovsdb-tool [TAB] m4_foreach( [test_command], [[ovs-appctl], [ovs-dpctl], [ovs-ofctl], [ovsdb-tool]], [ INPUT="$(bash ovs-appctl-bashcomp.bash debug test_command TAB 2>&1)" MATCH="$(test_command --option | sort | sed -n '/^--.*/p' | cut -d '=' -f1) $(test_command list-commands | tail -n +2 | cut -c3- | cut -d ' ' -f1 | sort)" AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0], [dnl ${MATCH} ])]) # complete ovs-appctl --tar[TAB] INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl --tar 2>&1)" AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0], [dnl --target ]) # complete ovs-appctl --target [TAB] INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl --target TAB 2>&1)" AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0], [dnl ovs-ofctl ovs-vswitchd ovsdb-server ]) # complete ovs-appctl --target ovs-vswitchd [TAB] # complete ovs-appctl --target ovsdb-server [TAB] # complete ovs-appctl --target ovs-ofctl [TAB] AT_CHECK([ovs-ofctl monitor br0 --detach --no-chdir --pidfile]) m4_foreach( [target_daemon], [[ovs-vswitchd], [ovsdb-server], [ovs-ofctl]], [ INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl --target target_daemon TAB 2>&1)" MATCH="$(ovs-appctl --option | sort | sed -n '/^--.*/p' | cut -d '=' -f1) $(ovs-appctl --target target_daemon list-commands | tail -n +2 | cut -c3- | cut -d ' ' -f1 | sort)" AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0], [dnl ${MATCH} ])]) OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) OVS_VSWITCHD_STOP AT_CLEANUP # complex completion check - bfd/set-forwarding # bfd/set-forwarding [interface] normal|false|true # test expansion of 'interface' AT_SETUP([appctl-bashcomp - complex completion check 1]) AT_SKIP_IF([test -z ${BASH_VERSION+x}]) OVS_VSWITCHD_START(add-port br0 p0 -- set Interface p0 type=dummy) # check the top level completion. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl bfd/set-forwarding TAB 2>&1)" MATCH="$(GET_COMP_STR([normal], []) GET_COMP_STR([false], []) GET_COMP_STR([true], []) GET_COMP_STR([interface], [p0]))" AT_CHECK_UNQUOTED([GET_EXPAN(${INPUT})], [0], [dnl ${MATCH} ]) # check the available completions. AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0], [dnl p0 ]) # set argument to 'true', there should be no more completions. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl bfd/set-forwarding true TAB 2>&1)" AT_CHECK_UNQUOTED([echo "$INPUT" | sed -e '/./,$!d'], [0], [dnl ]) # set argument to 'p1', there should still be the completion for booleans. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl bfd/set-forwarding p1 TAB 2>&1)" MATCH="$(GET_COMP_STR([normal], []) GET_COMP_STR([false], []) GET_COMP_STR([true], []))" AT_CHECK_UNQUOTED([GET_EXPAN(${INPUT})], [0], [dnl ${MATCH} ]) # check the available completions. AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0]) # set argument to 'p1 false', there should still no more completions. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl bfd/set-forwarding p1 false TAB 2>&1)" AT_CHECK_UNQUOTED([echo "$INPUT" | sed -e '/./,$!d'], [0], [dnl ]) OVS_VSWITCHD_STOP AT_CLEANUP # complex completion check - lacp/show # lacp/show [port] # test expansion on 'port' AT_SETUP([appctl-bashcomp - complex completion check 2]) AT_SKIP_IF([test -z ${BASH_VERSION+x}]) OVS_VSWITCHD_START(add-port br0 p0 -- set Interface p0 type=dummy \ -- add-port br0 p1 -- set Interface p1 type=dummy) # check the top level completion. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl lacp/show TAB 2>&1)" MATCH="$(GET_COMP_STR([port], [br0 p0 p1]))" AT_CHECK_UNQUOTED([GET_EXPAN(${INPUT})], [0], [dnl ${MATCH} ]) # check the available completions. AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0], [dnl br0 p0 p1 ]) # set argument to 'p1', there should be no more completions. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl lacp/show p1 TAB 2>&1)" AT_CHECK_UNQUOTED([echo "$INPUT" | sed -e '/./,$!d'], [0], [dnl ]) OVS_VSWITCHD_STOP AT_CLEANUP # complex completion check - ofproto/trace # ofproto/trace {[dp_name] odp_flow | bridge br_flow} [OPTIONS] [-generate|packet] # test expansion on 'dp|dp_name' and 'bridge' AT_SETUP([appctl-bashcomp - complex completion check 3]) AT_SKIP_IF([test -z ${BASH_VERSION+x}]) OVS_VSWITCHD_START(add-port br0 p0 -- set Interface p0 type=dummy \ -- add-port br0 p1 -- set Interface p1 type=dummy) # check the top level completion. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl ofproto/trace TAB 2>&1)" MATCH="$(GET_COMP_STR([bridge], [br0]) GET_COMP_STR([odp_flow], []) GET_COMP_STR([dp_name], [ovs-dummy]))" AT_CHECK_UNQUOTED([GET_EXPAN(${INPUT})], [0], [dnl ${MATCH} ]) # check the available completions. AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0], [dnl br0 ovs-dummy ]) # set argument to 'ovs-dummy', should go to the dp-name path. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl ofproto/trace ovs-dummy TAB 2>&1)" MATCH="$(GET_COMP_STR([odp_flow], []))" AT_CHECK_UNQUOTED([GET_EXPAN(${INPUT})], [0], [dnl ${MATCH} ]) # check the available completions. AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0]) # set odp_flow to some random string, should go to the next level. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl ofproto/trace ovs-dummy "in_port(123),mac(),ip,tcp" TAB 2>&1)" MATCH="$(GET_COMP_STR([-generate], [-generate]) GET_COMP_STR([packet], []) GET_COMP_STR([OPTIONS...], []))" AT_CHECK_UNQUOTED([GET_EXPAN(${INPUT})], [0], [dnl ${MATCH} ]) # check the available completions. AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0], [dnl -generate ]) # set packet to some random string, there should be no more completions. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl ofproto/trace ovs-dummy "in_port(123),mac(),ip,tcp" "ABSJDFLSDJFOIWEQR" TAB 2>&1)" AT_CHECK_UNQUOTED([echo "$INPUT" | sed -e '/./,$!d'], [0], [dnl ]) # set argument to 'br0', should go to the bridge path. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl ofproto/trace br0 TAB 2>&1)" MATCH="$(GET_COMP_STR([br_flow], []))" AT_CHECK_UNQUOTED([GET_EXPAN(${INPUT})], [0], [dnl ${MATCH} ]) # check the available completions. AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0]) # set argument to some random string, should go to the odp_flow path. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl ofproto/trace "in_port(123),mac(),ip,tcp" TAB 2>&1)" MATCH="$(GET_COMP_STR([-generate], [-generate]) GET_COMP_STR([packet], []) GET_COMP_STR([OPTIONS...], []))" AT_CHECK_UNQUOTED([GET_EXPAN(${INPUT})], [0], [dnl ${MATCH} ]) # check the available completions. AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0], [dnl -generate ]) OVS_VSWITCHD_STOP AT_CLEANUP # complex completion check - vlog/set # vlog/set {spec | PATTERN:destination:pattern} # test non expandable arguments AT_SETUP([appctl-bashcomp - complex completion check 4]) AT_SKIP_IF([test -z ${BASH_VERSION+x}]) OVS_VSWITCHD_START # check the top level completion. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl vlog/set TAB 2>&1)" MATCH="$(GET_COMP_STR([PATTERN:destination:pattern], []) GET_COMP_STR([spec], []))" AT_CHECK_UNQUOTED([GET_EXPAN(${INPUT})], [0], [dnl ${MATCH} ]) # check the available completions. AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0]) # set argument to random 'abcd', there should be no more completions. INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl vlog/set abcd TAB 2>&1)" AT_CHECK_UNQUOTED([echo "$INPUT" | sed -e '/./,$!d'], [0], [dnl ]) OVS_VSWITCHD_STOP AT_CLEANUP AT_SETUP([appctl-bashcomp - negative test]) AT_SKIP_IF([test -z ${BASH_VERSION+x}]) OVS_VSWITCHD_START(add-port br0 p0 -- set Interface p0 type=dummy) # negative test - incorrect subcommand INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl ERROR 2>&1)" AT_CHECK_UNQUOTED([echo "$INPUT" | sed -e 's/[ \t]*$//' | sed -e '/./,$!d'], [0]) INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl ERROR TAB 2>&1)" AT_CHECK_UNQUOTED([echo "$INPUT" | sed -e 's/[ \t]*$//' | sed -e '/./!d'], [0], [dnl ]) # negative test - no ovs-vswitchd # negative test - no ovsdb-server # negative test - no ovs-ofctl # should not see any error. OVS_VSWITCHD_STOP m4_foreach( [target_daemon], [[ovs-vswitchd], [ovsdb-server], [ovs-ofctl]], [ INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl --target target_daemon TAB 2>&1)" MATCH="$(ovs-appctl --option | sort | sed -n '/^--.*/p' | cut -d '=' -f1)" AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0], [dnl ${MATCH} ]) INPUT="$(bash ovs-appctl-bashcomp.bash debug ovs-appctl --target target_daemon ERROR SUBCMD TAB 2>&1)" AT_CHECK_UNQUOTED([echo "$INPUT" | sed -e 's/[ \t]*$//' | sed -e '/./!d'], [0], [dnl ])]) # negative test - do not match on nested option INPUT="$(bash ovs-appctl-bashcomp.bash debug ovsdb-tool create TAB 2>&1)" AT_CHECK_UNQUOTED([GET_AVAIL(${INPUT})], [0]) AT_CLEANUP dnl ---------------------------------------------------------------------- AT_BANNER([vsctl bashcomp unit tests]) m4_define([PREPARE_MATCH_NOSPACE], [ echo "$@" | tr ' ' '\n' | sed -e '/^$/d' | sort -u ]) m4_define([PREPARE_MATCH_SPACE], [ echo "$@" | tr ' ' '\n' | sed -e '/^$/d' | sed -e 's/$/ /g' | sort -u ]) AT_SETUP([vsctl-bashcomp - basic verification]) AT_SKIP_IF([test -z ${BASH_VERSION+x}]) AT_SKIP_IF([eval 'test ${BASH_VERSINFO[[0]]} -lt 4']) OVS_VSWITCHD_START # complete ovs-vsctl --db=* [TAB] TMP="$(ovs-vsctl --commands | cut -d',' -f1-2 | tr -d ',[[]]' | tr -s ' ' '\n') $(ovs-vsctl --options | grep -- '--' | sed -e 's/=.*$/=/g')" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "--db=unix:$OVS_RUNDIR/db.sock "], [0], [dnl ${MATCH} ]) # complete ovs-vsctl [TAB] AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test ""], [0], [dnl ${MATCH} ]) # complete on global options. AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "--dry-run "], [0], [dnl ${MATCH} ]) AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "--dry-run --pretty "], [0], [dnl ${MATCH} ]) # complete on local options. TMP="$(ovs-vsctl --commands | grep -- '--may-exist' | cut -d',' -f1-2 | tr -d ',[[]]' | tr -s ' ' '\n' | grep -v -- '--may-exist')" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "--may-exist "], [0], [dnl ${MATCH} ]) # # test !, +, ?, *. # # test !. no following arguments are expanded. TMP="$(ovsdb-client --no-heading list-tables)" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set "], [0], [dnl ${MATCH} ]) # test ?. will show completions for both current and following arguments. ovs-vsctl br-set-external-id br0 bridge-id br0 MATCH="$(PREPARE_MATCH_SPACE(bridge-id --))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "br-get-external-id br0 "], [0], [dnl ${MATCH} ]) # test *. argument with this prefix could be completed for zero or more times. TMP="$(ovs-vsctl --no-heading --columns=_uuid,name list Bridge | tr -d '\"')" MATCH="$(PREPARE_MATCH_SPACE(${TMP} --))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "destroy Bridge "], [0], [dnl ${MATCH} ]) AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "destroy Bridge br0 "], [0], [dnl ${MATCH} ]) # test +. the first time, an argument is required, after that, it becomes '*'. TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Bridge | awk '/key.*value/ { print $1":"; next } { print $1; next }')" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set Bridge br0 "], [0], [dnl ${MATCH} ]) MATCH="$(PREPARE_MATCH_NOSPACE(${TMP} --))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set Bridge br0 other_config:random_key=123 "], [0], [dnl ${MATCH} ]) OVS_VSWITCHD_STOP AT_CLEANUP AT_SETUP([vsctl-bashcomp - argument completion]) AT_SKIP_IF([test -z ${BASH_VERSION+x}]) AT_SKIP_IF([eval 'test ${BASH_VERSINFO[[0]]} -lt 4']) OVS_VSWITCHD_START( [add-br br1 -- \ set bridge br1 datapath-type=dummy -- \ add-br foo -- \ set bridge foo datapath-type=dummy -- \ add-br --weird-br_name -- \ set bridge --weird-br_name datapath-type=dummy -- \ add-port br0 br0p0 -- set Interface br0p0 type=dummy -- \ add-port br0 br0p1 -- set Interface br0p1 type=dummy -- \ add-port br1 br1p0 -- set Interface br1p0 type=dummy -- \ add-port br1 br1p1 -- set Interface br1p1 type=dummy -- \ add-port foo bar -- set Interface bar type=dummy ]) # # test completion functions defined in '_OVS_VSCTL_ARG_COMPLETION_FUNCS'. # therein, the different argument prefixes are also tested at the same time. # # A space is appended to each output if completion is configured without # 'nospace' option. # # # test: _ovs_vsctl_complete_table # TMP="$(ovsdb-client --no-heading list-tables)" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set "], [0], [dnl ${MATCH} ]) MATCH="$(PREPARE_MATCH_SPACE(Open_vSwitch))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set Open"], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_record # TMP="$(ovs-vsctl --no-heading --columns=_uuid list Open_vSwitch | tr -d '\"')" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set Open_vSwitch "], [0], [dnl ${MATCH} ]) TMP="$(ovs-vsctl --no-heading --columns=_uuid,name list Bridge | tr -d '\"')" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set Bridge "], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_bridge # TMP="$(ovs-vsctl list-br)" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "br-to-vlan "], [0], [dnl ${MATCH} ]) # this also helps check the '_ovs_vsctl_check_startswith_string'. MATCH="$(PREPARE_MATCH_SPACE(--weird-br_name))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "br-to-vlan --"], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_port # TMP="$(ovs-vsctl --no-heading --columns=name list Port | tr -d '\"')" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "port-to-br "], [0], [dnl ${MATCH} ]) # complete on ports in particular bridge. TMP="$(ovs-vsctl list-ports br0)" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "del-port br0 "], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_iface # for br in `ovs-vsctl list-br`; do TMP="${TMP} $(ovs-vsctl list-ifaces $br)" done MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "iface-to-br "], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_bridge_fail_mode # MATCH="$(PREPARE_MATCH_SPACE(standalone secure))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set-fail-mode br0 "], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_key # AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "br-set-external-id br0 "], [0], [dnl ]) # since there is no key added yet, we will only get our own input. MATCH="$(PREPARE_MATCH_SPACE(test_key))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "br-set-external-id br0 test_key"], [0], [dnl ${MATCH} ]) # now add a key, as we should see it. ovs-vsctl br-set-external-id br0 bridge-id br0 MATCH="$(PREPARE_MATCH_SPACE(bridge-id))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "br-set-external-id br0 "], [0], [dnl ${MATCH} ]) MATCH="$(PREPARE_MATCH_SPACE(bridge-id --))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "br-get-external-id br0 "], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_value # # should just return the user input. MATCH="$(PREPARE_MATCH_SPACE(test_value --))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "br-set-external-id br0 bridge-id test_value"], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_column # TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Open_vSwitch | tr -d ':' | cut -d' ' -f1)" UUID="$(ovs-vsctl --no-heading --columns=_uuid list Open_vSwitch | tr -d ' ')" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "clear Open_vSwitch $UUID "], [0], [dnl ${MATCH} ]) TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Bridge | tr -d ':' | cut -d' ' -f1)" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "clear Bridge br0 "], [0], [dnl ${MATCH} ]) # the 'clear' command requires one or more (+) COLUMN. # so, with one specified COLUMN 'other_config', it should still complete on # COLUMNs, plus '--'. MATCH="$(PREPARE_MATCH_SPACE(${TMP} --))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "clear Bridge br0 other_config "], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_key_value # # with no key available, should always get user input. MATCH="$(PREPARE_MATCH_NOSPACE(random_key))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "add Bridge br0 other_config random_key"], [0], [dnl ${MATCH} ]) MATCH="$(PREPARE_MATCH_NOSPACE(abc))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "add Bridge br0 other_config random_key=abc"], [0], [dnl ${MATCH} ]) # now add two random keys. ovs-vsctl set Bridge br0 other_config:random_key1=abc other_config:random_val1=xyz MATCH="$(PREPARE_MATCH_NOSPACE(random_key1= random_val1=))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "add Bridge br0 other_config ran"], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_column_optkey_value # # at first, we should complete on column. TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Bridge | awk '/key.*value/ { print $1":"; next } { print $1; next }')" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set Bridge br0 "], [0], [dnl ${MATCH} ]) MATCH="$(PREPARE_MATCH_NOSPACE(other_config:))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set Bridge br0 other"], [0], [dnl ${MATCH} ]) # then, with the ':' we should complete on key. TMP="$(ovs-vsctl --no-heading --columns=other_config list Bridge br0 | tr -d '{\"}' | tr -s ', ' '\n' | cut -d'=' -f1)" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set Bridge br0 other_config:"], [0], [dnl ${MATCH} ]) # finally, if user fill in some value, we should just complete on user input. MATCH="$(PREPARE_MATCH_NOSPACE(random_val1))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set Bridge br0 other_config:random_val1=12345"], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_filename # touch private_key certificate MATCH="$(PREPARE_MATCH_SPACE(private_key))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set-ssl priva"], [0], [dnl ${MATCH} ]) MATCH="$(PREPARE_MATCH_SPACE(certificate))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set-ssl private_key cer"], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_target # MATCH="$(PREPARE_MATCH_NOSPACE(pssl: ptcp: punix: ssl: tcp: unix:))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set-manager "], [0], [dnl ${MATCH} ]) # filename completion on unix, punix. MATCH="$(PREPARE_MATCH_NOSPACE(testsuite.log))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set-manager unix:test"], [0], [dnl ${MATCH} ]) # no completion on other type, just return available types. # in real environment, bash will not complete on anything. MATCH="$(PREPARE_MATCH_NOSPACE(pssl: ptcp: punix: tcp: unix:))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set-manager ssl:something"], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_new # # test 'add-br' AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "add-br "], [0], [dnl --- BEGIN MESSAGE Enter a new bridge: > ovs-vsctl add-br --- END MESSAGE ]) # user input does not change the output. AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "add-br new-br"], [0], [dnl --- BEGIN MESSAGE Enter a new bridge: > ovs-vsctl add-br new-br--- END MESSAGE ]) # after specifying the new bridge name, we should complete on parent bridge. TMP="$(ovs-vsctl list-br)" MATCH="$(PREPARE_MATCH_SPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "add-br new-br "], [0], [dnl ${MATCH} ]) # test 'add-port' # after specifying the new port name, we should complete on the column part # of '*COLUMN?:KEY=VALUE'. TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Port | awk '/key.*value/ { print $1":"; next } { print $1; next }')" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP} --))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "add-port br0 new-port "], [0], [dnl ${MATCH} ]) # # test: _ovs_vsctl_complete_dashdash # # after '--', there should be no global options available for completion. TMP="$(ovs-vsctl --commands | cut -d',' -f1-2 | tr -d ',[[]]' | tr -s ' ' '\n')" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP}))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "init -- "], [0], [dnl ${MATCH} ]) TMP="$(ovs-vsctl --no-heading --columns=name,_uuid list Port | tr -d '\"')" MATCH="$(PREPARE_MATCH_SPACE(${TMP} newp1 newp2))" AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "add-port br0 newp1 -- add-port br1 newp2 -- set Port "], [0], [dnl ${MATCH} ]) OVS_VSWITCHD_STOP AT_CLEANUP AT_SETUP([vsctl-bashcomp - negative test]) AT_SKIP_IF([test -z ${BASH_VERSION+x}]) AT_SKIP_IF([eval 'test ${BASH_VERSINFO[[0]]} -lt 4']) OVS_VSWITCHD_START # complete non-matching command. AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "invalid"], [0], [dnl ]) # complete after invalid command. AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "invalid argu"], [0], [dnl ]) # complete non-matching end argument. AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set INVALID_"], [0], [dnl ]) # complete after invalid intermediate argument. AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "set INVALID_TBL "], [1], [dnl --- BEGIN MESSAGE Cannot complete 'INVALID_TBL' at index 3: > ovs-vsctl set INVALID_TBL --- END MESSAGE]) # complete ovs-vsctl --db=wrongdb [TAB] # should return 1 and show nothing. AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test "--db=wrongdb"], [1], []) OVS_VSWITCHD_STOP # delete ovsdb-server and try again. AT_CHECK_UNQUOTED([bash ovs-vsctl-bashcomp.bash test ""], [1], []) AT_CLEANUP