aboutgitcodebugslistschat
path: root/test/lib/test
blob: df321785941529e523506b4a0dcf851f2f5ed7df (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15














                                                                           

                                                        

                                  


                                                        
                            
                      
               
                           

                            
                            

                                      
                            
 
                                                                         




                                                                         
 

                                                     
                                                                         


                                                                         
                                                                         



                                                                         

                             
                                                                            


                                                                            
 
                                                  
                             

                                                                                   
            
 


                                                                         
                                                                        

                                                                                     

                                                          

 


                     

                                                     


























                                                                                                                               









                                                                
                                                                     

                  
                                                      

                  
                                                           




                                                    
                                                                                           

                  
                                                                      

                  
                                                       

                  
                                                            
                  


                                                     

                                        

                                                                                                    

                  
                                                                      

                  
                                                       

                  
                                                            

                  
                                                                        

                  
                                                         

                  
                                                              

                  
                                                                                            

                  
                                                                                              

                  
                                                                                              

                  
                                                                        

                  
                                                         

                  
                                                              

                  
                                                                   
                  
              
                                                                    

                  
                                                                    
                  
              
                                                    
                  
               
                                                     

                  
                                                     
                  
              
                                                         
                  
               
                                                          

                  
                                                          
                  
                  
                                                                                         


                                        

                                                                                                    


                                        

                                                                                                    


                                        

                                                                                                    


                                        

                                                                                                    


                                        

                                                                                                    
                  

                                        

                                                                                                    


                                        

                                                                                                    
                  































                                           


                                                           





                                                                      

                                    























                                                                                                    


                                    






                                                                     
                                                                            






                                      


                                                           
                          








                                                                      



                                                                            


                                            
                                                                        



                                                                                            



                           
                                     

                                                   

                               
                                           




                                   


                                                                       


                                                                      
                                            

               

               
                   




                                                                 
                                                         






                                 
#!/bin/sh
#
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# PASST - Plug A Simple Socket Transport
#  for qemu/UNIX domain socket mode
#
# PASTA - Pack A Subtle Tap Abstraction
#  for network namespace/tap device mode
#
# test/lib/test - List tests and run them, evaluating directives from files
#
# Copyright (c) 2021 Red Hat GmbH
# Author: Stefano Brivio <sbrivio@redhat.com>

# test_iperf3() - Ugly helper for iperf3 directive
# $1:	Variable name: to put the measure bandwidth into
# $2:	Source/client context
# $3:	Destination/server context
# $4:	Destination name or address for client
# $5:	Port number, ${i} is translated to process index
# $6:	Number of processes to run in parallel
# $7:	Run time, in seconds
# $@:	Client options
test_iperf3() {
	__var="${1}"; shift
	__cctx="${1}"; shift
	__sctx="${1}"; shift
	__dest="${1}"; shift
	__port="${1}"; shift
	__procs="$((${1} - 1))"; shift
	__time="${1}"; shift

	pane_or_context_run_bg "${__sctx}" 				\
		 'for i in $(seq 0 '${__procs}'); do'			\
		 '	(iperf3 -s1J -p'${__port}' -i'${__time}		\
		 '	 > s${i}.json) &'				\
		 '	echo $! > s${i}.pid &'				\
		 'done'							\

	sleep 1		# Wait for server to be ready

	pane_or_context_run_bg "${__cctx}" 				\
		 '('							\
		 '	for i in $(seq 0 '${__procs}'); do'		\
		 '		iperf3 -c '${__dest}' -p '${__port}	\
		 '		 -t'${__time}' -i0 -T s${i} '"${@}"' &' \
		 '	done;'						\
		 '	wait'						\
		 ')'

	sleep $((__time + 5))

	# If client fails to deliver control message, tell server we're done
	pane_or_context_run "${__sctx}" 'kill -INT $(cat s*.pid); rm s*.pid'

	sleep 1		# ...and wait for output to be flushed

	__jval=".end.sum_received.bits_per_second"
	for __opt in ${@}; do
		# UDP test
		[ "${__opt}" = "-u" ] && __jval=".intervals[0].sum.bits_per_second"
	done

	__bw=$(pane_or_context_output "${__sctx}"			\
		 'cat s*.json | jq -rMs "map('${__jval}') | add"')
	pane_or_context_run "${__sctx}"					\
		'for i in $(seq 0 '${__procs}'); do rm s${i}.json; done'

	TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__var}__" "${__bw}" )"

	sleep 3		# Wait for kernel to free up ports
}

