Add ttcn3-bts-test env

Change-Id: I3251a49503dc823f0ef1fe8ef5d68236a584dad4
diff --git a/ttcn3/suites/ttcn3_bts_tests/scripts/BTS_Tests.cfg.tmpl b/ttcn3/suites/ttcn3_bts_tests/scripts/BTS_Tests.cfg.tmpl
new file mode 100644
index 0000000..7379528
--- /dev/null
+++ b/ttcn3/suites/ttcn3_bts_tests/scripts/BTS_Tests.cfg.tmpl
@@ -0,0 +1,25 @@
+[ORDERED_INCLUDE]
+"/osmo-ttcn3-hacks/Common.cfg"
+"/osmo-ttcn3-hacks/bts/BTS_Tests.default"
+
+[LOGGING]
+
+[TESTPORT_PARAMETERS]
+*.BTSVTY.CTRL_HOSTNAME := "${btsvty_ctrl_hostname}"
+
+[MODULE_PARAMETERS]
+BTS_Tests.mp_rsl_ip := "172.18.9.10"
+BTS_Tests.mp_bb_trxc_ip := "127.0.0.1"
+BTS_Tests.mp_pcu_socket := "/data/unix_pcu/pcu_bts"
+BTS_Tests.mp_bb_trxc_port := -1
+L1CTL_PortType.m_l1ctl_sock_path := "/data/unix_l2/osmocom_l2"
+BTS_Tests.mp_ctrl_ip   := "${btsvty_ctrl_hostname}"
+BTS_Tests.mp_rxlev_exp := 1
+BTS_Tests.mp_tolerance_rxlev := 10;
+BTS_Tests.mp_tolerance_rxqual := 1;
+BTS_Tests.mp_trx0_arfcn := 868
+
+[MAIN_CONTROLLER]
+
+[EXECUTE]
+BTS_Tests.control
diff --git a/ttcn3/suites/ttcn3_bts_tests/scripts/run_ttcn3_docker.sh b/ttcn3/suites/ttcn3_bts_tests/scripts/run_ttcn3_docker.sh
new file mode 100755
index 0000000..64987b3
--- /dev/null
+++ b/ttcn3/suites/ttcn3_bts_tests/scripts/run_ttcn3_docker.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+set -x
+
+RUNDIR="$1"
+JUNIT_TTCN3_DST_FILE="$2"
+L2_SOCKET_PATH="$3"
+PCU_SOCKET_PATH="$4"
+
+# Absolute path to this script
+SCRIPT=$(readlink -f "$0")
+# Absolute path this script is in
+SCRIPTPATH=$(dirname "$SCRIPT")
+
+VOL_BASE_DIR="$RUNDIR/logs"
+rm -rf "$VOL_BASE_DIR"
+mkdir -p "$VOL_BASE_DIR"
+
+if [ "x$BUILD_TAG" = "x" ]; then
+	BUILD_TAG=nonjenkins
+fi
+
+REPO_USER="registry.sysmocom.de"
+SUITE_NAME="ttcn3-bts-test"
+NET_NAME=$SUITE_NAME
+DOCKER_NAME="$BUILD_TAG-$SUITE_NAME"
+
+network_create() {
+	NET=$1
+	echo Creating network $NET_NAME
+	docker network create --internal --subnet $NET $NET_NAME
+}
+
+network_remove() {
+	echo Removing network $NET_NAME
+	docker network remove $NET_NAME
+}
+
+child_ps=0
+forward_kill() {
+	sig="$1"
+	echo "Caught signal SIG$sig!"
+	if [ "$child_ps" != "0" ]; then
+		echo "Killing $child_ps with SIG$sig!"
+		docker kill ${DOCKER_NAME}
+	fi
+	exit 130
+}
+forward_kill_int() {
+	forward_kill "INT"
+}
+forward_kill_term() {
+	forward_kill "TERM"
+}
+# Don't use 'set -e', otherwise traps are not triggered!
+trap forward_kill_int INT
+trap forward_kill_term TERM
+
+network_create 172.18.9.0/24
+
+mkdir $VOL_BASE_DIR/bts-tester
+echo "SCRIPTPATH=$SCRIPTPATH PWD=$PWD"
+cp $RUNDIR/BTS_Tests.cfg $VOL_BASE_DIR/bts-tester/
+
+echo Starting container with BTS testsuite
+docker kill ${DOCKER_NAME}
+docker run	--rm \
+		--network $NET_NAME --ip 172.18.9.10 \
+		-e "TTCN3_PCAP_PATH=/data" \
+		--mount type=bind,source=$VOL_BASE_DIR/bts-tester,destination=/data \
+		--mount type=bind,source="$(dirname "$L2_SOCKET_PATH")",destination=/data/unix_l2 \
+		--mount type=bind,source="$(dirname "$PCU_SOCKET_PATH")",destination=/data/unix_pcu \
+		--name ${DOCKER_NAME} \
+		$REPO_USER/${SUITE_NAME} &
+child_ps=$!
+echo "$$: waiting for $child_ps"
+wait "$child_ps"
+child_exit_code="$?"
+echo "ttcn3 docker exited with code $child_exit_code"
+
+network_remove
+
+echo "Copying TTCN3 junit file to $JUNIT_TTCN3_DST_FILE"
+cp $VOL_BASE_DIR/bts-tester/junit-xml-*.log $JUNIT_TTCN3_DST_FILE
+sed -i "s#classname='BTS_Tests'#classname='$(basename $JUNIT_TTCN3_DST_FILE)'#g" $JUNIT_TTCN3_DST_FILE
+
+exit $child_exit_code
diff --git a/ttcn3/suites/ttcn3_bts_tests/suite.conf b/ttcn3/suites/ttcn3_bts_tests/suite.conf
new file mode 100644
index 0000000..1eb0a02
--- /dev/null
+++ b/ttcn3/suites/ttcn3_bts_tests/suite.conf
@@ -0,0 +1,7 @@
+resources:
+  ip_address:
+  - times: 7 # msc, bsc, hlr, stp, mgw, sgsn, ggsn
+  bts:
+  - times: 1
+  osmocon_phone:
+  - times: 1
diff --git a/ttcn3/suites/ttcn3_bts_tests/ttcn3_bts_tests.py b/ttcn3/suites/ttcn3_bts_tests/ttcn3_bts_tests.py
new file mode 100755
index 0000000..b3ca946
--- /dev/null
+++ b/ttcn3/suites/ttcn3_bts_tests/ttcn3_bts_tests.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+import os
+from mako.template import Template
+
+from osmo_gsm_tester.testenv import *
+
+hlr_dummy = suite.hlr()
+mgw_dummy = suite.mgw()
+stp_dummy = suite.stp()
+msc_dummy = suite.msc(hlr_dummy, mgw_dummy, stp_dummy)
+ggsn_dummy = suite.ggsn()
+sgsn_dummy = suite.sgsn(hlr_dummy, ggsn_dummy)
+bsc = suite.bsc(msc_dummy, mgw_dummy, stp_dummy)
+bts = suite.bts()
+osmocon = suite.osmocon()
+
+bts.set_num_trx(1)
+bts.set_trx_phy_channel(0, 0, 'CCCH+SDCCH4')
+bts.set_trx_phy_channel(0, 1, 'TCH/F')
+bts.set_trx_phy_channel(0, 2, 'TCH/F')
+bts.set_trx_phy_channel(0, 3, 'TCH/F_PDCH')
+bts.set_trx_phy_channel(0, 4, 'TCH/F_TCH/H_PDCH')
+bts.set_trx_phy_channel(0, 5, 'TCH/H')
+bts.set_trx_phy_channel(0, 6, 'SDCCH8')
+bts.set_trx_phy_channel(0, 7, 'PDCH')
+
+print('Starting CNI')
+hlr_dummy.start()
+stp_dummy.start()
+msc_dummy.start()
+mgw_dummy.start()
+
+bsc.set_rsl_ip('172.18.9.10')
+bsc.bts_add(bts)
+sgsn_dummy.bts_add(bts)
+
+bsc.start()
+bts.start(keepalive=True)
+
+print('Starting osmocon')
+osmocon.start()
+
+own_dir = os.path.dirname(os.path.realpath(__file__))
+script_file = os.path.join(own_dir, 'scripts', 'run_ttcn3_docker.sh')
+bts_tmpl_file = os.path.join(own_dir, 'scripts', 'BTS_Tests.cfg.tmpl')
+script_run_dir = test.get_run_dir().new_dir('ttcn3')
+bts_cfg_file = os.path.join(str(script_run_dir), 'BTS_Tests.cfg')
+junit_ttcn3_dst_file = os.path.join(str(suite.trial.get_run_dir()), 'trial-') + suite.name() + '.xml'
+docker_cmd = (script_file, str(script_run_dir), junit_ttcn3_dst_file, osmocon.l2_socket_path(), bts.pcu_socket_path())
+
+print('Creating template')
+mytemplate = Template(filename=bts_tmpl_file)
+r = mytemplate.render(btsvty_ctrl_hostname=bts.remote_addr())
+with open(bts_cfg_file, 'w') as f:
+    f.write(r)
+
+
+print('Starting TTCN3 tests')
+proc = process.Process('ttcn3', script_run_dir, docker_cmd)
+try:
+    proc.launch()
+    print('Starting TTCN3 launched, waiting until it finishes')
+    proc.wait(timeout=3600)
+except Exception as e:
+    proc.terminate()
+    raise e
+
+if proc.result != 0:
+    raise RuntimeError("run_ttcn3_docker.sh exited with error code %d" % proc.result)
+
+print('Done')