Commit 6bac53c8 authored by hardy's avatar hardy

Merge remote-tracking branch 'origin/ci_quectel_support' into rh_ci_nsa_test_n310

parents 80a9aaf5 ca4bcf10
ranRepository : https://gitlab.eurecom.fr/oai/openairinterface5g.git
ranBranch : BRANCH_NAME
ranCommitID : COMMIT_ID
ranAllowMerge : 'true'
ranBranch : integration_2021_wk13_a
ranCommitID : 104aa7eed5d6702c1b9da663414079ef698da206
ranAllowMerge : 'yes'
ranTargetBranch : develop
steps:
- InitiateHtml,none
- TesteNB,xml_files/fr1_multi_node_build.xml
- TesteNB,xml_files/fr1_epc_start.xml
- TesteNB,xml_files/fr1_ran_ue_base.xml #ue toggle, nodes initialize, ue toggle, ping, nodes terminate
- TesteNB,xml_files/fr1_nsa_base_next.xml #ue toggle, nodes initialize, ue toggle, ping, nodes terminate
- TesteNB,xml_files/fr1_epc_closure.xml
......
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements. See the NOTICE file distributed with
# * this work for additional information regarding copyright ownership.
# * The OpenAirInterface Software Alliance licenses this file to You under
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
# * except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.openairinterface.org/?page_id=698
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *-------------------------------------------------------------------------------
# * For more information about the OpenAirInterface (OAI) Software Alliance:
# * contact@openairinterface.org
# */
#---------------------------------------------------------------------
#
# Required Python Version
# Python 3.x
#
#---------------------------------------------------------------------
import sys
import time
import serial
class qtel_ctl:
#---------------
#private methods
#---------------
def __init__(self, usb_port_at):
self.QUECTEL_USB_PORT_AT = usb_port_at #ex : '/dev/ttyUSB2'
self.modem = serial.Serial(self.QUECTEL_USB_PORT_AT, timeout=1)
self.cmd_dict= {"wup": self.wup,"detach":self.detach}#dictionary of function pointers
def __set_modem_state(self,ser,state):
self.__send_command(ser,"AT+CFUN={}\r".format(state))
def __send_command(self,ser,com):
if ser.inWaiting() > 0:
ser.flushInput()
ser.write(com.encode())
#--------------
#public methods
#--------------
def wup(self):#sending AT+CFUN=0, then AT+CFUN=1
self.__set_modem_state(self.modem,0)
time.sleep(3)
self.__set_modem_state(self.modem,1)
def detach(self):#sending AT+CFUN=0
self.__set_modem_state(self.modem,0)
if __name__ == "__main__":
#argv[1] : usb port
#argv[2] : qtel command (see function pointers dict "wup", "detach" etc ...)
command = sys.argv[2]
Module=qtel_ctl(sys.argv[1])
#calling the function to be applied
Module.cmd_dict[command]()
idefix:
ID: idefix
State : enabled
Kind : quectel
Process : quectel-CM
WakeupScript : ci_ctl_qtel.py /dev/ttyUSB2 wup
DetachScript : ci_ctl_qtel.py /dev/ttyUSB2 detach
UENetwork : wwan0
HostIPAddress : 192.168.18.188
HostUsername : oaicicd
HostPassword : oaicicd
HostSourceCodePath : none
dummy:
ID: dummy
dummy2:
ID: dummy2
Kind : cots
State : disabled
Process : quectel-cm
HostIPAddress : 192.168.18.186
HostUsername : oaicicd
HostPassword : oaicicd
HostSourceCodePath : none
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements. See the NOTICE file distributed with
# * this work for additional information regarding copyright ownership.
# * The OpenAirInterface Software Alliance licenses this file to You under
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
# * except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.openairinterface.org/?page_id=698
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *-------------------------------------------------------------------------------
# * For more information about the OpenAirInterface (OAI) Software Alliance:
# * contact@openairinterface.org
# */
#---------------------------------------------------------------------
#
# Required Python Version
# Python 3.x
#
#---------------------------------------------------------------------
#to use isfile
import os
import sys
import logging
#to create a SSH object locally in the methods
import sshconnection
#time.sleep
import time
#to load ue infrastructure dictionary
import yaml
class InfraUE:
def __init__(self):
self.ci_ue_infra ={}
#-----------------$
#PUBLIC Methods$
#-----------------$
#This method reads the yaml file describing the multi-UE infrastructure
#and stores the infra permanently in the related class attribute self.ci_ue_infra
def Get_UE_Infra(self,ue_infra_filename):
f_yaml=ue_infra_filename
with open(f_yaml,'r') as file:
logging.debug('Loading UE infrastructure from file '+f_yaml)
#load it permanently in the class attribute
self.ci_ue_infra = yaml.load(file,Loader=yaml.FullLoader)
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements. See the NOTICE file distributed with
# * this work for additional information regarding copyright ownership.
# * The OpenAirInterface Software Alliance licenses this file to You under
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
# * except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.openairinterface.org/?page_id=698
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *-------------------------------------------------------------------------------
# * For more information about the OpenAirInterface (OAI) Software Alliance:
# * contact@openairinterface.org
# */
#---------------------------------------------------------------------
#
# Required Python Version
# Python 3.x
#
#---------------------------------------------------------------------
#to use isfile
import os
import sys
import logging
#to create a SSH object locally in the methods
import sshconnection
#time.sleep
import time
import re
import subprocess
class Module_UE:
# ID: idefix
# State : enabled
# Kind : quectel
# Process : quectel-cm
# WakeupScript : ci_qtel.py
# UENetwork : wwan0
# HostIPAddress : 192.168.18.188
# HostUsername : oaicicd
# HostPassword : oaicicd
# HostSourceCodePath : none
def __init__(self,Module):
#create attributes as in the Module dictionary
for k, v in Module.items():
setattr(self, k, v)
self.UEIPAddress = ""
#dictionary linking command names and related module scripts
self.cmd_dict= {"wup": self.WakeupScript,"detach":self.DetachScript}#dictionary of function scripts
#-----------------$
#PUBLIC Methods$
#-----------------$
#this method checks if the specified Process is running on the server hosting the module
def CheckIsModule(self):
HOST=self.HostIPAddress
COMMAND="ps aux | grep " + self.Process + " | grep -v grep "
logging.debug(COMMAND)
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if len(result)!=0:
logging.debug(self.Process + " process found")
return True
else:
logging.debug(self.Process + " process NOT found")
return False
#Wakeup/Detach can probably be improved with encapsulation of the command such def Command(self, command)
#this method wakes up the module by calling the specified python script
# def WakeUp(self):
# mySSH = sshconnection.SSHConnection()
# mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
# mySSH.command('echo ' + self.HostPassword + ' | sudo -S python3 ' + self.WakeupScript + ' ','\$',5)
# time.sleep(5)
# logging.debug("Module wake-up")
# mySSH.close()
#this method detaches the module by calling the specified python script
# def Detach(self):
# mySSH = sshconnection.SSHConnection()
# mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
# mySSH.command('echo ' + self.HostPassword + ' | sudo -S python3 ' + self.DetachScript + ' ','\$',5)
# time.sleep(5)
# logging.debug("Module detach")
# mySSH.close()
#tentative: generic command function
def Command(self,cmd):
mySSH = sshconnection.SSHConnection()
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
mySSH.command('echo ' + self.HostPassword + ' | sudo -S python3 ' + self.cmd_dict[cmd] + ' ','\$',5)
time.sleep(5)
logging.debug("Module "+ cmd)
mySSH.close()
#this method retrieves the Module IP address (not the Host IP address)
def GetModuleIPAddress(self):
HOST=self.HostIPAddress
COMMAND="ip a show dev " + self.UENetwork + " | grep inet | grep " + self.UENetwork
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
response = ssh.stdout.readlines()
if len(response)!=0:
result = re.search('inet (?P<moduleipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', response[0].decode("utf-8") )
if result is not None:
if result.group('moduleipaddress') is not None:
self.UEIPAddress = result.group('moduleipaddress')
logging.debug('\u001B[1mUE Module IP Address is ' + self.UEIPAddress + '\u001B[0m')
else:
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
else:
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
else:
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
......@@ -54,7 +54,8 @@ import helpreadme as HELP
import constants as CONST
import sshconnection
import cls_module_ue
import cls_ci_ueinfra #class defining the multi Ue infrastrucure
#-----------------------------------------------------------
......@@ -129,6 +130,7 @@ class OaiCiTest():
self.iperf_packetloss_threshold = ''
self.iperf_profile = ''
self.iperf_options = ''
self.iperf_direction = ''
self.nbMaxUEtoAttach = -1
self.UEDevices = []
self.UEDevicesStatus = []
......@@ -157,6 +159,7 @@ class OaiCiTest():
self.clean_repository = True
self.air_interface=''
self.expectedNbOfConnectedUEs = 0
self.ue_id = '' #used for module identification
def BuildOAIUE(self,HTML):
......@@ -364,7 +367,8 @@ class OaiCiTest():
except:
os.kill(os.getppid(),signal.SIGUSR1)
def InitializeUE(self,HTML,COTS_UE):
def InitializeUE(self,HTML,COTS_UE, InfraUE):
if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
......@@ -379,14 +383,24 @@ class OaiCiTest():
for job in multi_jobs:
job.join()
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
else: #if an ID is specified, it is a module from the yaml infrastructure file
#RH
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
is_module=Module_UE.CheckIsModule()
if is_module:
#Module_UE.WakeUp()
Module_UE.Command("wup")
Module_UE.GetModuleIPAddress()
HTML.CreateHtmlTestRow(Module_UE.UEIPAddress, 'OK', CONST.ALL_PROCESSES_OK)
self.UEIPAddresses.append(Module_UE.UEIPAddress)
logging.debug('UEs IP addresses : '+ self.UEIPAddresses)
def InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE):
if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
if self.air_interface == 'lte-uesoftmodem':
result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args))
if result is None:
......@@ -944,7 +958,8 @@ class OaiCiTest():
except:
os.kill(os.getppid(),signal.SIGUSR1)
def AttachUE(self,HTML,RAN,EPC,COTS_UE):
def AttachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE):
if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
......@@ -1026,6 +1041,7 @@ class OaiCiTest():
os.kill(os.getppid(),signal.SIGUSR1)
def DetachUE(self,HTML,RAN,EPC,COTS_UE):
if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
......@@ -1056,6 +1072,14 @@ class OaiCiTest():
while cnt < len(self.UEDevices):
self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHED
cnt += 1
else:#if an ID is specified, it is a module from the yaml infrastructure file
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
is_module=Module_UE.CheckIsModule()
if is_module:
#Module_UE.Detach()
Module_UE.Command("detach")
Module_UE.GetModuleIPAddress()
HTML.CreateHtmlTestRow(Module_UE.UEIPAddress, 'OK', CONST.ALL_PROCESSES_OK)
def RebootUE_common(self, device_id):
try:
......@@ -1437,14 +1461,20 @@ class OaiCiTest():
statusQueue.put(message)
lock.release()
def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue,EPC):
def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue,EPC, Module_UE):
try:
SSH = sshconnection.SSHConnection()
# Launch ping on the EPC side (true for ltebox and old open-air-cn)
# But for OAI-Rel14-CUPS, we launch from python executor
launchFromEpc = True
launchFromModule = False
if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE):
launchFromEpc = False
#if module, ping from module to EPC
if self.ue_id!='':
launchFromEpc = False
launchfromModule = True
ping_time = re.findall("-c (\d+)",str(self.ping_args))
if launchFromEpc:
......@@ -1462,6 +1492,7 @@ class OaiCiTest():
#copy the ping log file to have it locally for analysis (ping stats)
SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.')
else:
if launchfromModule == False:
#ping log file is on the python executor
cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log'
message = cmd + '\n'
......@@ -1477,6 +1508,18 @@ class OaiCiTest():
SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
#cat is executed on EPC
SSH.command('cat ' + EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
else: #launch from Module
SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
cmd = 'ping -I ' + UE_IPAddress + ' ' + self.ping_args + ' ' + EPC.IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',int(ping_time[0])*1.5)
logging.debug(cmd)
#copy the ping log file to have it locally for analysis (ping stats)
SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'ping_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
#cat is executed locally
SSH.command('cat ping_' + self.testCase_id + '_' + self.ue_id + '.log', '\$', 5)
ping_status=0
# TIMEOUT CASE
if ping_status < 0:
message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!'
......@@ -1660,7 +1703,7 @@ class OaiCiTest():
except:
os.kill(os.getppid(),signal.SIGUSR1)
def Ping(self,HTML,RAN,EPC,COTS_UE):
def Ping(self,HTML,RAN,EPC,COTS_UE, InfraUE):
result = re.search('noS1', str(RAN.Initialize_eNB_args))
if result is not None:
self.PingNoS1(HTML,RAN,EPC,COTS_UE)
......@@ -1678,18 +1721,30 @@ class OaiCiTest():
HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
return
if self.ue_id=="":
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra['dummy']) #RH, temporary, we need a dummy Module_UE object to pass to Ping_common
ueIpStatus = self.GetAllUEIPAddresses()
if (ueIpStatus < 0):
HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
return
else:
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
Module_UE.GetModuleIPAddress()
if Module_UE.UEIPAddress not in self.UEIPAddresses:
self.UEIPAddresses.append(Module_UE.UEIPAddress)
logging.debug(self.UEIPAddresses)
multi_jobs = []
i = 0
lock = Lock()
status_queue = SimpleQueue()
for UE_IPAddress in self.UEIPAddresses:
if self.ue_id=="":
device_id = self.UEDevices[i]
p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,EPC,))
else:
device_id = Module_UE.ID + "-" + Module_UE.Kind
p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,EPC,Module_UE,))
p.daemon = True
p.start()
multi_jobs.append(p)
......@@ -1864,8 +1919,8 @@ class OaiCiTest():
else:
return -2
def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options):
if (not os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')):
def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options, filename,type):
if (not os.path.isfile(filename)):
self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log')
return
# Computing the requested bandwidth in float
......@@ -1890,14 +1945,18 @@ class OaiCiTest():
req_bandwidth = '%.1f Gbits/sec' % req_bw
req_bw = req_bw * 1000000000
server_file = open('iperf_server_' + self.testCase_id + '_' + device_id + '.log', 'r')
server_file = open(filename, 'r')
br_sum = 0.0
ji_sum = 0.0
pl_sum = 0
ps_sum = 0
row_idx = 0
for line in server_file.readlines():
if type==0:
result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(?P<lostPack>[0-9]+)/ +(?P<sentPack>[0-9]+)', str(line))
else:
result = re.search('^.+ +(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(?P<lostPack>[0-9]+)\/(?P<sentPack>[0-9]+)', str(line))
if result is not None:
bitrate = result.group('bitrate')
jitter = result.group('jitter')
......@@ -2127,12 +2186,62 @@ class OaiCiTest():
SSH.command('docker cp prod-trf-gen:/iperf-2.0.5/iperf_server_' + self.testCase_id + '_' + device_id + '.log ' + EPC.SourceCodePath + '/scripts', '\$', 5)
SSH.close()
SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath+ '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options)
filename='iperf_server_' + self.testCase_id + '_' + device_id + '.log'
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options,filename,0)
# in case of OAI-UE
if (device_id == 'OAI-UE'):
SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.')
SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts')
def Iperf_Module(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC, Module_UE):
SSH = sshconnection.SSHConnection()
iperf_time = self.Iperf_ComputeTime()
if self.iperf_direction=="DL":
logging.debug("Iperf for Module in DL mode detected")
#server side UE
SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
cmd = 'echo $USER; nohup iperf -s -B ' + UE_IPAddress + ' -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',5)
logging.debug(cmd)
#client side EPC
SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
cmd = 'iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',int(iperf_time)*5.0)
logging.debug(cmd)
#copy the 2 resulting files locally
SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
#send for analysis
filename='iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)
elif self.iperf_direction=="UL":
logging.debug("Iperf for Module in UL mode detected")
#server side EPC
SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password)
cmd = 'echo $USER; nohup iperf -s -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',5)
logging.debug(cmd)
#client side UE
SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword)
cmd = 'iperf -B ' + UE_IPAddress + ' ' + '-c ' + EPC.IPAddress + ' ' + self.iperf_args + ' > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log'
SSH.command(cmd,'\$',int(iperf_time)*5.0)
logging.debug(cmd)
#copy the 2 resulting files locally
SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '.')
#send for analysis
filename='iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log'
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1)
else :
logging.debug("Incorrect or missing IPERF direction in XML")
SSH.close()
return
def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC):
try:
SSH = sshconnection.SSHConnection()
......@@ -2229,8 +2338,13 @@ class OaiCiTest():
# Launch the IPERF client on the EPC side for DL (true for ltebox and old open-air-cn
# But for OAI-Rel14-CUPS, we launch from python executor
launchFromEpc = True
launchFromModule = False
if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE):
launchFromEpc = False
#if module
if self.ue_id!='' and self.iperf :
launchFromEpc = False
launchfromModule = True
# When using a docker-based deployment, IPERF client shall be launched from trf container
launchFromTrfContainer = False
if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE):
......@@ -2334,7 +2448,8 @@ class OaiCiTest():
subprocess.run(cmd, shell=True)
except:
pass
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options)
filename='iperf_server_' + self.testCase_id + '_' + device_id + '.log'
self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options,filename,0)
# in case of OAI UE:
if (device_id == 'OAI-UE'):
......@@ -2422,7 +2537,8 @@ class OaiCiTest():
if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')):
os.remove('iperf_server_' + self.testCase_id + '.log')
SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log')
self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options)
filename='iperf_server_' + self.testCase_id + '_' + device_id + '.log'
self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options,filename,0)
# copying on the EPC server for logCollection
if (clientStatus == -1):
......@@ -2457,7 +2573,7 @@ class OaiCiTest():
HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
def Iperf(self,HTML,RAN,EPC,COTS_UE):
def Iperf(self,HTML,RAN,EPC,COTS_UE, InfraUE):
result = re.search('noS1', str(RAN.Initialize_eNB_args))
if result is not None:
self.IperfNoS1(HTML,RAN,EPC,COTS_UE)
......@@ -2475,12 +2591,21 @@ class OaiCiTest():
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
return
if self.ue_id=="":#is not a module, follow legacy code
ueIpStatus = self.GetAllUEIPAddresses()
if (ueIpStatus < 0):
logging.debug('going here')
HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC)
return
else: #is a module
Module_UE = cls_module_ue.Module_UE(InfraUE.ci_ue_infra[self.ue_id])
Module_UE.GetModuleIPAddress()
if Module_UE.UEIPAddress not in self.UEIPAddresses:
self.UEIPAddresses.append(Module_UE.UEIPAddress)
self.dummyIperfVersion = '2.0.10'
#cmd = 'iperf --version'
......@@ -2498,9 +2623,15 @@ class OaiCiTest():
ue_num = len(self.UEIPAddresses)
lock = Lock()
status_queue = SimpleQueue()
logging.debug(self.UEIPAddresses)
for UE_IPAddress in self.UEIPAddresses:
device_id = self.UEDevices[i]
p = Process(target = self.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,EPC,))
#special quick and dirty treatment for modules, iperf to be restructured
if self.ue_id!="": #is module
device_id = Module_UE.ID + "-" + Module_UE.Kind
p = Process(target = self.Iperf_Module ,args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, Module_UE,))
else: #legacy code
p = Process(target = self.Iperf_common, args = (lock, UE_IPAddress, device_id, i, ue_num, status_queue, EPC, ))
p.daemon = True
p.start()
multi_jobs.append(p)
......
......@@ -43,7 +43,7 @@ import cls_physim #class PhySim for physical simulators build and
import cls_cots_ue #class CotsUe for Airplane mode control
import cls_containerize #class Containerize for all container-based operations on RAN/UE objects
import cls_static_code_analysis #class for static code analysis
import cls_ci_ueinfra #class defining the multi Ue infrastrucure
import sshconnection
import epc
......@@ -193,6 +193,20 @@ def GetParametersFromXML(action):
else :
RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
elif action == 'Initialize_UE':
ue_id = test.findtext('id')
if (ue_id is None):
CiTestObj.ue_id = ""
else:
CiTestObj.ue_id = ue_id
elif action == 'Detach_UE':
ue_id = test.findtext('id')
if (ue_id is None):
CiTestObj.ue_id = ""
else:
CiTestObj.ue_id = ue_id
elif action == 'Attach_UE':
nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
if (nbMaxUEtoAttach is None):
......@@ -253,9 +267,20 @@ def GetParametersFromXML(action):
elif (action == 'Ping') or (action == 'Ping_CatM_module'):
CiTestObj.ping_args = test.findtext('ping_args')
CiTestObj.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
ue_id = test.findtext('id')
if (ue_id is None):
CiTestObj.ue_id = ""
else:
CiTestObj.ue_id = ue_id
elif action == 'Iperf':
CiTestObj.iperf_args = test.findtext('iperf_args')
ue_id = test.findtext('id')
if (ue_id is None):
CiTestObj.ue_id = ""
else:
CiTestObj.ue_id = ue_id
CiTestObj.iperf_direction = test.findtext('direction')#used for modules only
CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold')
CiTestObj.iperf_profile = test.findtext('iperf_profile')
if (CiTestObj.iperf_profile is None):
......@@ -370,6 +395,20 @@ with open(yaml_file,'r') as f:
#loading UE infrastructure from yaml
ue_infra_file='ci_ueinfra.yaml'
if (os.path.isfile(ue_infra_file)):
yaml_file=ue_infra_file
elif (os.path.isfile('ci-scripts/'+ue_infra_file)):
yaml_file='ci-scripts/'+ue_infra_file
else:
logging.error("UE infrastructure yaml file cannot be found")
sys.exit("UE infrastructure file cannot be found")
InfraUE=cls_ci_ueinfra.InfraUE() #initialize UE infrastructure class
InfraUE.Get_UE_Infra(yaml_file) #read the UE infra, filename is hardcoded and unique for the moment but should be passed as parameter from the test suite
mode = ''
CiTestObj = cls_oaicitest.OaiCiTest()
......@@ -384,7 +423,6 @@ SCA = cls_static_code_analysis.StaticCodeAnalysis()
ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU build
#-----------------------------------------------------------
# Parsing Command Line Arguments
#-----------------------------------------------------------
......@@ -673,7 +711,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
elif action == 'Terminate_eNB':
RAN.TerminateeNB(HTML, EPC)
elif action == 'Initialize_UE':
CiTestObj.InitializeUE(HTML,COTS_UE)
CiTestObj.InitializeUE(HTML,COTS_UE, InfraUE)
elif action == 'Terminate_UE':
CiTestObj.TerminateUE(HTML,COTS_UE)
elif action == 'Attach_UE':
......@@ -703,9 +741,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
elif action == 'Ping_CatM_module':
CiTestObj.PingCatM(HTML,RAN,EPC,COTS_UE,EPC)
elif action == 'Ping':
CiTestObj.Ping(HTML,RAN,EPC,COTS_UE)
CiTestObj.Ping(HTML,RAN,EPC,COTS_UE, InfraUE)
elif action == 'Iperf':
CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE)
CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE, InfraUE)
elif action == 'Reboot_UE':
CiTestObj.RebootUE(HTML,RAN,EPC)
elif action == 'Initialize_HSS':
......
......@@ -239,7 +239,6 @@ class RANManagement():
while (count > 0) and buildOAIprocess:
mySSH.command('ps aux | grep --color=never build_ | grep -v grep', '\$', 6)
result = re.search('build_oai', mySSH.getBefore())
print(result)
if result is None:
buildOAIprocess = False
else:
......
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-NSA-FR1-TM1</htmlTabRef>
<htmlTabName>NSA QUECTEL</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
030000
040000
000001
010000
000002
050000
050001
000001
070000
000001
070001
000001
010002
000001
080001
080000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010000">
<class>Initialize_UE</class>
<desc>Initialize Quectel</desc>
<id>idefix</id>
</testCase>
<testCase id="010002">
<class>Detach_UE</class>
<desc>Detach UE</desc>
<id>idefix</id>
</testCase>
<testCase id="030000">
<class>Initialize_eNB</class>
<desc>Initialize eNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf</Initialize_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
</testCase>
<testCase id="040000">
<class>Initialize_eNB</class>
<desc>Initialize gNB</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E</Initialize_eNB_args>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<air_interface>nr</air_interface>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>30</idle_sleep_time_in_sec>
</testCase>
<testCase id="050000">
<class>Ping</class>
<desc>Ping: 20pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
</testCase>
<testCase id="070000">
<class>Iperf</class>
<desc>iperf (DL/20Mbps/UDP)(20 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 20 -i 1</iperf_args>
<direction>DL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="070001">
<class>Iperf</class>
<desc>iperf (UL/3Mbps/UDP)(20 sec)(single-ue profile)</desc>
<iperf_args>-u -b 3M -t 20 -i 1</iperf_args>
<direction>UL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
<testCase id="080000">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<air_interface>lte</air_interface>
</testCase>
<testCase id="080001">
<class>Terminate_eNB</class>
<desc>Terminate gNB</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<air_interface>nr</air_interface>
</testCase>
</testCaseList>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment