go.ligato.io/vpp-agent/v3@v3.5.0/tests/perf/perf_test.sh (about)

     1  #!/bin/bash
     2  
     3  set -euo pipefail
     4  
     5  SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
     6  BASH_ENTRY_DIR="$(dirname $(readlink -e "${BASH_SOURCE[0]}"))"
     7  
     8  # ------
     9  # config
    10  # ------
    11  
    12  _test="${1}"
    13  _requests="${2-1000}"
    14  _perreq="${3-5}"
    15  _numclients="${4-1}"
    16  
    17  _test_client="$SCRIPT_DIR/$_test"
    18  _vpp_config="$_test_client/vpp.conf"
    19  
    20  [ -z ${REPORT_DIR-} ] && REPORT_DIR="${SCRIPT_DIR}/reports/$_test"
    21  
    22  export DEBUG_PROFILE_PATH="${REPORT_DIR}"
    23  
    24  log_report="${REPORT_DIR}/report.log"
    25  log_vpp="${REPORT_DIR}/vpp.log"
    26  log_agent="${REPORT_DIR}/agent.log"
    27  
    28  sys_info="${REPORT_DIR}/sys-info.txt"
    29  vpp_info="${REPORT_DIR}/vpp-info.txt"
    30  agent_info="${REPORT_DIR}/agent-info"
    31  
    32  cpuprof="${REPORT_DIR}/cpu.pprof"
    33  memprof="${REPORT_DIR}/mem.pprof"
    34  
    35  rest_addr="${REST_ADDR:-http://127.0.0.1:9191}"
    36  sleep_extra="${SLEEP_EXTRA:-5}"
    37  
    38  # -------
    39  #  test
    40  # -------
    41  
    42  function run_test() {
    43  	echo "Preparing PERF testing.."
    44  
    45  	# create report directory
    46  	rm -vrf ${REPORT_DIR}/* 2>/dev/null
    47  	mkdir --mode=777 -p ${REPORT_DIR}
    48  
    49  	perftest $* 2>&1 | tee "$log_report"
    50  }
    51  
    52  function perftest() {
    53  	local perftest="$1"
    54  	local requests="$2"
    55  	local tunnels="$3"
    56  	local clients="$4"
    57  
    58  	echo "================================================================================"
    59  	echo " PERF TEST - ${perftest}"
    60  	echo "================================================================================"
    61  	echo "report dir: ${REPORT_DIR}"
    62  	echo
    63  	echo "settings:"
    64  	echo " - requests per client: ${requests}"
    65  	echo " - tunnels per request: ${_perreq}"
    66  	echo " - clients: ${_numclients}"
    67  	echo "--------------------------------------------------------------------------------"
    68  
    69  	prepare_test
    70  
    71  	trap 'on_exit' EXIT
    72  	start_vpp
    73  	start_agent
    74  
    75  	echo "-> sleeping for $sleep_extra seconds before starting test"
    76  	sleep "$sleep_extra"
    77  
    78  	echo "-> starting $perftest test.."
    79  	echo "--------------------------------------------------------------"
    80  	test_result=0
    81  	"$_test_client"/"$_test" --tunnels=$requests --numperreq=$tunnels --clients=$clients ${CLIENT_PARAMS:-}  || test_result=$?
    82  	echo "--------------------------------------------------------------"
    83  	echo "-> $_test test finished (exit code: $test_result)"
    84  
    85  	sleep 1
    86  
    87  	check_vpp
    88  	check_agent
    89  
    90  	set +e
    91  
    92  	#curl -sSfL "http://127.0.0.1:9094/metrics" > "${REPORT_DIR}/metrics_client.txt" || true
    93  
    94  	echo "-> collecting system info to: $sys_info"
    95  	sysinfo "pwd" >> $sys_info
    96  	sysinfo "env | sort" >> $sys_info
    97  	sysinfo "uname -a" > $sys_info
    98  	sysinfo "lscpu" >> $sys_info
    99  	sysinfo "free -h" >> $sys_info
   100  	sysinfo "df -h" >> $sys_info
   101  	sysinfo "ip -br link" >> $sys_info
   102  	sysinfo "ip -br addr" >> $sys_info
   103  	sysinfo "ip -br route" >> $sys_info
   104  	sysinfo "ps faux" >> $sys_info
   105  
   106  	echo "-> collecting agent data.."
   107  	curljson "$rest_addr/scheduler/stats" > "${REPORT_DIR}/agent-stats_scheduler.json"
   108  	curljson "$rest_addr/govppmux/stats" > "${REPORT_DIR}/agent-stats_govppmux.json"
   109  	curl -sSfL "$rest_addr/metrics" > "${REPORT_DIR}/metrics_agent.txt"
   110  
   111  	echo "-> collecting VPP data to: $vpp_info"
   112  	echo -e "VPP info:\n\n" > $vpp_info
   113  	vppcli "show clock" >> $vpp_info
   114  	vppcli "show version verbose" >> $vpp_info
   115  	vppcli "show plugins" >> $vpp_info
   116  	vppcli "show cpu" >> $vpp_info
   117  	vppcli "show version cmdline" >> $vpp_info
   118  	vppcli "show threads" >> $vpp_info
   119  	vppcli "show physmem" >> $vpp_info
   120  	vppcli "show memory main-heap verbose" >> $vpp_info
   121  	vppcli "show memory api-segment verbose" >> $vpp_info
   122  	vppcli "show memory stats-segment verbose" >> $vpp_info
   123  	vppcli "show api histogram" >> $vpp_info
   124  	vppcli "show api ring-stats" >> $vpp_info
   125  	vppcli "show api trace-status" >> $vpp_info
   126  	vppcli "api trace status" >> $vpp_info
   127  	vppcli "show api clients" >> $vpp_info
   128  	vppcli "show unix files" >> $vpp_info
   129  	vppcli "show unix errors" >> $vpp_info
   130  	vppcli "show event-logger" >> $vpp_info
   131  	vppcli "show ip fib summary" >> $vpp_info
   132  
   133  	if [[ "$test_result" == "0" ]]; then
   134  		echo "--------------------------------------------------------------------------------"
   135  		echo " ✓ Test run passed!"
   136  		echo "--------------------------------------------------------------------------------"
   137  	else
   138  		fail "Test client failure (exit code: $test_result)"
   139  	fi
   140  
   141  	echo "-> sleeping for $sleep_extra seconds before stopping"
   142  	sleep "$sleep_extra"
   143  	
   144  	trap - EXIT
   145  	stop_agent
   146  	stop_vpp
   147  
   148  	echo -n "-> processing profiles.. "
   149  	set +e
   150  	if [ -r "$cpuprof" ]; then
   151  		go tool pprof -dot "$cpuprof" | dot -Tsvg -o "$REPORT_DIR/cpu-profile.svg"
   152  	fi
   153  	if [ -r "$memprof" ]; then
   154  		go tool pprof -alloc_space -dot "$memprof" | dot -Tsvg -o "$REPORT_DIR/mem-profile.svg"
   155  	fi
   156  	set -e
   157  
   158  	echo
   159  }
   160  
   161  function prepare_test() {
   162  	#cd ${BASH_ENTRY_DIR}
   163  	# build test client
   164  
   165  	#[[ -e "./$_test" ]] || {
   166  		echo "-> compiling test client $_test.."
   167  		go build -o "$_test_client/$_test" "$_test_client"
   168  	#}
   169  }
   170  
   171  function fail() {
   172      set +eu
   173  
   174      local msg=${1:-"Unknown cause."}
   175  
   176      echo -e "$msg" >&2
   177  	echo "--------------------------------------------------------------------------------"
   178      echo " ✗ Test run failed!"
   179  	echo "--------------------------------------------------------------------------------"
   180      exit "${2:-1}"
   181  }
   182  
   183  function on_exit() {
   184  	echo "-> cleaning up"
   185  	stop_agent
   186  	stop_vpp
   187  	exit
   188  }
   189  
   190  function sysinfo() {
   191  	local cmd=$1
   192  
   193  	echo "----------------------------------------------------"
   194  	echo "$ $cmd"
   195  	echo "----------------------------------------------------"
   196  	bash -c "$cmd"
   197  	echo
   198  }
   199  
   200  # ---------
   201  #  VPP
   202  # ---------
   203  
   204  wait_vpp_boot=3
   205  
   206  function start_vpp() {
   207  	set +e
   208  
   209  	if ps -C vpp_main >/dev/null 2>&1; then
   210  		fail "VPP is already running"
   211  	fi
   212  
   213  	local _vpp="$(which vpp)"
   214  	[[ -e "$_vpp" ]] || fail "VPP not found!"
   215  
   216  	echo -n "-> starting VPP ($_vpp).. "
   217  	rm -vf /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api
   218  	$_vpp -c "${_vpp_config}" > "$log_vpp" 2>&1 &
   219  	pid_vpp="$!"
   220  	timeout "${wait_vpp_boot}" grep -q "vlib_plugin_early_init" <(tail -qF $log_vpp)
   221  	echo "ok! (PID:${pid_vpp})"
   222  }
   223  
   224  function stop_vpp() {
   225  	set +ue
   226  
   227  	if ps -p $pid_vpp >/dev/null 2>&1; then
   228  		echo "-> stopping VPP (PID: $pid_vpp).."
   229  		kill -SIGTERM $pid_vpp
   230  		wait $pid_vpp
   231  	fi
   232  }
   233  
   234  function check_vpp() {
   235  	set +ue
   236  
   237  	echo -n "-> checking VPP.. "
   238  	if ! ps -p $pid_vpp >/dev/null 2>&1; then
   239  		wait $pid_vpp
   240  		vpp_result=$?
   241  		out=$(tail "$log_vpp")
   242  		fail "VPP down! (exit code: $vpp_result)\n\n$log_vpp output:\n${out}\n"
   243  	fi
   244  	log_errors=$(grep 'WARNING' "$log_vpp" | wc -l)
   245  	if [[ "$log_errors" -gt "0" ]]; then
   246  		echo "found ${log_errors} warnings!"
   247  	else
   248  		echo "ok!"
   249  	fi
   250  }
   251  
   252  function vppcli() {
   253  	set +e
   254  
   255  	local cmd=$1
   256  	local _clisock="/run/vpp/cli.sock"
   257  
   258  	echo "----------------------------------------------------"
   259  	echo "vppctl $cmd"
   260  	echo "----------------------------------------------------"
   261  	if [ -S "$_clisock" ]; then
   262  		vppctl "$cmd"
   263  	else
   264  		vppctl -s localhost:5002 "$cmd"
   265  	fi
   266  	echo
   267  }
   268  
   269  # -------------
   270  #  vpp-agent
   271  # -------------
   272  
   273  wait_agent_boot=10
   274  
   275  function start_agent() {
   276  	local _agent="$(which vpp-agent)"
   277  	[[ -e "$_agent" ]] || fail "vpp-agent not found!"
   278  
   279  	export CONFIG_DIR="$_test_client"
   280  
   281  	echo -n "-> starting agent.. "
   282  	$_agent > "$log_agent" 2>&1 &
   283  	pid_agent="$!"
   284  	timeout "${wait_agent_boot}" grep -q "Agent started" <(tail -qF $log_agent) || {
   285  		echo "AGENT LOG:"
   286  		echo "---"
   287  		tail "$log_agent"
   288  		echo "---"
   289  		fail "TIMEOUT!"
   290  	}
   291  	echo "ok! (PID:${pid_agent})"
   292  }
   293  
   294  function stop_agent() {
   295  	set +ue
   296  
   297  	if ps -p $pid_agent >/dev/null 2>&1; then
   298  		echo "-> stopping vpp-agent (PID: $pid_agent).."
   299  		kill -SIGINT ${pid_agent}
   300  		wait ${pid_agent}
   301  	fi
   302  }
   303  
   304  function check_agent() {
   305  	set +ue
   306  
   307  	echo -n "-> checking vpp-agent.. "
   308  	if ! ps -p $pid_agent >/dev/null 2>&1; then
   309  		wait $pid_agent
   310  		result=$?
   311  		out=$(tail "$log_agent")
   312  		fail "Agent down! (exit code: $result)\n\n$log_agent output:\n${out}\n"
   313  	fi
   314  
   315  	log_errors=$(grep 'level=error' "$log_agent")
   316  	err_num=$(echo -n "$log_errors" | wc -l)
   317  
   318  	if [[ "$err_num" -gt "0" ]]; then
   319  		echo "found ${err_num} errors in log:"
   320  		echo "-----"
   321  		echo "$log_errors" | tail -n 10 | sed 's/.*/\t&/'
   322  		echo "-----"
   323  	else
   324  		echo "ok!"
   325  	fi
   326  }
   327  
   328  function curljson() {
   329  	local url="$1"
   330  
   331  	curl -sSfL -H "Content-Type: application/json" "$url"
   332  }
   333  
   334  # skip running test if no argument is given (source)
   335  #[ -z "${1-}" ] || run_test $1
   336  
   337  run_test "$_test" "$_requests" "$_perreq" "$_numclients"
   338