Skip to content
Snippets Groups Projects
Commit 1f95f48f authored by Cédric Roux's avatar Cédric Roux
Browse files

first version of v2 test setup

The old one is still usable by replacing .gitlab-ci.yml with
the previous version.
parent b29f6bc7
No related branches found
No related tags found
No related merge requests found
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):
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.task_hss = None
self.task_enb = None
self.task_ue = 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()
##########################################################################
# 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("INFO: ALU test: compile softmodem")
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." + 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_bandrich_ue
##########################################################################
def start_bandrich_ue(self):
log("INFO: ALU test: start bandrich UE")
self.task_ue = Task("actions/start_bandrich.bash",
"start_bandrich",
self.ue_machine,
self.oai_user,
self.oai_password,
self.env,
self.logdir + "/start_bandrich." + 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: bandrich UE did not connect")
raise TestFailed()
self.event.clear()
if ( not self.task_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 bandrich UE IP
l = open(self.task_ue.logfile, "r").read()
self.bandrich_ue_ip = re.search("local IP address (.*)\n", l) \
.groups()[0]
log("INFO: ALU test: bandrich UE IP address: " + self.bandrich_ue_ip)
##########################################################################
# stop_bandrich_ue
##########################################################################
def stop_bandrich_ue(self):
log("INFO: ALU test: stop bandrich UE")
self.task_ue.sendnow("%c" % 3)
ret = self.task_ue.wait()
if ret != 0:
log("ERROR: ALU test: task bandrich 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 ( not self.task_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_epc.alive():
task_traffic_epc.kill()
if self.task_enb.alive():
self.task_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 ( not self.task_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):
self._do_traffic("bandrich downlink TCP",
"server_tcp", self.ue_machine, self.bandrich_ue_ip,
"client_tcp", self.epc_machine,
"Server listening on TCP port 5001",
"bandrich_downlink_tcp_server",
"bandrich_downlink_tcp_client")
##########################################################################
# ul_tcp
##########################################################################
def ul_tcp(self):
self._do_traffic("bandrich uplink TCP",
"server_tcp", self.epc_machine, "192.172.0.1",
"client_tcp", self.ue_machine,
"Server listening on TCP port 5001",
"bandrich_uplink_tcp_server",
"bandrich_uplink_tcp_client")
##########################################################################
# dl_udp
##########################################################################
def dl_udp(self, bandwidth):
self._do_traffic("bandrich downlink UDP",
"server_udp", self.ue_machine, self.bandrich_ue_ip,
"client_udp", self.epc_machine,
"Server listening on UDP port 5001",
"bandrich_downlink_udp_server",
"bandrich_downlink_udp_client",
udp_bandwidth=bandwidth)
##########################################################################
# ul_udp
##########################################################################
def ul_udp(self, bandwidth):
self._do_traffic("bandrich uplink UDP",
"server_udp", self.epc_machine, "192.172.0.1",
"client_udp", self.ue_machine,
"Server listening on UDP port 5001",
"bandrich_uplink_udp_server",
"bandrich_uplink_udp_client",
udp_bandwidth=bandwidth)
##############################################################################
# run_b210_alu
##############################################################################
def run_b210_alu(tests, openair_dir, oai_user, oai_password, env):
if not do_tests(tests['b210']['alu']):
return
#compile eNB
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',
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
#run tests
udp_dl_bandwidth = { "5" : "15M",
"10" : "30M",
"20" : "60M" }
udp_ul_bandwidth = { "5" : "7M",
"10" : "15M",
"20" : "15M" }
for bw in ('5', '10', '20'):
if do_tests(tests['b210']['alu'][bw]):
log("INFO: ALU test: run tests for bandwidth " + bw + " MHz")
ctest = tests['b210']['alu'][bw]
alu = alu_test(epc='amerique', enb='hutch', ue='stevens',
openair=openair_dir,
user=oai_user, password=oai_password,
log_subdir='enb_tests/b210_alu/' + bw,
env=env)
try:
alu.start_epc()
alu.start_enb("enb.band7.tm1.usrpb210." + bw + "MHz.conf")
if do_tests(ctest['bandrich']):
alu.start_bandrich_ue()
if do_tests(ctest['bandrich']['tcp']['dl']): alu.dl_tcp()
if do_tests(ctest['bandrich']['tcp']['ul']): alu.ul_tcp()
if do_tests(ctest['bandrich']['udp']['dl']):
alu.dl_udp(udp_dl_bandwidth[bw])
if do_tests(ctest['bandrich']['udp']['ul']):
alu.ul_udp(udp_ul_bandwidth[bw])
alu.stop_bandrich_ue()
alu.stop_enb()
alu.stop_epc()
except BaseException, e:
log("ERROR: ALU test failed: " + str(e))
alu.finish()
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1";
mobile_country_code = "208";
mobile_network_code = "92";
////////// Physical parameters:
component_carriers = (
{
node_function = "eNodeB_3GPP";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 50;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -24;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -103;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -104;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.26";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.19/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.19/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1";
mobile_country_code = "208";
mobile_network_code = "92";
////////// Physical parameters:
component_carriers = (
{
node_function = "eNodeB_3GPP";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 100;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -24;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -103;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -104;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.26";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.19/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.19/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1";
mobile_country_code = "208";
mobile_network_code = "92";
////////// Physical parameters:
component_carriers = (
{
node_function = "eNodeB_3GPP";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -24;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -103;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -104;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.26";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.19/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.19/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
import os, subprocess, time, fcntl, termios, tty, signal, thread
from utils import log
class connection:
def __init__(self, description, host, user, password):
self.description = description
self.host = host
self.user = user
self.password = password
self.sendlock = thread.allocate_lock()
try:
(pid, fd) = os.forkpty()
except BaseException, e:
log("ERROR: forkpty for '" + description + "': " + e)
(pid, fd) = (-1, -1)
if pid == -1:
log("ERROR: creating connection for '" + description + "'")
os._exit(1)
# child process, run ssh
if pid == 0:
try:
os.execvp('sshpass', ['sshpass', '-p', password,
'ssh', user + '@' + host])
except BaseException, e:
log("ERROR: execvp for '" + description + "': " + e)
log("ERROR: execvp failed for '" + description + "'")
os._exit(1)
# parent process
# make the TTY raw to avoid getting input printed and no ^M
try:
tty.setraw(fd, termios.TCSANOW)
except BaseException, e:
log("ERROR: failed configuring TTY: " + str(e))
os._exit(1)
# try:
# fcntl.fcntl(fd, fcntl.F_SETFL,
# fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
# except:
# log("ERROR: fcntl failed for '" + description + "'")
# os._exit(1)
self.pid = pid
self.fd = fd
self.active = True
self.retcode = -1
def send(self, string):
if self.active == False:
log("ERROR: send: child is dead for '" + self.description + "'")
return -1
try:
(pid, out) = os.waitpid(self.pid, os.WNOHANG)
except BaseException, e:
log("ERROR: send: waitpid failed for '" + self.description +
"': " + str(e))
(pid, out) = (self.pid, 1)
if pid != 0:
log("ERROR: send: child process dead for '" +
self.description + "'")
try:
os.close(self.fd)
except BaseException, e:
#we don't care about errors at this point
pass
self.active = False
self.retcode = out
return -1
self.sendlock.acquire()
length = len(string)
while length != 0:
try:
ret = os.write(self.fd, string)
except BaseException, e:
log("ERROR: send fails for '" + self.description + "': " +
str(e))
os._exit(1)
if ret == 0:
log("ERROR: send: write returns 0 for '" +
self.description + "'")
os._exit(1)
length = length - ret
string = string[ret:]
self.sendlock.release()
return 0
def kill(self, signal=signal.SIGTERM):
log("INFO: kill connection '" + self.description + "'")
try:
os.kill(self.pid, signal)
except BaseException, e:
log("ERROR: connection.kill: " + str(e))
import threading, os
from utils import log
class MachineWaiterThread(threading.Thread):
def __init__(self, machine, tasks):
threading.Thread.__init__(self)
self.machine = machine
self.tasks = tasks
def run(self):
try:
for task in self.tasks:
ret = task.wait()
if ret != 0:
log("ERROR: task '" + task.description + "' failed " +
"on machine " + self.machine.name)
task.postaction()
self.machine.unbusy()
except BaseException, e:
log("ERROR: MachineWaiterThread: " + str(e))
os._exit(1)
class Machine():
def __init__(self, machine, cond):
self.name = machine
self.free = True
self.cond = cond
def busy(self, tasks):
waiter = MachineWaiterThread(self, tasks)
waiter.start()
def unbusy(self):
self.cond.acquire()
self.free = True
self.cond.notify()
self.cond.release()
class MachineList():
def __init__(self, list):
self.list = []
self.cond = threading.Condition()
for m in list:
self.list.append(Machine(m, self.cond))
def get_free_machine(self):
try:
self.cond.acquire()
while True:
free_machine = None
for m in self.list:
if m.free == True:
free_machine = m
break
if free_machine != None:
break
self.cond.wait()
free_machine.free = False
self.cond.release()
except BaseException, e:
log("ERROR: machine_list: " + str(e))
os._exit(1)
return free_machine
def wait_all_free(self):
try:
self.cond.acquire()
while True:
all_free = True
for m in self.list:
if m.free == False:
all_free = False
break
if all_free == True:
break
self.cond.wait()
self.cond.release()
except BaseException, e:
log("ERROR: machine_list: " + str(e))
os._exit(1)
This diff is collapsed.
import os, time, threading, sys, os, errno, select
from connection import connection
import utils
from utils import log
#this class is to communicate between reader and sender threads
#the reader increments a count each time it receives the prompt
#and wakes up the sender
#it also indicates when it exits so the sender can exit too
#the sender (calling get) waits for the count to be greated than passed
#argument or if reader exited
#it returns argument+1 if things okay, -1 if reader exited
class Counter:
def __init__(self):
self.count = 0
self.cond = threading.Condition()
def inc(self):
self.cond.acquire()
self.count = self.count + 1
self.cond.notify()
self.cond.release()
def set(self, value):
self.cond.acquire()
self.count = value
self.cond.notify()
self.cond.release()
def get(self, current):
self.cond.acquire()
while True:
if self.count == -1:
ret = -1
break
if self.count >= current + 1:
ret = current + 1
break
self.cond.wait()
self.cond.release()
return ret
#this class is used for the main application to wait for some specific
#output from the remote program (typically the ALU HSS prompt, indicating
#it is ready and we can proceed further)
#(too much classes...)
class ProducerConsumer:
def __init__(self):
self.count = 0
self.cond = threading.Condition()
def add(self, v):
self.cond.acquire()
self.count = self.count + v
self.cond.notify()
self.cond.release()
def set(self, v):
self.cond.acquire()
self.count = v
self.cond.notify()
self.cond.release()
def get(self, old):
self.cond.acquire()
while True:
if self.count == -1:
ret = -1
break
if self.count > old:
ret = self.count
break
self.cond.wait()
self.cond.release()
return ret
#this thread gets input from the child process of the task
#it removes the prompts it gets (be carefully to use a prompt
#that will not be output of any command otherwise you dead)
class ReaderThread(threading.Thread):
def __init__(self, fdin, logfile, prompt, prompt_counter, producer):
threading.Thread.__init__(self)
self.fdin = fdin
self.logfile = logfile
self.prompt_counter = prompt_counter
self.prompt = prompt
self.promptsize = len(prompt)
self.stack = ""
self.stacksize = 0
self.producer = producer
def run(self):
try:
outfile = open(self.logfile, "w")
except BaseException, e:
log("ERROR: ReaderThread: " + self.logfile + ": " + str(e))
os._exit(1)
while True:
try:
(a, b, c) = select.select([ self.fdin ], [], [ self.fdin ])
except BaseException, e:
log("ERROR: ReaderThread: " + self.logfile +
": select failed: " + str(e))
os._exit(1)
try:
z = os.read(self.fdin, 1024)
except OSError, e:
if e.errno == errno.EIO:
#pipe has died, quit the thread
break
else:
log("ERROR: ReaderThread: " + self.logfile +
": unhandled error: " + str(e))
except BaseException, e:
log("ERROR: ReaderThread: " + self.logfile +
": unhandled error: " + str(e))
break
try:
produced = 0
#this part is to remove the prompt
for x in z:
if x == self.prompt[self.stacksize]:
self.stack = self.stack + x
self.stacksize = self.stacksize + 1
if self.stacksize == self.promptsize:
self.prompt_counter.inc()
self.stack = ""
self.stacksize = 0
else:
outfile.write(self.stack)
outfile.write(x)
produced = produced + len(self.stack) + len(x)
self.stack = ""
self.stacksize = 0
outfile.flush()
self.producer.add(produced)
except BaseException, e:
log("ERROR: ReaderThread: " + self.logfile + ": " + str(e))
os._exit(1)
try:
outfile.close()
except BaseException, e:
log("ERROR: ReaderThread: " + self.logfile + ": " + str(e))
os._exit(1)
#close the pipe, don't care about errors
try:
os.close(self.fdin)
except:
pass
#signal sender to quit
self.prompt_counter.set(-1)
self.producer.set(-1)
class SenderQuit(Exception):
pass
#this thread sends commands to the child process of the task
#it waits for the prompt between each command
#'event' is used for the main thread to wait for one of several tasks
#to quit, meaning error or end-of-test
class SenderThread(threading.Thread):
def __init__(self, fdout, prompt_counter, connection, env, action,
description, prompt, event=None):
threading.Thread.__init__(self)
self.fdin = fdout
self.prompt_counter = prompt_counter
self.connection = connection
self.env = env
self.action = action
self.description = description
self.prompt = prompt
self.count = 0
self.event = event
self.alive = True
def wait_prompt(self):
self.count = self.prompt_counter.get(self.count)
if self.count == -1:
raise SenderQuit()
def _run(self):
self.connection.send('export PS1=' + self.prompt + '\n')
self.wait_prompt()
self.connection.send('set +o emacs\n')
self.wait_prompt()
self.connection.send('echo\n')
self.wait_prompt()
self.connection.send('echo\n')
self.wait_prompt()
self.connection.send("echo -e '" + utils.GREEN +
'---------------------------------------------'
+ utils.RESET + "'\n")
self.wait_prompt()
self.connection.send('echo\n')
self.wait_prompt()
self.connection.send("echo -n -e '" + utils.YELLOW +
"COMMANDS START: " +
utils.RESET + "'\n")
self.wait_prompt()
self.connection.send('date\n')
self.wait_prompt()
for l in self.env:
self.connection.send('export ' + l + '\n')
self.wait_prompt()
with open(self.action) as f:
for line in f:
self.connection.send("echo -n -e '" + utils.GREEN +
"RUNNING: " + utils.RESET + "'\n")
self.wait_prompt()
self.connection.send("echo '" +
line.replace('\n','')
.replace("'", "'\\''") + "'\n")
self.wait_prompt()
self.connection.send(line)
self.wait_prompt()
self.connection.send("if [ $? != 0 ]; then " +
"echo -e '" + utils.RED +
"TEST_SETUP_ERROR: " + utils.RESET +
"last command failed, exiting'; " +
"date; exit 1; fi\n")
self.wait_prompt()
self.connection.send("echo -n -e '" + utils.YELLOW +
"COMMANDS DONE: " +
utils.RESET + "'\n")
self.wait_prompt()
self.connection.send('date\n')
self.wait_prompt()
self.connection.send("echo -e '" + utils.GREEN +
"TEST_SETUP_SUCCESS" + utils.RESET + "'\n")
self.wait_prompt()
self.connection.send('exit\n')
def run(self):
try:
self._run()
except SenderQuit:
log("WARNING: '" + self.description + "' exits too early?")
pass
except BaseException, e:
log("ERROR: task failed: " + str(e))
log("ERROR: action is: " + self.action)
log("ERROR: description is: " + self.description)
os._exit(1)
self.alive = False
if self.event != None:
self.event.set()
WAITLOG_RUNNING = 0
WAITLOG_SUCCESS = 1
WAITLOG_FAILURE = 2
class WaitlogFailed(Exception):
pass
#'event' is used by main thread to wait for any of several threads to quit.
#'Task' passes it the 'SenderThread' above, which sets it when it finishes.
class Task:
def __init__(self, action, description, machine, user, password, env,
logfile, post_action = None, event=None):
self.action = action
self.description = description
self.machine = machine
self.user = user
self.password = password
self.post_action = post_action
self.producer = ProducerConsumer()
self.logfile = logfile
prompt = "__OAI_TEST_SETUP_PROMPT__:"
prompt_counter = Counter()
self.connection = connection(description, machine, user, password)
self.reader = ReaderThread(self.connection.fd, logfile, prompt,
prompt_counter, self.producer)
self.reader.start()
self.sender = SenderThread(self.connection.fd, prompt_counter,
self.connection, env, action, description,
prompt, event)
self.sender.start()
def wait(self, timeout=-1):
if self.connection.active == False:
return self.connection.retcode
try:
(pid, ret) = os.waitpid(self.connection.pid, 0)
except KeyboardInterrupt, e:
log("ERROR: ctrl+c catched! " + str(e))
os._exit(1)
except BaseException, e:
log("ERROR: " + str(e))
os._exit(1)
self.sender.join()
self.reader.join()
return ret
#this function should not be called, it is used internally by 'waitlog'
#in mode 'background thread'
#TODO: join() the thread at some point
def _waitlog_thread(self, task, s):
consumed = 0
while True:
consumed = task.producer.get(consumed)
if consumed == -1:
log("ERROR: string '" + s + "' not found in logfile " +
task.logfile)
task.waitlog_state = WAITLOG_FAILURE
task.waitlog_event.set()
return
if s in open(task.logfile).read():
task.waitlog_state = WAITLOG_SUCCESS
task.waitlog_event.set()
return
#two ways to wait for a string in the log file:
# - blocking way
# - background thread, using an Event to signal success/failure
def waitlog(self, s, event=None):
if event != None:
self.waitlog_state = WAITLOG_RUNNING
self.waitlog_event = event
self.waitlog_thread = \
threading.Thread(target=self._waitlog_thread,
args=(self, s))
self.waitlog_thread.start()
return
#TODO: optimize, do not process all the file at each wakeup
consumed = 0
while True:
consumed = self.producer.get(consumed)
if consumed == -1:
log("ERROR: string '" + s + "' not found in logfile " +
self.logfile)
raise WaitlogFailed()
if s in open(self.logfile).read():
return
def sendnow(self, x):
self.connection.send(x)
def alive(self):
return self.sender.alive
def kill(self):
self.connection.kill()
#put some error log in logfile, for verbosity
try:
f = open(self.logfile, "a+")
f.write("\n\n" + utils.RED + "TEST_SETUP_ERROR: " + utils.RESET +
"task killed by test setup\n\n");
close(f)
except BaseException, e:
pass
def postaction(self):
if self.post_action != None:
out = utils.quickshell(self.post_action)
if len(out):
log("INFO: task '" + self.description +
"' post_action '" + self.post_action + "' says: ")
for l in out.splitlines():
log("INFO: " + l)
import subprocess, os, thread, sys, time
#logging facitiliy
#TODO: simplify (a first version redefined stdout, then we replaced 'print'
#instead, keeping stuff as is)
class Logger:
def __init__(self, stream):
self.stream = stream
self.start_of_line = True
self.lock = thread.allocate_lock()
openair_dir = os.environ.get('OPENAIR_DIR')
if openair_dir == None:
print "FATAL: no OPENAIR_DIR"
os._exit(1)
try:
self.logfile = open(openair_dir +
"/cmake_targets/autotests/log/python.stdout", "w")
except BaseException, e:
print "FATAL: cannot create log file"
print e
os._exit(1)
def put(self, data):
self.stream.write(data)
self.logfile.write(data)
def write(self, data):
self.lock.acquire()
for c in data:
if self.start_of_line:
self.start_of_line = False
t = time.strftime("%H:%M:%S", time.localtime()) + ": "
self.stream.write(t)
self.logfile.write(t)
self.put(c)
if c == '\n':
self.start_of_line = True
self.stream.flush()
self.logfile.flush()
self.lock.release()
logger = Logger(sys.stdout)
def log(x):
logger.write(x + "\n")
#check if given test is in list
#it is in list if one of the strings in 'list' is at the beginning of 'test'
def test_in_list(test, list):
for check in list:
check=check.replace('+','')
if (test.startswith(check)):
return True
return False
#run a local command in a shell
def quickshell(command):
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
(retout, reterr) = process.communicate()
if (process.returncode != 0):
log("ERROR: shell command failed: " + command)
if len(retout):
log("ERROR: command says: ")
for l in retout.splitlines():
log("ERROR: " + l)
os._exit(1)
return retout
RED="\x1b[31m"
GREEN="\x1b[32m"
YELLOW="\x1b[33m"
RESET="\x1b[m"
#an exception raised when a test fails
class TestFailed(Exception):
pass
#this function returns True if a test in 'x' is set to True
#to be used as: if do_tests(tests['b210']['alu']) ...
def do_tests(x):
if type(x) == list:
for v in x:
if do_tests(v): return True
return False
if type(x) == dict: return do_tests(x.values())
if x == True: return True
return False
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment