adding basic shell script for running end-to-end tests

This commit is contained in:
Andre Puschmann 2020-01-15 16:32:49 +01:00
parent 9720449cbb
commit 0247762265
4 changed files with 361 additions and 0 deletions

View File

@ -551,3 +551,5 @@ if(ENABLE_SRSEPC)
else(ENABLE_SRSEPC)
message(STATUS "srsEPC build disabled")
endif(ENABLE_SRSEPC)
add_subdirectory(test)

31
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,31 @@
#
# Copyright 2013-2020 Software Radio Systems Limited
#
# This file is part of srsLTE
#
# srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# srsLTE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# A copy of the GNU Affero General Public License can be found in
# the LICENSE file in the top-level directory of this distribution
# and at http://www.gnu.org/licenses/.
#
########################################################################
# END-TO-END TESTS
########################################################################
SET(CTEST_OUTPUT_ON_FAILURE TRUE)
if (ZEROMQ_FOUND)
foreach (cell_n_prb 6 15 25 50 75 100)
add_test(e2e_${cell_n_prb}prb ${CMAKE_CURRENT_SOURCE_DIR}/run_lte.sh ${CMAKE_CURRENT_BINARY_DIR}/../ ${cell_n_prb})
endforeach (cell_n_prb)
endif (ZEROMQ_FOUND)

51
test/README.md Normal file
View File

@ -0,0 +1,51 @@
End-to-End LTE Tests
====================
This folder contains a basic shell script that allows a quick end-to-end LTE test
using srsUE, srsENB, and srsEPC. The script has minimal requirements and should
only take less then 30 seconds for each configuration. Currently the script
only allows to configure the cell bandwidth.
The script launches all components and puts the UE into a different network namespace
in order to allow IP connectivity to srsEPC on a single machine. It therefore
requires root privelages at the moment.
It then launches, one after another, uplink and downlink ping as well as a quick UDP
downlink session. Between those experiments, the UE transits between RRC Idle and Connected
states multiple times and is either put into Connected through pending UL traffic or
pending DL traffic (using paging).
After the experiments are finished, all components are torn down and the log files
are analyzed.
Single Execution
----------------
The script can be executed manually. It expects the srsLTE build directory as
the first argument and the cell bandwidth as the second.
```
$ sudo ./run_lte.sh ~/src/srsLTE/build 50
```
Testing all Bandwidths
----------------------
You can also test all bandwidths by letting CTest iterate over all possible PRB sizes.
```
$ cd test
$ sudo make test
```
Known Issues
------------
If you've started the script and it failed it may left the network namespace open and thus
the next execution of the script will fail. In this case, just delete the network namespace
before running again:
```
$ sudo ip netns delete ue1
```

277
test/run_lte.sh Executable file
View File