test_one_line() {
	__line="${1}"

	[ ${DEBUG} -eq 1 ] && info DEBUG: "${__line}"

	# Strip comments
	__line="${__line%%#*}"

	if [ -n "${TEST_ONE_in_def}" ]; then
		[ "${__line}" = "endef" ] && TEST_ONE_in_def= && return
		# Append $__line to variable TEST_ONE_DEF_<definition name>
		__ifs="${IFS}"
		IFS=
		eval TEST_ONE_DEF_$TEST_ONE_in_def=\"\$\(printf \"%s\\n%s\" \"\$TEST_ONE_DEF_$TEST_ONE_in_def\" \"$__line\"\)\"
		IFS="${__ifs}"
		return
	fi

	# tab-split command and arguments, apply variable substitutions
	__cmd="${__line%%$(printf '\t')*}"
	__arg="${__line#*$(printf '\t')*}"
	__arg="$(subs_apply "${TEST_ONE_subs}" "${__arg}")"

	[ ${TEST_ONE_nok} -eq 1 ] && [ "${__cmd}" != "test" ] && continue
	case ${__cmd} in
	"def")
		TEST_ONE_in_def="${__arg}"
		# Clear variable TEST_ONE_DEF_<definition name>
		__ifs="${IFS}"
		IFS= eval TEST_ONE_DEF_$TEST_ONE_in_def=
		IFS="${__ifs}"
		;;
	"test")
		[ ${TEST_ONE_perf_nok} -eq 0 ] || TEST_ONE_nok=1
		[ ${TEST_ONE_nok} -eq 1 ] && status_test_fail
		[ ${TEST_ONE_nok} -eq 0 ] && status_test_ok

		status_test_start "${__arg}"
		TEST_ONE_nok=0
		TEST_ONE_perf_nok=0
		;;
	"host")
		pane_or_context_run host "${__arg}" || TEST_ONE_nok=1
		;;
	"hostb")
		pane_or_context_run_bg host "${__arg}"
		;;
	"hostw")
		pane_or_context_wait host || TEST_ONE_nok=1
		;;
	"hint")
		tmux send-keys -t ${PANE_HOST} "C-c"
		;;
	"htools")
		pane_or_context_run host 'which '"${__arg}"' >/dev/null' || TEST_ONE_skip=1
		;;
	"passt")
		pane_or_context_run passt "${__arg}" || TEST_ONE_nok=1
		;;
	"passtb")
		pane_or_context_run_bg passt "${__arg}"
		;;
	"passtw")
		pane_or_context_wait passt || TEST_ONE_nok=1
		;;
	"pint")
		tmux send-keys -t ${PANE_PASST} "C-c"
		;;
	"pout")
		__varname="${__arg%% *}"
		__output="$(pane_or_context_output passt "${__arg#* }")"
		TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__varname}__" "${__output}")"
		;;
	"guest")
		pane_or_context_run guest "${__arg}" || TEST_ONE_nok=1
		;;
	"guestb")
		pane_or_context_run_bg guest "${__arg}"
		;;
	"guestw")
		pane_or_context_wait guest || TEST_ONE_nok=1
		;;
	"guest1")
		pane_or_context_run guest_1 "${__arg}" || TEST_ONE_nok=1
		;;
	"guest1b")
		pane_or_context_run_bg guest_1 "${__arg}"
		;;
	"guest1w")
		pane_or_context_wait guest_1 || TEST_ONE_nok=1
		;;
	"gtools")
		pane_or_context_run guest 'which '"${__arg}"' >/dev/null' || TEST_ONE_skip=1
		;;
	"g1tools")
		pane_or_context_run guest_1 'which '"${__arg}"' >/dev/null' || TEST_ONE_skip=1
		;;
	"g2tools")
		pane_or_context_run guest_2 'which '"${__arg}"' >/dev/null' || TEST_ONE_skip=1
		;;
	"guest2")
		pane_or_context_run guest_2 "${__arg}" || TEST_ONE_nok=1
		;;
	"guest2b")
		pane_or_context_run_bg guest_2 "${__arg}"
		;;
	"guest2w")
		pane_or_context_wait guest_2 || TEST_ONE_nok=1
		;;
	"ns")
		pane_or_context_run ns "${__arg}" || TEST_ONE_nok=1
		;;
	"ns1")
		pane_or_context_run ns1 "${__arg}" || TEST_ONE_nok=1
		;;
	"ns2")
		pane_or_context_run ns2 "${__arg}" || TEST_ONE_nok=1
		;;
	"nsb")
		pane_or_context_run_bg ns "${__arg}"
		;;
	"ns1b")
		pane_or_context_run_bg ns1 "${__arg}"
		;;
	"ns2b")
		pane_or_context_run_bg ns2 "${__arg}"
		;;
	"nsw")
		pane_or_context_wait ns || TEST_ONE_nok=1
		;;
	"ns1w")
		pane_or_context_wait ns1 || TEST_ONE_nok=1
		;;
	"ns2w")
		pane_or_context_wait ns2 || TEST_ONE_nok=1
		;;
	"nstools")
		pane_or_context_run ns 'which '"${__arg}"' >/dev/null' || TEST_ONE_skip=1
		;;
	"gout")
		__varname="${__arg%% *}"
		__output="$(pane_or_context_output guest "${__arg#* }")"
		TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__varname}__" "${__output}")"
		;;
	"g1out")
		__varname="${__arg%% *}"
		__output="$(pane_or_context_output guest_1 "${__arg#* }")"
		TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__varname}__" "${__output}")"
		;;
	"g2out")
		__varname="${__arg%% *}"
		__output="$(pane_or_context_output guest_2 "${__arg#* }")"
		TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__varname}__" "${__output}")"
		;;
	"hout")
		__varname="${__arg%% *}"
		__output="$(pane_or_context_output host "${__arg#* }")"
		TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__varname}__" "${__output}")"
		;;
	"nsout")
		__varname="${__arg%% *}"
		__output="$(pane_or_context_output ns "${__arg#* }")"
		TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__varname}__" "${__output}")"
		;;
	"ns1out")
		__varname="${__arg%% *}"
		__output="$(pane_or_context_output ns1 "${__arg#* }")"
		TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__varname}__" "${__output}")"
		;;
	"ns2out")
		__varname="${__arg%% *}"
		__output="$(pane_or_context_output ns2 "${__arg#* }")"
		TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__varname}__" "${__output}")"
		;;
	"check")
		info_check "${__arg}"
		__nok=0
		eval "${__arg} || __nok=1"
		if [ ${__nok} -eq 1 ]; then
			TEST_ONE_nok=1
			info_check_failed
		else
			info_check_passed
		fi
		;;
	"sleep")
		sleep "${__arg}"
		;;
	"info")
		info "${__arg}"
		;;
	"report")
		perf_report ${__arg}
		;;
	"th")
		table_header ${__arg}
		;;
	"tr")
		table_row "${__arg}"
		;;
	"tl")
		table_line "${__arg}"
		;;
	"te")
		table_end
		;;
	"td")
		table_value ${__arg} || TEST_ONE_perf_nok=1
		;;
	"bw")
		table_value_throughput ${__arg} || TEST_ONE_perf_nok=1
		;;
	"lat")
		table_value_latency ${__arg} || TEST_ONE_perf_nok=1
		;;
	"iperf3")
		test_iperf3 ${__arg}
		;;
	"set")
		TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__${__arg%% *}__" "${__arg#* }")"
		;;

	# Demo commands
	"say")
		text_write "${__arg}"
		;;
	"em")
		em_write "${__arg}"
		;;
	"nl")
		info_nolog ""
		;;
	"hl")
		pane_highlight "${__arg}"
		;;
	"bsp")
		text_backspace "${__arg}"
		;;
	"killp")
		pane_kill "${__arg}"
		;;
	"resize")
		pane_resize ${__arg}
		;;
	*)
		__def_body="$(eval printf \"\$TEST_ONE_DEF_$__cmd\")"
		if [ -n "${__def_body}" ]; then
			__ifs="${IFS}"
			IFS='
