552 lines
23 KiB
Python
Executable File
552 lines
23 KiB
Python
Executable File
import threading, os, re
|
|
|
|
from utils import quickshell, log, TestFailed, do_tests
|
|
from task import Task, WAITLOG_SUCCESS
|
|
|
|
class alu_test:
|
|
def __init__(self,
|
|
epc, enb, ue,
|
|
openair,
|
|
user, password,
|
|
log_subdir,
|
|
env,
|
|
enb_rru = "",
|
|
enb_rcc = ""):
|
|
self.epc_machine = epc
|
|
self.enb_machine = enb
|
|
self.ue_machine = ue
|
|
self.openair_dir = openair
|
|
self.oai_user = user
|
|
self.oai_password = password
|
|
self.env = env
|
|
self.enb_rru_machine = enb_rru
|
|
self.enb_rcc_machine = enb_rcc
|
|
|
|
self.task_hss = None
|
|
self.task_enb = None
|
|
self.task_ue = None
|
|
self.task_rru_enb = None
|
|
self.task_rcc_enb = None
|
|
|
|
self.logdir = openair + '/cmake_targets/autotests/log/' + log_subdir
|
|
quickshell('mkdir -p ' + self.logdir)
|
|
|
|
#event object used to wait for several tasks at once
|
|
self.event = threading.Event()
|
|
|
|
##########################################################################
|
|
# finish
|
|
##########################################################################
|
|
def finish(self):
|
|
#brutally kill tasks still running
|
|
#TODO: call 'wait', some processes may still be there as zombies
|
|
if self.task_hss != None and self.task_hss.alive():
|
|
self.task_hss.kill()
|
|
if self.task_enb != None and self.task_enb.alive():
|
|
self.task_enb.kill()
|
|
if self.task_ue != None and self.task_ue.alive():
|
|
self.task_ue.kill()
|
|
if self.task_rru_enb != None and self.task_rru_enb.alive():
|
|
self.task_rru_enb.kill()
|
|
if self.task_rcc_enb != None and self.task_rcc_enb.alive():
|
|
self.task_rcc_enb.kill()
|
|
|
|
##########################################################################
|
|
# start_epc
|
|
##########################################################################
|
|
def start_epc(self):
|
|
#launch HSS, wait for prompt
|
|
log("INFO: ALU test: run HSS")
|
|
self.task_hss = Task("actions/alu_hss.bash",
|
|
"alu_hss",
|
|
self.epc_machine,
|
|
self.oai_user,
|
|
self.oai_password,
|
|
self.env,
|
|
self.logdir + "/alu_hss." + self.epc_machine,
|
|
event=self.event)
|
|
self.task_hss.waitlog('S6AS_SIM-> ')
|
|
|
|
#then launch EPC, wait for connection on HSS side
|
|
log("INFO: ALU test: run EPC")
|
|
task_epc = Task("actions/alu_epc.bash",
|
|
"ALU EPC",
|
|
self.epc_machine,
|
|
self.oai_user,
|
|
self.oai_password,
|
|
self.env,
|
|
self.logdir + "/alu_epc." + self.epc_machine)
|
|
ret = task_epc.wait()
|
|
if ret != 0:
|
|
log("ERROR: EPC start failure");
|
|
raise TestFailed()
|
|
self.task_hss.waitlog('Connected\n')
|
|
|
|
##########################################################################
|
|
# stop_epc
|
|
##########################################################################
|
|
def stop_epc(self):
|
|
#stop EPC, wait for disconnection on HSS side
|
|
log("INFO: ALU test: stop EPC")
|
|
task_epc = Task("actions/alu_epc_stop.bash",
|
|
"alu_epc_stop",
|
|
self.epc_machine,
|
|
self.oai_user,
|
|
self.oai_password,
|
|
self.env,
|
|
self.logdir + "/alu_epc_stop." + self.epc_machine)
|
|
ret = task_epc.wait()
|
|
if ret != 0:
|
|
log("ERROR: ALU test: ALU EPC stop failed")
|
|
raise TestFailed()
|
|
self.task_hss.waitlog('Disconnected\n')
|
|
|
|
log("INFO: ALU test: stop HSS")
|
|
self.task_hss.sendnow("exit\n")
|
|
ret = self.task_hss.wait()
|
|
if ret != 0:
|
|
log("ERROR: ALU test: ALU HSS failed")
|
|
raise TestFailed()
|
|
|
|
##########################################################################
|
|
# compile_enb
|
|
##########################################################################
|
|
def compile_enb(self, build_arguments, log_suffix=""):
|
|
log("INFO: ALU test: compile softmodem on " + self.enb_machine)
|
|
envcomp = list(self.env)
|
|
envcomp.append('BUILD_ARGUMENTS="' + build_arguments + '"')
|
|
#we don't care about BUILD_OUTPUT but required (TODO: change that)
|
|
envcomp.append('BUILD_OUTPUT=/')
|
|
logdir = self.logdir + "/compile_log"
|
|
remote_files = "'/tmp/oai_test_setup/oai/cmake_targets/log/*'"
|
|
post_action = "mkdir -p "+ logdir + \
|
|
" && sshpass -p " + self.oai_password + \
|
|
" scp -r " + self.oai_user + \
|
|
"@" + self.enb_machine + ":" + remote_files + " " + logdir + \
|
|
" || true"
|
|
task = Task("actions/compilation.bash",
|
|
"compile_softmodem",
|
|
self.enb_machine,
|
|
self.oai_user,
|
|
self.oai_password,
|
|
envcomp,
|
|
self.logdir + "/compile_softmodem." + log_suffix + \
|
|
self.enb_machine,
|
|
post_action=post_action)
|
|
ret = task.wait()
|
|
if ret != 0:
|
|
log("ERROR: softmodem compilation failure");
|
|
raise TestFailed()
|
|
task.postaction()
|
|
|
|
##########################################################################
|
|
# start_enb
|
|
##########################################################################
|
|
def start_enb(self, config_file):
|
|
#copy wanted configuration file
|
|
quickshell("sshpass -p " + self.oai_password +
|
|
" scp config/" + config_file + " " +
|
|
self.oai_user + "@" + self.enb_machine + ":/tmp/enb.conf")
|
|
|
|
#run softmodem
|
|
log("INFO: ALU test: run softmodem with configuration file " +
|
|
config_file)
|
|
self.task_enb = Task("actions/run_enb.bash",
|
|
"run_softmodem",
|
|
self.enb_machine,
|
|
self.oai_user,
|
|
self.oai_password,
|
|
self.env,
|
|
self.logdir + "/run_softmodem." + self.enb_machine,
|
|
event=self.event)
|
|
self.task_enb.waitlog('got sync')
|
|
|
|
##########################################################################
|
|
# stop_enb
|
|
##########################################################################
|
|
def stop_enb(self):
|
|
log("INFO: ALU test: stop softmodem")
|
|
self.task_enb.sendnow("%c" % 3)
|
|
ret = self.task_enb.wait()
|
|
if ret != 0:
|
|
log("ERROR: ALU test: softmodem failed")
|
|
#not sure if we have to quit here or not
|
|
#os._exit(1)
|
|
|
|
##########################################################################
|
|
# start_enb_rru_rcc
|
|
##########################################################################
|
|
def start_enb_rru_rcc(self, rru_config_file, rcc_config_file):
|
|
#copy wanted configuration files
|
|
quickshell("sshpass -p " + self.oai_password +
|
|
" scp config/" + rru_config_file + " " +
|
|
self.oai_user + "@" + self.enb_rru_machine+":/tmp/enb.conf")
|
|
quickshell("sshpass -p " + self.oai_password +
|
|
" scp config/" + rcc_config_file + " " +
|
|
self.oai_user + "@" + self.enb_rcc_machine+":/tmp/enb.conf")
|
|
|
|
#run RRU/RCC softmodem
|
|
log("INFO: ALU test: run RRU softmodem with configuration file " +
|
|
rru_config_file)
|
|
self.task_rru_enb = Task("actions/run_enb.bash",
|
|
"run_RRU_softmodem",
|
|
self.enb_rru_machine,
|
|
self.oai_user,
|
|
self.oai_password,
|
|
self.env,
|
|
self.logdir + "/run_softmodem." + self.enb_rru_machine,
|
|
event=self.event)
|
|
self.task_rru_enb.waitlog('[RRH] binding to')
|
|
log("INFO: ALU test: run RCC softmodem with configuration file " +
|
|
rcc_config_file)
|
|
self.task_rcc_enb = Task("actions/run_enb.bash",
|
|
"run_RCC_softmodem",
|
|
self.enb_rcc_machine,
|
|
self.oai_user,
|
|
self.oai_password,
|
|
self.env,
|
|
self.logdir + "/run_softmodem." + self.enb_rcc_machine,
|
|
event=self.event)
|
|
self.task_rcc_enb.waitlog('[BBU] local ip addr')
|
|
#wait for RRU and RCC to be connected
|
|
self.task_rru_enb.waitlog('devices ok (eNB_thread_asynch_rx)')
|
|
|
|
##########################################################################
|
|
# stop_enb_rru_rcc
|
|
##########################################################################
|
|
def stop_enb_rru_rcc(self):
|
|
log("INFO: ALU test: stop RRU/RCC softmodem")
|
|
self.task_rru_enb.sendnow("%c" % 3)
|
|
ret = self.task_rru_enb.wait()
|
|
if ret != 0:
|
|
log("ERROR: ALU test: RRU softmodem failed")
|
|
#not sure if we have to quit here or not
|
|
#os._exit(1)
|
|
self.task_rcc_enb.sendnow("%c" % 3)
|
|
ret = self.task_rcc_enb.wait()
|
|
if ret != 0:
|
|
log("ERROR: ALU test: RCC softmodem failed")
|
|
#not sure if we have to quit here or not
|
|
#os._exit(1)
|
|
|
|
##########################################################################
|
|
# start_ue
|
|
##########################################################################
|
|
def start_ue(self, ue):
|
|
log("INFO: ALU test: start " + ue + " UE")
|
|
self.task_ue = Task("actions/start_" + ue + ".bash",
|
|
"start_" + ue,
|
|
self.ue_machine,
|
|
self.oai_user,
|
|
self.oai_password,
|
|
self.env,
|
|
self.logdir + "/start_" + ue + "." + self.ue_machine,
|
|
event=self.event)
|
|
self.task_ue.waitlog("local IP address", event=self.event)
|
|
self.event.wait()
|
|
|
|
#at this point one task has died or we have the line in the log
|
|
if self.task_ue.waitlog_state != WAITLOG_SUCCESS:
|
|
log("ERROR: ALU test: " + ue + " UE did not connect")
|
|
raise TestFailed()
|
|
|
|
self.event.clear()
|
|
|
|
if ( (self.task_enb != None and not self.task_enb.alive()) or
|
|
(self.task_rru_enb!=None and not self.task_rru_enb.alive()) or
|
|
(self.task_rcc_enb!=None and not self.task_rcc_enb.alive()) or
|
|
not self.task_hss.alive() or
|
|
not self.task_ue.alive()):
|
|
log("ERROR: ALU test: eNB, HSS or UE task died")
|
|
raise TestFailed()
|
|
|
|
#get UE IP
|
|
l = open(self.task_ue.logfile, "r").read()
|
|
self.ue_ip = re.search("local IP address (.*)\n", l) \
|
|
.groups()[0]
|
|
log("INFO: ALU test: " + ue + " UE IP address: " + self.ue_ip)
|
|
|
|
##########################################################################
|
|
# stop_ue
|
|
##########################################################################
|
|
def stop_ue(self, ue):
|
|
log("INFO: ALU test: stop " + ue + " UE")
|
|
self.task_ue.sendnow("%c" % 3)
|
|
ret = self.task_ue.wait()
|
|
if ret != 0:
|
|
log("ERROR: ALU test: task " + ue + " UE failed")
|
|
#not sure if we have to quit here or not
|
|
#os._exit(1)
|
|
|
|
##########################################################################
|
|
# _do_traffic (internal function, do not call out of the class)
|
|
##########################################################################
|
|
def _do_traffic(self, name,
|
|
server_code, server_machine, server_ip,
|
|
client_code, client_machine,
|
|
waitlog,
|
|
server_logfile, client_logfile,
|
|
udp_bandwidth=None):
|
|
log("INFO: ALU test: run traffic: " + name)
|
|
|
|
log("INFO: ALU test: launch server")
|
|
task_traffic_server = Task("actions/" + server_code + ".bash",
|
|
server_logfile,
|
|
server_machine,
|
|
self.oai_user,
|
|
self.oai_password,
|
|
self.env,
|
|
self.logdir + "/" + server_logfile + "." + server_machine,
|
|
event=self.event)
|
|
task_traffic_server.waitlog(waitlog)
|
|
|
|
env = list(self.env)
|
|
if udp_bandwidth != None:
|
|
env.append("UDP_BANDWIDTH=" + udp_bandwidth)
|
|
env.append("SERVER_IP=" + server_ip)
|
|
|
|
log("INFO: ALU test: launch client")
|
|
task_traffic_client = Task("actions/" + client_code + ".bash",
|
|
client_logfile,
|
|
client_machine,
|
|
self.oai_user,
|
|
self.oai_password,
|
|
env,
|
|
self.logdir + "/" + client_logfile + "." + client_machine,
|
|
event=self.event)
|
|
log("INFO: ALU test: wait for client to finish (or some error)")
|
|
|
|
self.event.wait()
|
|
log("DEBUG: event.wait() done")
|
|
|
|
if ( (self.task_enb != None and not self.task_enb.alive()) or
|
|
(self.task_rru_enb!=None and not self.task_rru_enb.alive()) or
|
|
(self.task_rcc_enb!=None and not self.task_rcc_enb.alive()) or
|
|
not self.task_hss.alive() or
|
|
not self.task_ue.alive()):
|
|
log("ERROR: unexpected task exited, test failed, kill all")
|
|
if task_traffic_client.alive():
|
|
task_traffic_client.kill()
|
|
if (self.task_enb != None and self.task_enb.alive()):
|
|
self.task_enb.kill()
|
|
if (self.task_rru_enb != None and self.task_rru_enb.alive()):
|
|
self.task_rru_enb.kill()
|
|
if (self.task_rcc_enb != None and self.task_rcc_enb.alive()):
|
|
self.task_rcc_enb.kill()
|
|
if self.task_ue.alive():
|
|
self.task_ue.kill()
|
|
|
|
ret = task_traffic_client.wait()
|
|
if ret != 0:
|
|
log("ERROR: ALU test: downlink traffic failed")
|
|
#not sure if we have to quit here or not
|
|
#os._exit(1)
|
|
|
|
#stop downlink server
|
|
#log("INFO: ALU test: stop server (kill ssh connection)")
|
|
#task_traffic_server.kill()
|
|
log("INFO: ALU test: stop server (ctrl+z then kill -9 %1)")
|
|
task_traffic_server.sendnow("%ckill -9 %%1 || true\n" % 26)
|
|
log("INFO: ALU test: wait for server to quit")
|
|
task_traffic_server.wait()
|
|
|
|
self.event.clear()
|
|
|
|
if ( (self.task_enb != None and not self.task_enb.alive()) or
|
|
(self.task_rru_enb!=None and not self.task_rru_enb.alive()) or
|
|
(self.task_rcc_enb!=None and not self.task_rcc_enb.alive()) or
|
|
not self.task_hss.alive() or
|
|
not self.task_ue.alive()):
|
|
log("ERROR: ALU test: eNB, HSS or UE task died")
|
|
raise TestFailed()
|
|
|
|
##########################################################################
|
|
# dl_tcp
|
|
##########################################################################
|
|
def dl_tcp(self, ue):
|
|
self._do_traffic(ue + " downlink TCP",
|
|
"server_tcp", self.ue_machine, self.ue_ip,
|
|
"client_tcp", self.epc_machine,
|
|
"Server listening on TCP port 5001",
|
|
ue + "_downlink_tcp_server",
|
|
ue + "_downlink_tcp_client")
|
|
|
|
##########################################################################
|
|
# ul_tcp
|
|
##########################################################################
|
|
def ul_tcp(self, ue):
|
|
self._do_traffic(ue + " uplink TCP",
|
|
"server_tcp", self.epc_machine, "192.172.0.1",
|
|
"client_tcp", self.ue_machine,
|
|
"Server listening on TCP port 5001",
|
|
ue + "_uplink_tcp_server",
|
|
ue + "_uplink_tcp_client")
|
|
|
|
##########################################################################
|
|
# dl_udp
|
|
##########################################################################
|
|
def dl_udp(self, ue, bandwidth):
|
|
self._do_traffic(ue + " downlink UDP",
|
|
"server_udp", self.ue_machine, self.ue_ip,
|
|
"client_udp", self.epc_machine,
|
|
"Server listening on UDP port 5001",
|
|
ue + "_downlink_udp_server",
|
|
ue + "_downlink_udp_client",
|
|
udp_bandwidth=bandwidth)
|
|
|
|
##########################################################################
|
|
# ul_udp
|
|
##########################################################################
|
|
def ul_udp(self, ue, bandwidth):
|
|
self._do_traffic(ue + " uplink UDP",
|
|
"server_udp", self.epc_machine, "192.172.0.1",
|
|
"client_udp", self.ue_machine,
|
|
"Server listening on UDP port 5001",
|
|
ue + "_uplink_udp_server",
|
|
ue + "_uplink_udp_client",
|
|
udp_bandwidth=bandwidth)
|
|
|
|
##############################################################################
|
|
# run_b210_alu
|
|
##############################################################################
|
|
|
|
def run_b210_alu(tests, openair_dir, oai_user, oai_password, env):
|
|
|
|
#compile eNB (two cases: one for FDD and one for TDD)
|
|
|
|
if do_tests(tests['b210']['alu']['fdd']):
|
|
alu = alu_test(epc='amerique', enb='hutch', ue='stevens',
|
|
openair=openair_dir,
|
|
user=oai_user, password=oai_password,
|
|
log_subdir='enb_tests/b210_alu/compile_enb_fdd',
|
|
env=env)
|
|
|
|
try:
|
|
alu.compile_enb("--eNB -w USRP -x -c --disable-cpu-affinity")
|
|
except BaseException, e:
|
|
log("ERROR: ALU test failed: eNB compilation failed: " + str(e))
|
|
return
|
|
|
|
if do_tests(tests['b210']['alu']['tdd']):
|
|
alu = alu_test(epc='amerique', enb='calisson', ue='mozart',
|
|
openair=openair_dir,
|
|
user=oai_user, password=oai_password,
|
|
log_subdir='enb_tests/b210_alu/compile_enb_tdd',
|
|
env=env)
|
|
|
|
try:
|
|
alu.compile_enb("--eNB -w USRP -x -c --disable-cpu-affinity")
|
|
except BaseException, e:
|
|
log("ERROR: ALU test failed: eNB compilation failed: " + str(e))
|
|
return
|
|
|
|
#compile RRU/RCC eNB
|
|
|
|
if do_tests(tests['remote b210']['alu']['fdd']):
|
|
#RRU
|
|
alu = alu_test(epc='amerique', ue='stevens',
|
|
openair=openair_dir,
|
|
user=oai_user, password=oai_password,
|
|
log_subdir='enb_tests/remote_b210_alu/compile_enb_rru',
|
|
env=env,
|
|
#hack: set 'enb' to reuse 'compile_enb'
|
|
enb = 'superserver',
|
|
enb_rru = 'superserver', enb_rcc = 'starsky')
|
|
|
|
try:
|
|
alu.compile_enb("--eNB -x -c -w USRP -t ETHERNET",
|
|
log_suffix='rru.')
|
|
except BaseException, e:
|
|
log("ERROR: ALU test failed: RRU eNB compilation failed: "+str(e))
|
|
return
|
|
|
|
#RCC
|
|
alu = alu_test(epc='amerique', ue='stevens',
|
|
openair=openair_dir,
|
|
user=oai_user, password=oai_password,
|
|
log_subdir='enb_tests/remote_b210_alu/compile_enb_rcc',
|
|
env=env,
|
|
#hack: set 'enb' to reuse 'compile_enb'
|
|
enb = 'starsky',
|
|
enb_rru = 'superserver', enb_rcc = 'starsky')
|
|
|
|
try:
|
|
alu.compile_enb("--eNB -w None -t ETHERNET",
|
|
log_suffix='rcc.')
|
|
except BaseException, e:
|
|
log("ERROR: ALU test failed: RCC eNB compilation failed: "+str(e))
|
|
return
|
|
|
|
|
|
#run tests
|
|
|
|
udp_dl_bandwidth = { "5" : "15M",
|
|
"10" : "30M",
|
|
"20" : "60M" }
|
|
|
|
udp_ul_bandwidth = { "5" : "7M",
|
|
"10" : "15M",
|
|
"20" : "15M" }
|
|
|
|
ue_machine = { "fdd" : "stevens",
|
|
"tdd" : "mozart" }
|
|
|
|
enb_machine = { "fdd" : "hutch",
|
|
"tdd" : "calisson" }
|
|
|
|
band = { "fdd" : "7",
|
|
"tdd" : "38" }
|
|
|
|
for mode in ('fdd', 'tdd'):
|
|
for bw in ('5', '10', '20'):
|
|
if do_tests(tests['b210']['alu'][mode][bw]):
|
|
log("INFO: ALU test: run tests for bandwidth " + bw + " MHz")
|
|
ctest = tests['b210']['alu'][mode][bw]
|
|
alu = alu_test(epc='amerique', enb=enb_machine[mode], ue=ue_machine[mode],
|
|
openair=openair_dir,
|
|
user=oai_user, password=oai_password,
|
|
log_subdir='enb_tests/b210_alu/' + mode + "/" + bw,
|
|
env=env)
|
|
try:
|
|
alu.start_epc()
|
|
alu.start_enb("enb.band" + band[mode] + ".tm1.usrpb210." + mode + "." + bw + "MHz.conf")
|
|
for ue in ('bandrich', '3276'):
|
|
if ue in ctest and do_tests(ctest[ue]):
|
|
alu.start_ue(ue)
|
|
if do_tests(ctest[ue]['tcp']['dl']): alu.dl_tcp(ue)
|
|
if do_tests(ctest[ue]['tcp']['ul']): alu.ul_tcp(ue)
|
|
if do_tests(ctest[ue]['udp']['dl']): alu.dl_udp(ue, udp_dl_bandwidth[bw])
|
|
if do_tests(ctest[ue]['udp']['ul']): alu.ul_udp(ue, udp_ul_bandwidth[bw])
|
|
alu.stop_ue(ue)
|
|
alu.stop_enb()
|
|
alu.stop_epc()
|
|
except BaseException, e:
|
|
log("ERROR: ALU test failed: " + str(e))
|
|
alu.finish()
|
|
if do_tests(tests['remote b210']['alu'][mode][bw]):
|
|
log("INFO: ALU test: run RRU/RCC tests for bandwidth " + bw + " MHz")
|
|
ctest = tests['remote b210']['alu'][mode][bw]
|
|
alu = alu_test(epc='amerique', enb='', ue=ue_machine[mode],
|
|
openair=openair_dir,
|
|
user=oai_user, password=oai_password,
|
|
log_subdir='enb_tests/remote_b210_alu/' + bw,
|
|
env=env,
|
|
enb_rru='superserver', enb_rcc='starsky')
|
|
try:
|
|
alu.start_epc()
|
|
alu.start_enb_rru_rcc("rru.band7.tm1.if4p5." + bw + "MHz.udp.usrpb210.conf",
|
|
"rcc.band7.tm1.if4p5." + bw + "MHz.conf")
|
|
for ue in ('bandrich', '3276'):
|
|
if ue in ctest and do_tests(ctest[ue]):
|
|
alu.start_ue(ue)
|
|
if do_tests(ctest[ue]['tcp']['dl']): alu.dl_tcp(ue)
|
|
if do_tests(ctest[ue]['tcp']['ul']): alu.ul_tcp(ue)
|
|
if do_tests(ctest[ue]['udp']['dl']): alu.dl_udp(ue, udp_dl_bandwidth[bw])
|
|
if do_tests(ctest[ue]['udp']['ul']): alu.ul_udp(ue, udp_ul_bandwidth[bw])
|
|
alu.stop_ue(ue)
|
|
alu.stop_enb_rru_rcc()
|
|
alu.stop_epc()
|
|
except BaseException, e:
|
|
log("ERROR: ALU test failed: " + str(e))
|
|
alu.finish()
|