@ -0,0 +1,277 @@
#!/bin/bash
#
# Copyright 2013-2020 Software Radio Systems Limited
#
# This file is part of srsLTE
#
# srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# srsLTE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# A copy of the GNU Affero General Public License can be found in
# the LICENSE file in the top-level directory of this distribution
# and at http://www.gnu.org/licenses/.
#
epc_pid=0
enb_pid=0
ue_pid=0
print_use(){
echo "Please call script with srsLTE build path as first argument and number of PRBs as second"
echo "E.g. ./run_lte.sh [build_path] [nof_prb]"
exit -1
}
kill_lte(){
echo "Shutting down LTE network"
# Allow to gracefully exit
kill -SIGTERM $ue_pid
sleep 4
kill -SIGTERM $enb_pid
sleep 4
kill -SIGTERM $epc_pid
sleep 1
# Force kill if they are still running
if ps -p $ue_pid > /dev/null
then
echo "Killing UE"
kill -9 $ue_pid
fi
if ps -p $enb_pid > /dev/null
then
echo "Killing eNB"
kill -9 $enb_pid
fi
if ps -p $epc_pid > /dev/null
then
echo "Killing EPC"
kill -9 $epc_pid
fi
if [ -f ./srsLTE.backtrace.crash ]; then
echo "Rename backtrace"
mv ./srsLTE.backtrace.crash srsLTE.backtrace.log
fi
# Delete netns
ip netns delete $ue_netns
# Don't exit with return code ..
}
valid_num_prb()
{
case "$1" in
"6"|"15"|"25"|"50"|"75"|"100")
return 0;;
*)
echo "Invalid number of PRBs. Possible values are [6, 15, 25, 50, 75, 100]."
return 1;;
esac
}
# check if build path has been passed
if ([ ! $1 ])
then
print_use
exit
fi
build_path="$1"
# check number of PRBs
if ([ ! $2 ])
then
print_use
exit
fi
nof_prb="$2"
# Check for LTE binaries in build path
if [ ! -x "$build_path/srsenb/src/srsenb" ]; then
echo "Error! srsENB binary not found or not executable!"
exit 1
fi
if [ ! -x "$build_path/srsepc/src/srsepc" ]; then
echo "Error! srsEPC binary not found or not executable!"
exit 1
fi
if [ ! -x "$build_path/srsue/src/srsue" ]; then
echo "Error! srsUE binary not found or not executable!"
exit 1
fi
# Check PRB parameter
if ! valid_num_prb "$nof_prb"; then
exit 1
fi
# Adding netns
ue_netns="ue1"
ip netns add $ue_netns
if [ $? -ne 0 ]
then
echo "Couldn't add netns. Missing permissions? Network namespace $ue_netns already exists?"
exit 1
fi
epc_args="$build_path/../srsepc/epc.conf.example --log.filename=./${nof_prb}prb_epc.log"
enb_args="$build_path/../srsenb/enb.conf.example --rf.device_name=zmq --rf.device_args=\"fail_on_disconnect=true,tx_port=tcp://*:2000,rx_port=tcp://localhost:2001,id=enb,base_srate=23.04e6\" --expert.nof_phy_threads=1 --expert.rrc_inactivity_timer=1000 --enb.n_prb=$nof_prb --log.filename=./${nof_prb}prb_enb.log"
ue_args="$build_path/../srsue/ue.conf.example --rf.device_name=zmq --rf.device_args=\"tx_port=tcp://*:2001,rx_port=tcp://localhost:2000,id=ue,base_srate=23.04e6\" --phy.nof_phy_threads=1 --gw.netns=$ue_netns --log.filename=./${nof_prb}prb_ue.log"
# Remove existing log files
log_files=$(ls -l | grep ${nof_prb}prb_)
if [ ! -z "$log_files" ]; then
echo "Deleting existing log files for ${nof_prb} PRB."
eval "rm -Rf ${nof_prb}prb_*.log"
fi
# Run srsEPC
echo "Starting srsEPC"
screen -S srsepc -dm -L -Logfile ./${nof_prb}prb_screenlog_srsepc.log $build_path/srsepc/src/srsepc $epc_args
sleep 3
epc_pid=$(pgrep srsepc)
if [ -z "$epc_pid" ]
then
echo "Couldn't start EPC."
kill_lte
exit 1
fi
echo "srsEPC's PID is $epc_pid"
# Run srsENB
echo "Starting srsENB"
screen -S srsenb -dm -L -Logfile ./${nof_prb}prb_screenlog_srsenb.log $build_path/srsenb/src/srsenb $enb_args
sleep 2
enb_pid=$(pgrep srsenb)
if [ -z "$enb_pid" ]
then
echo "Couldn't start ENB"
kill_lte
exit 1
fi
echo "srsENB's PID is $enb_pid"
# Run srsUE
echo "Starting srsUE"
screen -S srsue -dm -L -Logfile ${nof_prb}prb_screenlog_srsue.log $build_path/srsue/src/srsue $ue_args
sleep 2
ue_pid=$(pgrep srsue)
if [ -z "$ue_pid" ]
then
echo "Couldn't start UE"
kill_lte
exit 1
fi
echo "srsUE's PID is $ue_pid"
# Wait until UE is connected
timeout=10
tun_dev="tun_srsue"
echo "Waiting for $tun_dev to become available for ${timeout}s .."
wait_time=0
ip=$(ip netns exec $ue_netns ip addr show $tun_dev | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
while [ -z $ip ] && [ $wait_time -ne $timeout ]
do
# Wait 1s before next attempt
sleep 1
let wait_time++
ip=$(ip netns exec $ue_netns ip addr show $tun_dev | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
done
if [ ! -z $ip ]; then
echo "$tun_dev is up with IP $ip!"
sleep 1
else
echo "$tun_dev didn't get up after ${timeout}s"
kill_lte
exit 1
fi
# extract MME IP
baseip=`echo $ip | cut -d"." -f1-3`
mme_ip=$baseip".1"
echo "MME IP is $mme_ip"
# show UE console trace
screen -S srsue -X stuff "t$(printf \\r)"
# Run tests now
# sleep 3s to get RRC connection release
sleep 1.5
# run UL ping test
echo "Run UL ping"
ip netns exec $ue_netns screen -dm -L -Logfile ./${nof_prb}prb_screenlog_ping_ul.log ping $mme_ip -c 3
sleep 4
# sleep 3s to get RRC connection release
echo "Run DL ping"
screen -dm -L -Logfile ./${nof_prb}prb_screenlog_ping_dl.log ping $ip -c 3
sleep 4
# run UDP DL
echo "Run DL iperf"
screen -dm -L -Logfile ./${nof_prb}prb_screenlog_iperf_dl.log iperf -c $ip -u -t 1 -i 1 -b 100M
sleep 2
# Stop all running LTE components and remove netns
kill_lte
# check ping results
loss_rate=$(cat ./${nof_prb}prb_screenlog_ping_ul.log | grep -oP '\d+(?=% packet loss)')
if [ "$loss_rate" != "0" ] 2>/dev/null; then
echo "Error. Detected $loss_rate per-cent loss rate in UL ping."
exit 1
fi
loss_rate=$(cat ./${nof_prb}prb_screenlog_ping_dl.log | grep -oP '\d+(?=% packet loss)')
if [ "$loss_rate" != "0" ] 2>/dev/null; then
echo "Error. Detected $loss_rate per-cent loss rate in DL ping."
exit 1
fi
# check that all log files have "Closing log" as last line
last_line=$(cat ./${nof_prb}prb_ue.log | tail -n1)
if [ "$last_line" != "Closing log" ]; then
echo "Error. srsUE didn't seem to have exited properly."
exit 1
fi
last_line=$(cat ./${nof_prb}prb_enb.log | tail -n1)
if [ "$last_line" != "Closing log" ]; then
echo "Error. srsENB didn't seem to have exited properly."
exit 1
fi
last_line=$(cat ./${nof_prb}prb_epc.log | tail -n1)
if [ "$last_line" != "Closing log" ]; then
echo "Error. srsEPC didn't seem to have exited properly."
exit 1
fi
# Check PRACH results
num_prach=$(cat ./${nof_prb}prb_screenlog_srsenb.log | grep RACH | wc -l)
if [ "$loss_rate" != "5" ] 2>/dev/null; then
echo "Error. Detected $num_prach PRACHs. But should be 5."
exit 1
fi
echo "All tests passed!"
exit 0