'
			for __def_line in ${__def_body}; do
				IFS="${__ifs}" test_one_line "${__def_line}"
			done
			IFS="${__ifs}"
		fi
		;;
	esac
}

# test_one() - Run a single test file evaluating directives
# $1:	Name of test file, relative to test/ directory
test_one() {
	TEST_ONE_dirclean=
	__test_file="test/${1}"

	__type="$(file -b --mime-type ${__test_file})"
	if [ "${__type}" = "text/x-shellscript" ]; then
		status_file_start "${1}" 1
		"${__test_file}" && status_test_ok || status_test_fail
		return
	fi

	if [ ${DEMO} -eq 0 ]; then
		__ntests="$(grep -c "^test$(printf '\t')" "${__test_file}")"
		status_file_start "${1}" "${__ntests}"
	fi

	[ ${CI} -eq 1 ] && video_link "${1}"

	TEST_ONE_subs="$(list_add_pair "" "__BASEPATH__" "${BASEPATH}")"
	TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__STATESETUP__" "${STATESETUP}")"
	STATEDIR="${STATEBASE}/${1}"
	mkdir -p "${STATEDIR}"
	TEST_ONE_subs="$(list_add_pair "${TEST_ONE_subs}" "__STATEDIR__" "${STATEDIR}")"
	TEST_ONE_nok=-1
	TEST_ONE_perf_nok=0
	TEST_ONE_skip=0
	TEST_ONE_in_def=
	while IFS= read -r __line; do
		test_one_line "${__line}"
		[ ${TEST_ONE_skip} -eq 1 ] && break
	done < "${__test_file}"

	for __d in ${TEST_ONE_dirclean}; do
		rm -rf ${__d}
	done

	[ ${DEMO} -eq 1 ] && return

	[ ${TEST_ONE_skip} -eq 1 ] && status_test_skip && return
	[ ${TEST_ONE_perf_nok} -eq 0 ] || TEST_ONE_nok=1
	[ ${TEST_ONE_nok} -eq 0 ] && status_test_ok || status_test_fail
}

# test() - Build list of tests to run, in order, then issue test_one()
# $@:	Test files to run, relative to test/
test() {
	__list=

	cd test
	for __f; do
		__type="$(file -b --mime-type ${__f})"
		if [ "${__type}" = "text/x-shellscript" ]; then
			__list="$(list_add "${__list}" "${__f}")"
			continue
		fi
		__list="$(list_add "${__list}" "${__f}")"
	done
	cd ..

	for __f in ${__list}; do
		test_one "${__f}"
	done
}