#!/bin/bash # # Tests for the ovs-command-compgen.bash # # Please run this with ovs-command-compgen.bash script inside # ovs-sandbox, under the same directory. # # For information about running the ovs-sandbox, please refer to # the tutorial directory. # # # COMP_OUTPUT= TMP= EXPECT= TEST_RESULT= TEST_COUNTER=0 TEST_COMMANDS=(ovs-appctl ovs-ofctl ovs-dpctl ovsdb-tool) TEST_APPCTL_TARGETS=(ovs-vswitchd ovsdb-server ovs-ofctl) # # Helper functions. # get_command_format() { local input="$@" echo "$(grep -A 1 "Command format" <<< "$input" | tail -n+2)" } get_argument_expansion() { local input="$@" echo "$(grep -- "available completions for keyword" <<< "$input" | sed -e 's/^[ \t]*//')" } get_available_completions() { local input="$@" echo "$(sed -e '1,/Available/d' <<< "$input" | tail -n+2)" } generate_expect_completions() { local keyword="$1" local completions="$2" echo "available completions for keyword \"$keyword\": $completions" \ | sed -e 's/[ \t]*$//' } reset_globals() { COMP_OUTPUT= TMP= EXPECT= TEST_RESULT= } # # $1: Test name. # $2: ok or fail. # print_result() { (( TEST_COUNTER++ )) printf "%2d: %-70s %s\n" "$TEST_COUNTER" "$1" "$2" } # # $1: test stage # $2: actual # $3: expect # print_error() { local stage="$1" local actual="$2" local expect="$3" printf "failed at stage_%s:\n" "$stage" printf "actual output: %s\n" "$actual" printf "expect output: %s\n" "$expect" } # # Sub-tests. # ovs_apptcl_TAB() { local target="$1" local target_line= local comp_output tmp expect if [ -n "$target" ]; then target_line="--target $target" fi comp_output="$(bash ovs-command-compgen.bash debug ovs-appctl $target_line TAB 2>&1)" tmp="$(get_available_completions "$comp_output")" expect="$(ovs-appctl --option | sort | sed -n '/^--.*/p' | cut -d '=' -f1) $(ovs-appctl $target_line list-commands | tail -n +2 | cut -c3- | cut -d ' ' -f1 | sort)" if [ "$tmp" = "$expect" ]; then echo "ok" else echo "fail" fi } # # Test preparation. # ovs-vsctl add-br br0 ovs-vsctl add-port br0 p1 # # Begin the test. # cat <&1)" TMP="$(get_argument_expansion "$COMP_OUTPUT" | sed -e 's/[ \t]*$//')" EXPECT="$(generate_expect_completions "-generate" "-generate") $(generate_expect_completions "packet" "")" if [ "$TMP" != "$EXPECT" ]; then print_error "5" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # check the available completions. TMP="$(get_available_completions "$COMP_OUTPUT" | tr '\n' ' ' | sed -e 's/[ \t]*$//')" EXPECT="-generate" if [ "$TMP" != "$EXPECT" ]; then print_error "6" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # set packet to some random string, there should be no more completions. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl ofproto/trace ovs-system "in_port(123),mac(),ip,tcp" "ABSJDFLSDJFOIWEQR" TAB 2>&1)" TMP="$(sed -e '/./,$!d' <<< "$COMP_OUTPUT")" EXPECT="Command format: ofproto/trace {[dp_name] odp_flow | bridge br_flow} [-generate|packet]" if [ "$TMP" != "$EXPECT" ]; then print_error "7" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # set argument to 'br0', should go to the bridge path. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl ofproto/trace br0 TAB 2>&1)" TMP="$(get_argument_expansion "$COMP_OUTPUT" | sed -e 's/[ \t]*$//')" EXPECT="$(generate_expect_completions "br_flow" "")" if [ "$TMP" != "$EXPECT" ]; then print_error "8" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # check the available completions. TMP="$(get_available_completions "$COMP_OUTPUT" | tr '\n' ' ' | sed -e 's/[ \t]*$//')" EXPECT= if [ "$TMP" != "$EXPECT" ]; then print_error "9" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # set argument to some random string, should go to the odp_flow path. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl ofproto/trace "in_port(123),mac(),ip,tcp" TAB 2>&1)" TMP="$(get_argument_expansion "$COMP_OUTPUT" | sed -e 's/[ \t]*$//')" EXPECT="$(generate_expect_completions "-generate" "-generate") $(generate_expect_completions "packet" "")" if [ "$TMP" != "$EXPECT" ]; then print_error "10" "$TMP" "$EXPEC"T TEST_RESULT=fail break fi # check the available completions. TMP="$(get_available_completions "$COMP_OUTPUT" | tr '\n' ' ' | sed -e 's/[ \t]*$//')" EXPECT="-generate" if [ "$TMP" != "$EXPECT" ]; then print_error "11" "$TMP" "$EXPECT" TEST_RESULT=fail break fi TEST_RESULT=ok done print_result "complex completion check - ofproto/trace" "$TEST_RESULT" # complex completion check - vlog/set # vlog/set {spec | PATTERN:facility:pattern} # test non expandable arguments reset_globals for i in loop_once; do # check the top level completion. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl vlog/set TAB 2>&1)" TMP="$(get_argument_expansion "$COMP_OUTPUT" | sed -e 's/[ \t]*$//')" EXPECT="$(generate_expect_completions "PATTERN:facility:pattern" "") $(generate_expect_completions "spec" "")" if [ "$TMP" != "$EXPECT" ]; then print_error "1" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # check the available completions. TMP="$(get_available_completions "$COMP_OUTPUT" | tr '\n' ' ' | sed -e 's/[ \t]*$//')" EXPECT= if [ "$TMP" != "$EXPECT" ]; then print_error "2" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # set argument to random 'abcd', there should be no more completions. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl vlog/set abcd TAB 2>&1)" TMP="$(sed -e '/./,$!d' <<< "$COMP_OUTPUT")" EXPECT="Command format: vlog/set {spec | PATTERN:facility:pattern}" if [ "$TMP" != "$EXPECT" ]; then print_error "3" "$TMP" "$EXPECT" TEST_RESULT=fail break fi TEST_RESULT=ok done print_result "complex completion check - vlog/set" "$TEST_RESULT" # complete after delete port reset_globals ovs-vsctl del-port p1 for i in loop_once; do # check match on interface, there should be no available interface expansion. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl bfd/set-forwarding TAB 2>&1)" TMP="$(get_argument_expansion "$COMP_OUTPUT" | sed -e 's/[ \t]*$//')" EXPECT="$(generate_expect_completions "normal" "") $(generate_expect_completions "false" "") $(generate_expect_completions "true" "") $(generate_expect_completions "interface" "")" if [ "$TMP" != "$EXPECT" ]; then print_error "1" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # check the available completions. TMP="$(get_available_completions "$COMP_OUTPUT" | tr '\n' ' ' | sed -e 's/[ \t]*$//')" EXPECT= if [ "$TMP" != "$EXPECT" ]; then print_error "2" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # check match on port, there should be no p1 as port. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl lacp/show TAB 2>&1)" TMP="$(get_argument_expansion "$COMP_OUTPUT" | sed -e 's/[ \t]*$//')" EXPECT="$(generate_expect_completions "port" "br0")" if [ "$TMP" != "$EXPECT" ]; then print_error "3" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # check the available completions. TMP="$(get_available_completions "$COMP_OUTPUT" | tr '\n' ' ' | sed -e 's/[ \t]*$//')" EXPECT="br0" if [ "$TMP" != "$EXPECT" ]; then print_error "4" "$TMP" "$EXPECT" TEST_RESULT=fail break fi TEST_RESULT=ok done print_result "complete after delete port" "$TEST_RESULT" # complete after delete bridge reset_globals ovs-vsctl del-br br0 for i in loop_once; do # check match on port, there should be no p1 as port. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl bridge/dump-flows TAB 2>&1)" TMP="$(get_argument_expansion "$COMP_OUTPUT" | sed -e 's/[ \t]*$//')" EXPECT="$(generate_expect_completions "bridge" "")" if [ "$TMP" != "$EXPECT" ]; then print_error "1" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # check the available completions. TMP="$(get_available_completions "$COMP_OUTPUT" | tr '\n' ' ' | sed -e 's/[ \t]*$//')" EXPECT= if [ "$TMP" != "$EXPECT" ]; then print_error "2" "$TMP" "$EXPECT" TEST_RESULT=fail break fi # check 'ovs-ofctl monitor [misslen] [invalid_ttl] [watch:[...]]', should # not show any available completion. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-ofctl monitor non_exist_br TAB 2>&1)" TMP="$(get_argument_expansion "$COMP_OUTPUT" | sed -e 's/[ \t]*$//')" EXPECT= if [ "$TMP" != "$EXPECT" ]; then print_error "3" "$TMP" "$EXPECT" TEST_RESULT=fail break fi TEST_RESULT=ok done print_result "complete after delete bridge" "$TEST_RESULT" # negative test - incorrect subcommand reset_globals for i in loop_once; do # incorrect subcommand COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl ERROR 2>&1)" TMP="$(echo "$COMP_OUTPUT" | sed -e 's/[ \t]*$//' | sed -e '/./,$!d')" EXPECT= if [ "$TMP" != "$EXPECT" ]; then print_error "1" "$TMP" "$EXPECT" TEST_RESULT=fail break fi COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl ERROR TAB 2>&1)" TMP="$(echo "$COMP_OUTPUT" | sed -e 's/[ \t]*$//' | sed -e '/./!d')" EXPECT="Command format:" if [ "$TMP" != "$EXPECT" ]; then print_error "2" "$TMP" "$EXPECT" TEST_RESULT=fail break fi TEST_RESULT=ok done print_result "negative test - incorrect subcommand" "$TEST_RESULT" # negative test - no ovs-vswitchd # negative test - no ovsdb-server # negative test - no ovs-ofctl # should not see any error. reset_globals killall ovs-vswitchd ovsdb-server for i in ${TEST_APPCTL_TARGETS[@]}; do for j in loop_once; do reset_globals daemon="$i" # should show no avaiable subcommands. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl --target $daemon TAB 2>&1)" TMP="$(get_available_completions "$COMP_OUTPUT")" EXPECT="$(ovs-appctl --option | sort | sed -n '/^--.*/p' | cut -d '=' -f1)" if [ "$TMP" != "$EXPECT" ]; then TEST_RESULT=fail break fi # should not match any input. COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovs-appctl --target $daemon ERROR SUBCMD TAB 2>&1)" TMP="$(echo "$COMP_OUTPUT" | sed -e 's/[ \t]*$//' | sed -e '/./!d')" EXPECT="Command format:" if [ "$TMP" != "$EXPECT" ]; then TEST_RESULT=fail break fi TEST_RESULT=ok done print_result "negative test - no $daemon" "$TEST_RESULT" done # negative test - do not match on nested option reset_globals for i in loop_once; do COMP_OUTPUT="$(bash ovs-command-compgen.bash debug ovsdb-tool create TAB 2>&1)" TMP="$(get_available_completions "$COMP_OUTPUT")" EXPECT= if [ "$TMP" != "$EXPECT" ]; then TEST_RESULT=fail break fi TEST_RESULT=ok done print_result "negative test - do not match on nested option" "$TEST_RESULT"