mirror of https://gerrit.osmocom.org/osmo-dev
ttcn3: run ttcn3 testsuites from osmo-dev
Build testsuite, SUT and dependencies and run everything with one command. Example usage: $ ./ttcn3/ttcn3.sh msc So far, it works at least with: hlr, mgw, msc, pcu, pcu-sns, sgsn Change-Id: I6b4bf2743adeec1a950d5f090a690182b991cf49
This commit is contained in:
parent
c65901cf09
commit
e398564bdd
|
@ -14,3 +14,6 @@ net/*
|
|||
!net/config_2g3g
|
||||
!net/README
|
||||
!net/fill_config.py
|
||||
ttcn3/3G+2G_ttcn3.deps
|
||||
ttcn3/out/
|
||||
ttcn3/make/
|
||||
|
|
20
README
20
README
|
@ -132,6 +132,26 @@ default is /usr/local.
|
|||
Find other useful scripts in src/, see src/README.
|
||||
|
||||
|
||||
=== ttcn3/ttcn3.sh
|
||||
|
||||
Clone and build all dependencies, then run a given TTCN-3 testsuite and all
|
||||
required components. This is intended to make test-cycles as short as possible,
|
||||
without any manual configuration effort and without the need to rebuild the
|
||||
entire testsuite, SUT (subject under test, e.g. osmo-mgw) and dependencies from
|
||||
scratch for each code change. Instead, ttcn3.sh will make use of osmo-dev's
|
||||
generated global makefile and only build what actually changed.
|
||||
|
||||
Example usage:
|
||||
|
||||
./ttcn3/ttcn3.sh mgw
|
||||
|
||||
Note that not all testsuites are supported at this point, see the output of
|
||||
ttcn3.sh without any argument for more information.
|
||||
|
||||
More about the testsuites:
|
||||
https://osmocom.org/projects/cellular-infrastructure/wiki/Titan_TTCN3_Testsuites
|
||||
|
||||
|
||||
=== Troubleshooting
|
||||
|
||||
When using sanitize.opts, osmo-trx is not built with the address sanitizer
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
osmo-bts --enable-trx
|
|
@ -0,0 +1,369 @@
|
|||
#!/bin/sh -e
|
||||
PROJECT="$1"
|
||||
PROJECT_UPPER="$(echo "$PROJECT" | tr '[:lower:]' '[:upper:]')"
|
||||
DIR_OSMODEV="$(readlink -f "$(dirname $0)/..")"
|
||||
DIR_MAKE="${DIR_MAKE:-${DIR_OSMODEV}/ttcn3/make}"
|
||||
DIR_OUTPUT="${DIR_OUTPUT:-${DIR_OSMODEV}/ttcn3/out}"
|
||||
JOBS="${JOBS:-9}"
|
||||
|
||||
check_usage() {
|
||||
if [ -z "$PROJECT" ]; then
|
||||
echo "usage: $(basename $0) PROJECT"
|
||||
echo "example: $(basename $0) hlr"
|
||||
echo "known working projects: hlr, mgw, msc, pcu, pcu-sns, sgsn"
|
||||
echo "wip: bts, bts-oml"
|
||||
echo ""
|
||||
echo "notes (see docker-playground.git/ttcn3-*/jenkins.sh):"
|
||||
echo "- bts: classic test suite with BSC for OML and trxcon+fake_trx"
|
||||
echo "- bts-oml: OML tests (without BSC)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns the name of the testsuite binary
|
||||
get_testsuite_name() {
|
||||
case "$PROJECT" in
|
||||
bts-*) echo "BTS_Tests" ;;
|
||||
mgw) echo "MGCP_Test" ;;
|
||||
pcu-sns) echo "PCU_Tests" ;;
|
||||
*) echo "${PROJECT_UPPER}_Tests" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_testsuite_dir() {
|
||||
local hacks="${DIR_OSMODEV}/src/osmo-ttcn3-hacks"
|
||||
|
||||
case "$PROJECT" in
|
||||
bts-*) echo "$hacks/bts" ;;
|
||||
pcu-sns) echo "$hacks/pcu" ;;
|
||||
*) echo "$hacks/$PROJECT" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_testsuite_config() {
|
||||
case "$PROJECT" in
|
||||
bts-gprs) echo "BTS_Tests_GPRS.cfg" ;;
|
||||
bts-oml) echo "BTS_Tests_OML.cfg" ;;
|
||||
pcu-sns) echo "PCU_Tests_SNS.cfg" ;;
|
||||
*) echo "$(get_testsuite_name).cfg" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Programs that need to be built, launched and killed. To add programs to only one of the steps, modify the appropriate
|
||||
# function below (build_osmo_programs, run_osmo_programs, kill_osmo_programs).
|
||||
get_programs() {
|
||||
case "$PROJECT" in
|
||||
bsc) echo "osmo-stp osmo-bsc osmo-bts-omldummy" ;;
|
||||
bts) echo "osmo-bsc osmo-bts-trx fake_trx.py trxcon" ;;
|
||||
msc) echo "osmo-stp osmo-msc" ;;
|
||||
pcu-sns) echo "osmo-pcu" ;;
|
||||
pcu) echo "osmo-pcu osmo-bsc osmo-bts-virtual virtphy" ;;
|
||||
sgsn) echo "osmo-stp osmo-sgsn" ;;
|
||||
*) echo "osmo-$PROJECT" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# $1: program name
|
||||
get_program_config() {
|
||||
case "$1" in
|
||||
fake_trx.py) ;; # no config
|
||||
osmo-bts-*) echo "osmo-bts.cfg" ;;
|
||||
osmo-pcu)
|
||||
if [ "$PROJECT" = "pcu-sns" ]; then
|
||||
echo "osmo-pcu-sns.cfg"
|
||||
else
|
||||
echo "osmo-pcu.cfg"
|
||||
fi
|
||||
;;
|
||||
trxcon) ;; # no config
|
||||
virtphy) ;; # no config
|
||||
*) echo "$1.cfg" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Return the git repository name, which has the source for a specific program.
|
||||
# $1: program name
|
||||
get_program_repo() {
|
||||
case "$1" in
|
||||
fake_trx.py) echo "osmocom-bb" ;;
|
||||
osmo-bts-*) echo "osmo-bts" ;;
|
||||
osmo-stp) echo "libosmo-sccp" ;;
|
||||
trxcon) echo "osmocom-bb" ;;
|
||||
virtphy) echo "osmocom-bb" ;;
|
||||
*) echo "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_ttcn3_install() {
|
||||
if ! command -v ttcn3_compiler > /dev/null; then
|
||||
echo "ERROR: ttcn3_compiler is not installed."
|
||||
echo "Install eclipse-titan from the Osmocom latest repository."
|
||||
echo "Details: https://osmocom.org/projects/cellular-infrastructure/wiki/Titan_TTCN3_Testsuites"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
kill_osmo_programs() {
|
||||
programs="$(get_programs)"
|
||||
|
||||
# Kill wrappers first
|
||||
for program in $programs; do
|
||||
case "$program" in
|
||||
osmo-pcu) killall osmo-pcu-respawn.sh || true ;;
|
||||
osmo-bts-trx) killall osmo-bts-trx-respawn.sh || true ;;
|
||||
fake_trx.py) killall fake_trx.sh || true ;;
|
||||
esac
|
||||
done
|
||||
|
||||
killall $programs || true
|
||||
}
|
||||
|
||||
setup_dir_make() {
|
||||
cd "$DIR_OSMODEV"
|
||||
|
||||
( echo "# Generated by ttcn3.sh, do not edit"
|
||||
cat ./3G+2G.deps
|
||||
echo
|
||||
echo "osmo-bts libosmocore libosmo-abis"
|
||||
echo "osmo-pcu libosmocore"
|
||||
# just clone these, building is handled by ttcn3.sh
|
||||
echo "osmo-ttcn3-hacks"
|
||||
echo "osmocom-bb") > ttcn3/3G+2G_ttcn3.deps
|
||||
|
||||
./gen_makefile.py ttcn3/3G+2G_ttcn3.deps default.opts iu.opts no_systemd.opts ttcn3/ttcn3.opts -I -m "$DIR_MAKE"
|
||||
}
|
||||
|
||||
# $1: name of repository (e.g. osmo-ttcn3-hacks)
|
||||
clone_repo() {
|
||||
make -C "$DIR_MAKE" ".make.${1}.clone"
|
||||
}
|
||||
|
||||
# Require testsuite dir, with testsuite and all program configs
|
||||
check_dir_testsuite() {
|
||||
local program
|
||||
local config_testsuite
|
||||
local dir_testsuite="$(get_testsuite_dir)"
|
||||
|
||||
if ! [ -d "$dir_testsuite" ]; then
|
||||
echo "ERROR: project '$PROJECT' is invalid, resulting path not found: $dir_testsuite"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for program in $(get_programs); do
|
||||
local config="$(get_program_config "$program")"
|
||||
if [ -z "$config" ]; then
|
||||
continue
|
||||
fi
|
||||
config="$dir_testsuite/$config"
|
||||
if ! [ -e "$config" ]; then
|
||||
echo "ERROR: config not found: $config"
|
||||
echo "Copy it from docker-playground.git, and change IPs to 127.0.0.*."
|
||||
echo "Make sure that everything works, then submit a patch with the config."
|
||||
echo "If $program's config has a different name or is not needed at all, edit"
|
||||
echo "get_program_config() in ttcn3.sh."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
config_testsuite="$dir_testsuite/$(get_testsuite_config)"
|
||||
if ! [ -e "$config_testsuite" ]; then
|
||||
echo "ERROR: testsuite config not found: $config_testsuite"
|
||||
echo "Copy it from docker-playground.git, change the paths to be relative and submit it as patch."
|
||||
echo "If $program's testsuite has a different name, edit get_testsuite_name() in ttcn3.sh."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Build a program that is in the subdir of a repository (e.g. trxcon in osmocom-bb.git).
|
||||
# $1: repository
|
||||
# $2: path in the repository
|
||||
build_osmo_program_subdir() {
|
||||
clone_repo "$1"
|
||||
cd "$DIR_OSMODEV/src/$1/$2"
|
||||
if ! [ -e "./configure" ] && [ -e "configure.ac" ]; then
|
||||
autoreconf -fi
|
||||
fi
|
||||
if ! [ -e "Makefile" ] && [ -e "Makefile.am" ]; then
|
||||
./configure
|
||||
fi
|
||||
make -j"$JOBS"
|
||||
}
|
||||
|
||||
# Use osmo-dev to build a typical Osmocom program, and run a few sanity checks.
|
||||
# $1 program
|
||||
build_osmo_program_osmodev() {
|
||||
local repo="$(get_program_repo "$program")"
|
||||
make -C "$DIR_MAKE" "$repo"
|
||||
|
||||
local path="$(command -v "$program")"
|
||||
if [ -z "$path" ]; then
|
||||
echo "ERROR: program was not installed to PATH: $program"
|
||||
echo "Maybe you need to add /usr/local/bin to PATH?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local pathdir="$(dirname "$path")"
|
||||
local reference="$DIR_MAKE/.make.$repo.build"
|
||||
if [ -z "$(find "$pathdir" -name "$program" -newer "$reference")" ]; then
|
||||
echo "ERROR: $path is outdated!"
|
||||
echo "Maybe you need to pass a configure argument to $repo.git, so it builds and installs $program?"
|
||||
echo "Or the order in PATH is wrong?"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Use osmo-dev to build one Osmocom program and its dependencies
|
||||
build_osmo_programs() {
|
||||
local program
|
||||
for program in $(get_programs); do
|
||||
case "$program" in
|
||||
fake_trx.py) clone_repo "osmocom-bb" ;;
|
||||
trxcon) build_osmo_program_subdir "osmocom-bb" "src/host/trxcon" ;;
|
||||
virtphy) build_osmo_program_subdir "osmocom-bb" "src/host/virt_phy" ;;
|
||||
*) build_osmo_program_osmodev "$program" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
build_testsuite() {
|
||||
cd "$(get_testsuite_dir)"
|
||||
./gen_links.sh
|
||||
./regen_makefile.sh
|
||||
make compile
|
||||
make -j"$JOBS"
|
||||
}
|
||||
|
||||
remove_old_logs() {
|
||||
cd "$(get_testsuite_dir)"
|
||||
rm *.log *.merged 2> /dev/null || true
|
||||
}
|
||||
|
||||
prepare_dir_output() {
|
||||
local program
|
||||
local dir_testsuite="$(get_testsuite_dir)"
|
||||
|
||||
rm -r "$DIR_OUTPUT"/* 2> /dev/null || true
|
||||
mkdir -p "$DIR_OUTPUT"
|
||||
|
||||
for program in $(get_programs); do
|
||||
local config="$(get_program_config "$program")"
|
||||
if [ -n "$config" ]; then
|
||||
cp "$dir_testsuite/$config" "$DIR_OUTPUT"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# $1: log name
|
||||
# $2: command to run
|
||||
run_osmo_program() {
|
||||
local pid
|
||||
local log="$1"
|
||||
shift
|
||||
|
||||
echo "Starting ($log): $@"
|
||||
"$@" > "$log" 2>&1 &
|
||||
pid="$!"
|
||||
|
||||
sleep 0.5
|
||||
if ! kill -0 "$pid" 2> /dev/null; then
|
||||
echo "ERROR: failed to start: $@"
|
||||
cat "$log"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_osmo_programs() {
|
||||
local program
|
||||
local osmocom_bb="$DIR_OSMODEV/src/osmocom-bb"
|
||||
local wrappers="$DIR_OSMODEV/ttcn3/wrappers"
|
||||
|
||||
cd "$DIR_OUTPUT"
|
||||
for program in $(get_programs); do
|
||||
case "$program" in
|
||||
fake_trx.py)
|
||||
run_osmo_program "fake_trx.log" \
|
||||
"$wrappers/fake_trx.sh" \
|
||||
--log-level DEBUG \
|
||||
-b 127.0.0.21 \
|
||||
-R 127.0.0.20 \
|
||||
-r 127.0.0.22
|
||||
;;
|
||||
osmo-bts-omldummy)
|
||||
for i in $(seq 0 2); do
|
||||
run_osmo_program "osmo-bts-$i.log" osmo-bts-omldummy 127.0.0.1 $((i + 1234)) 1
|
||||
done
|
||||
;;
|
||||
osmo-bts-trx)
|
||||
run_osmo_program "$program.log" \
|
||||
"$wrappers/osmo-bts-trx-respawn.sh" -i 127.0.0.10
|
||||
;;
|
||||
osmo-pcu)
|
||||
run_osmo_program "$program.log" "$wrappers/osmo-pcu-respawn.sh" \
|
||||
-c "$(get_program_config osmo-pcu)"
|
||||
;;
|
||||
trxcon)
|
||||
run_osmo_program "$program.log" \
|
||||
"$osmocom_bb/src/host/trxcon/trxcon" \
|
||||
trxcon -i 127.0.0.21 \
|
||||
-s /tmp/osmocom_l2
|
||||
;;
|
||||
virtphy)
|
||||
run_osmo_program "$program.log" "$osmocom_bb/src/host/virt_phy/src/virtphy" \
|
||||
-s /tmp/osmocom_l2
|
||||
;;
|
||||
*)
|
||||
run_osmo_program "$program.log" "$program"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
run_testsuite() {
|
||||
local testsuite="$(get_testsuite_name)"
|
||||
local cfg="$(get_testsuite_config)"
|
||||
|
||||
cd "$(get_testsuite_dir)"
|
||||
../start-testsuite.sh "$testsuite" "$cfg" 2>&1 | tee "$DIR_OUTPUT/ttcn3_stdout.log"
|
||||
}
|
||||
|
||||
collect_logs() {
|
||||
# Merge and move logs
|
||||
cd "$(get_testsuite_dir)"
|
||||
../log_merge.sh $(get_testsuite_name) --rm
|
||||
if ! mv *.merged "$DIR_OUTPUT"; then
|
||||
echo "---"
|
||||
echo "ERROR: no logs generated! Invalid test names in $(get_testsuite_config)?"
|
||||
echo "---"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Format logs
|
||||
cd "$DIR_OUTPUT"
|
||||
for log in *.merged; do
|
||||
ttcn3_logformat -o "${log}.log" "$log"
|
||||
rm "$log"
|
||||
done
|
||||
|
||||
# Print log path
|
||||
echo "---"
|
||||
echo "Logs: $DIR_OUTPUT"
|
||||
echo "---"
|
||||
}
|
||||
|
||||
# Tell glibc to print segfault output to stderr (OS#4212)
|
||||
export LIBC_FATAL_STDERR_=1
|
||||
|
||||
check_usage
|
||||
kill_osmo_programs
|
||||
check_ttcn3_install
|
||||
setup_dir_make
|
||||
clone_repo "osmo-ttcn3-hacks"
|
||||
check_dir_testsuite
|
||||
build_osmo_programs
|
||||
build_testsuite
|
||||
remove_old_logs
|
||||
prepare_dir_output
|
||||
run_osmo_programs
|
||||
run_testsuite
|
||||
kill_osmo_programs
|
||||
collect_logs
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh -x
|
||||
# Run in a separate script, so we can kill it with "killall"
|
||||
|
||||
DIR="$(readlink -f "$(dirname $0)")"
|
||||
cd "$DIR"
|
||||
PID=""
|
||||
|
||||
cleanup() {
|
||||
echo "Caught signal, cleaning up..."
|
||||
set -x
|
||||
kill "$PID"
|
||||
exit 1
|
||||
}
|
||||
|
||||
trap cleanup "TERM"
|
||||
|
||||
./osmocom-bb/src/target/trx_toolkit/fake_trx.py "$@" &
|
||||
PID="$!"
|
||||
|
||||
set +x
|
||||
while true; do
|
||||
sleep 0.1
|
||||
done
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh -x
|
||||
# Automatically restart osmo-bts-trx while running TTCN3 tests. See docker-playground.git.
|
||||
|
||||
while true; do
|
||||
osmo-bts-trx "$@"
|
||||
done
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh -x
|
||||
# Automatically restart osmo-pcu while running TTCN3 tests. See docker-playground.git's osmo-pcu-master/respawn.sh.
|
||||
|
||||
while true; do
|
||||
osmo-pcu "$@"
|
||||
done
|
Loading…
Reference in New Issue