diff --git a/ci-scripts/html.py b/ci-scripts/html.py index 3a520d30e3aa6ddb3c1cb8b43ae7261b63cba344..ccd89eb57799a6713654543ca418412b455b8cd7 100644 --- a/ci-scripts/html.py +++ b/ci-scripts/html.py @@ -48,12 +48,12 @@ class HTMLManagement(): self.htmlHeaderCreated = False self.htmlFooterCreated = False + self.ranAllowMerge = False + self.nbTestXMLfiles = 0 self.htmlTabRefs = [] self.htmlTabNames = [] self.htmlTabIcons = [] self.testXMLfiles = [] - self.htmlHeaderCreated = False - self.htmlFooterCreated = False #----------------------------------------------------------- # Setters and Getters @@ -110,6 +110,9 @@ class HTMLManagement(): def SetnbTestXMLfiles(self, nb): self.nbTestXMLfiles = nb + def GetnbTestXMLfiles(self): + return self.nbTestXMLfiles + def SettestXMLfiles(self, xmlFile): self.testXMLfiles.append(xmlFile) diff --git a/ci-scripts/main-cnt-mod.py b/ci-scripts/main-cnt-mod.py deleted file mode 100644 index 439dc0cfe4c05b5edb9085ed324900fd685fc924..0000000000000000000000000000000000000000 --- a/ci-scripts/main-cnt-mod.py +++ /dev/null @@ -1,4927 +0,0 @@ -# /* -# * 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 -# */ -#--------------------------------------------------------------------- -# Python for CI of OAI-eNB + COTS-UE -# -# Required Python Version -# Python 3.x -# -# Required Python Package -# pexpect -#--------------------------------------------------------------------- - -#----------------------------------------------------------- -# Version -#----------------------------------------------------------- -Version = '0.1' - -#----------------------------------------------------------- -# Constants -#----------------------------------------------------------- -ALL_PROCESSES_OK = 0 -ENB_PROCESS_FAILED = -1 -ENB_PROCESS_OK = +1 -ENB_PROCESS_SEG_FAULT = -11 -ENB_PROCESS_ASSERTION = -12 -ENB_PROCESS_REALTIME_ISSUE = -13 -ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14 -ENB_PROCESS_SLAVE_RRU_NOT_SYNCED = -15 -HSS_PROCESS_FAILED = -2 -HSS_PROCESS_OK = +2 -MME_PROCESS_FAILED = -3 -MME_PROCESS_OK = +3 -SPGW_PROCESS_FAILED = -4 -SPGW_PROCESS_OK = +4 -UE_IP_ADDRESS_ISSUE = -5 -OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE = -20 -OAI_UE_PROCESS_COULD_NOT_SYNC = -21 -OAI_UE_PROCESS_ASSERTION = -22 -OAI_UE_PROCESS_FAILED = -23 -OAI_UE_PROCESS_NO_TUNNEL_INTERFACE = -24 -OAI_UE_PROCESS_OK = +6 - -UE_STATUS_DETACHED = 0 -UE_STATUS_DETACHING = 1 -UE_STATUS_ATTACHING = 2 -UE_STATUS_ATTACHED = 3 - -X2_HO_REQ_STATE__IDLE = 0 -X2_HO_REQ_STATE__TARGET_RECEIVES_REQ = 1 -X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE = 2 -X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ = 3 -X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK = 10 - -#----------------------------------------------------------- -# Import -#----------------------------------------------------------- -import sys # arg -import re # reg -import pexpect # pexpect -import time # sleep -import os -import subprocess -import xml.etree.ElementTree as ET -import logging -import datetime -import signal -from multiprocessing import Process, Lock, SimpleQueue -logging.basicConfig( - level=logging.DEBUG, - format="[%(asctime)s] %(name)s:%(levelname)s: %(message)s" -) - -#----------------------------------------------------------- -# Class Declaration -#----------------------------------------------------------- -class SSHConnection(): - def __init__(self): - self.prematureExit = False - self.ranRepository = '' - self.ranBranch = '' - self.ranAllowMerge = False - self.ranCommitID = '' - self.ranTargetBranch = '' - self.eNBIPAddress = '' - self.eNBUserName = '' - self.eNBPassword = '' - self.eNBSourceCodePath = '' - self.EPCIPAddress = '' - self.EPCUserName = '' - self.EPCPassword = '' - self.eNB1IPAddress = '' - self.eNB1UserName = '' - self.eNB1Password = '' - self.eNB1SourceCodePath = '' - self.eNB2IPAddress = '' - self.eNB2UserName = '' - self.eNB2Password = '' - self.eNB2SourceCodePath = '' - self.EPCSourceCodePath = '' - self.EPCType = '' - self.EPC_PcapFileName = '' - self.ADBIPAddress = '' - self.ADBUserName = '' - self.ADBPassword = '' - self.ADBCentralized = True - self.testCase_id = '' - self.testXMLfiles = [] - self.nbTestXMLfiles = 0 - self.desc = '' - self.Build_eNB_args = '' - self.backgroundBuild = False - self.backgroundBuildTestId = ['', '', ''] - self.Initialize_eNB_args = '' - self.eNB_instance = '' - self.eNB_serverId = '' - self.eNBLogFiles = ['', '', ''] - self.eNBOptions = ['', '', ''] - self.ping_args = '' - self.ping_packetloss_threshold = '' - self.iperf_args = '' - self.iperf_packetloss_threshold = '' - self.iperf_profile = '' - self.nbMaxUEtoAttach = -1 - self.UEDevices = [] - self.UEDevicesStatus = [] - self.UEDevicesRemoteServer = [] - self.UEDevicesRemoteUser = [] - self.UEDevicesOffCmd = [] - self.UEDevicesOnCmd = [] - self.UEDevicesRebootCmd = [] - self.CatMDevices = [] - self.UEIPAddresses = [] - self.htmlFile = '' - self.htmlHeaderCreated = False - self.htmlFooterCreated = False - self.htmlUEConnected = -1 - self.htmleNBFailureMsg = '' - self.htmlUEFailureMsg = '' - self.picocom_closure = False - self.idle_sleep_time = 0 - self.x2_ho_options = 'network' - self.x2NbENBs = 0 - self.x2ENBBsIds = [] - self.x2ENBConnectedUEs = [] - self.htmlTabRefs = [] - self.htmlTabNames = [] - self.htmlTabIcons = [] - # repeatCounts was a list --> becomes an integer - self.repeatCounts = 1 - self.finalStatus = False - self.OsVersion = '' - self.KernelVersion = '' - self.UhdVersion = '' - self.UsrpBoard = '' - self.CpuNb = '' - self.CpuModel = '' - self.CpuMHz = '' - self.UEIPAddress = '' - self.UEUserName = '' - self.UEPassword = '' - self.UE_instance = '' - self.UESourceCodePath = '' - self.UELogFile = '' - self.Build_OAI_UE_args = '' - self.Initialize_OAI_UE_args = '' - self.flexranCtrlInstalled = False - self.flexranCtrlStarted = False - self.expectedNbOfConnectedUEs = 0 - self.startTime = 0 - - def open(self, ipaddress, username, password): - count = 0 - connect_status = False - while count < 4: - self.ssh = pexpect.spawn('ssh', [username + '@' + ipaddress], timeout = 5) - self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - self.ssh.sendline('yes') - self.ssh.expect('password:') - self.ssh.sendline(password) - self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - count = 10 - connect_status = True - else: - logging.debug('self.sshresponse = ' + str(self.sshresponse)) - elif self.sshresponse == 1: - self.ssh.sendline(password) - self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - count = 10 - connect_status = True - else: - logging.debug('self.sshresponse = ' + str(self.sshresponse)) - elif self.sshresponse == 2: - # Checking if we are really on the remote client defined by its IP address - self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', '\$', 5) - result = re.search(str(ipaddress), str(self.ssh.before)) - if result is None: - self.close() - else: - count = 10 - connect_status = True - else: - # debug output - logging.debug(str(self.ssh.before)) - logging.debug('self.sshresponse = ' + str(self.sshresponse)) - # adding a tempo when failure - if not connect_status: - time.sleep(1) - count += 1 - if connect_status: - pass - else: - sys.exit('SSH Connection Failed') - - def command(self, commandline, expectedline, timeout): - logging.debug(commandline) - self.ssh.timeout = timeout - self.ssh.sendline(commandline) - self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - return 0 - elif self.sshresponse == 1: - logging.debug('\u001B[1;37;41m Unexpected EOF \u001B[0m') - logging.debug('Expected Line : ' + expectedline) - sys.exit(self.sshresponse) - elif self.sshresponse == 2: - logging.debug('\u001B[1;37;41m Unexpected TIMEOUT \u001B[0m') - logging.debug('Expected Line : ' + expectedline) - result = re.search('ping |iperf |picocom', str(commandline)) - if result is None: - logging.debug(str(self.ssh.before)) - sys.exit(self.sshresponse) - else: - return -1 - else: - logging.debug('\u001B[1;37;41m Unexpected Others \u001B[0m') - logging.debug('Expected Line : ' + expectedline) - sys.exit(self.sshresponse) - - def close(self): - self.ssh.timeout = 5 - self.ssh.sendline('exit') - self.sshresponse = self.ssh.expect([pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - pass - elif self.sshresponse == 1: - if not self.picocom_closure: - logging.debug('\u001B[1;37;41m Unexpected TIMEOUT during closing\u001B[0m') - else: - logging.debug('\u001B[1;37;41m Unexpected Others during closing\u001B[0m') - - def copyin(self, ipaddress, username, password, source, destination): - count = 0 - copy_status = False - logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination) - while count < 10: - scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 100) - scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0: - scp_spawn.sendline('yes') - scp_spawn.expect('password:') - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0: - count = 10 - copy_status = True - else: - logging.debug('1 - scp_response = ' + str(scp_response)) - elif scp_response == 1: - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0 or scp_response == 3: - count = 10 - copy_status = True - else: - logging.debug('2 - scp_response = ' + str(scp_response)) - elif scp_response == 2: - count = 10 - copy_status = True - else: - logging.debug('3 - scp_response = ' + str(scp_response)) - # adding a tempo when failure - if not copy_status: - time.sleep(1) - count += 1 - if copy_status: - return 0 - else: - return -1 - - def copyout(self, ipaddress, username, password, source, destination): - count = 0 - copy_status = False - logging.debug('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination) - while count < 4: - scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 100) - scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0: - scp_spawn.sendline('yes') - scp_spawn.expect('password:') - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0: - count = 10 - copy_status = True - else: - logging.debug('1 - scp_response = ' + str(scp_response)) - elif scp_response == 1: - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0 or scp_response == 3: - count = 10 - copy_status = True - else: - logging.debug('2 - scp_response = ' + str(scp_response)) - elif scp_response == 2: - count = 10 - copy_status = True - else: - logging.debug('3 - scp_response = ' + str(scp_response)) - # adding a tempo when failure - if not copy_status: - time.sleep(1) - count += 1 - if copy_status: - pass - else: - sys.exit('SCP failed') - - def BuildeNB(self): - if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '': - Usage() - sys.exit('Insufficient Parameter') - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(lIpAddr, lUserName, lPassWord) - self.command('mkdir -p ' + lSourcePath, '\$', 5) - self.command('cd ' + lSourcePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) - # Raphael: here add a check if git clone or git fetch went smoothly - self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) - self.command('git config user.name "OAI Jenkins"', '\$', 5) - # Checking the BUILD INFO file - if not self.backgroundBuild: - self.command('ls *.txt', '\$', 5) - result = re.search('LAST_BUILD_INFO', str(self.ssh.before)) - if result is not None: - mismatch = False - self.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) - result = re.search(self.ranCommitID, str(self.ssh.before)) - if result is None: - mismatch = True - self.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): - result = re.search('YES', str(self.ssh.before)) - if result is None: - mismatch = True - self.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - result = re.search('develop', str(self.ssh.before)) - else: - result = re.search(self.ranTargetBranch, str(self.ssh.before)) - if result is None: - mismatch = True - else: - result = re.search('NO', str(self.ssh.before)) - if result is None: - mismatch = True - if not mismatch: - self.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - return - - self.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30) - # if the commit ID is provided use it to point to it - if self.ranCommitID != '': - self.command('git checkout -f ' + self.ranCommitID, '\$', 5) - # if the branch is not develop, then it is a merge request and we need to do - # the potential merge. Note that merge conflicts should already been checked earlier - if (self.ranAllowMerge): - if self.ranTargetBranch == '': - if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): - self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) - else: - logging.debug('Merging with the target branch: ' + self.ranTargetBranch) - self.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('mkdir -p log', '\$', 5) - self.command('chmod 777 log', '\$', 5) - # no need to remove in log (git clean did the trick) - if self.backgroundBuild: - self.command('echo "./build_oai ' + self.Build_eNB_args + '" > ./my-lte-softmodem-build.sh', '\$', 5) - self.command('chmod 775 ./my-lte-softmodem-build.sh', '\$', 5) - self.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=build_enb_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ./my-lte-softmodem-build.sh', '\$', 5) - self.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - self.backgroundBuildTestId[int(self.eNB_instance)] = self.testCase_id - return - self.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee compile_oai_enb.log', 'Bypassing the Tests|build have failed', 1500) - self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.testCase_id) - - def WaitBuildeNBisFinished(self): - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(lIpAddr, lUserName, lPassWord) - count = 40 - buildOAIprocess = True - while (count > 0) and buildOAIprocess: - self.command('ps aux | grep --color=never build_ | grep -v grep', '\$', 3) - result = re.search('build_oai', str(self.ssh.before)) - if result is None: - buildOAIprocess = False - else: - count -= 1 - time.sleep(30) - self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.backgroundBuildTestId[int(self.eNB_instance)]) - - def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId): - self.command('cd ' + lSourcePath + '/cmake_targets', '\$', 3) - self.command('ls lte_build_oai/build', '\$', 3) - self.command('ls lte_build_oai/build', '\$', 3) - buildStatus = True - result = re.search('lte-softmodem', str(self.ssh.before)) - if result is None: - buildStatus = False - else: - # Generating a BUILD INFO file - self.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) - self.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): - self.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - self.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - self.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - self.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) - self.command('mkdir -p build_log_' + testcaseId, '\$', 5) - self.command('mv log/* ' + 'build_log_' + testcaseId, '\$', 5) - self.command('mv compile_oai_enb.log ' + 'build_log_' + testcaseId, '\$', 5) - if self.eNB_serverId != '0': - self.command('cd cmake_targets', '\$', 5) - self.command('if [ -e tmp_build' + testcaseId + '.zip ]; then rm -f tmp_build' + testcaseId + '.zip; fi', '\$', 5) - self.command('zip -r -qq tmp_build' + testcaseId + '.zip build_log_' + testcaseId, '\$', 5) - self.close() - if (os.path.isfile('./tmp_build' + testcaseId + '.zip')): - os.remove('./tmp_build' + testcaseId + '.zip') - self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/tmp_build' + testcaseId + '.zip', '.') - if (os.path.isfile('./tmp_build' + testcaseId + '.zip')): - self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './tmp_build' + testcaseId + '.zip', self.eNBSourceCodePath + '/cmake_targets/.') - os.remove('./tmp_build' + testcaseId + '.zip') - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5) - self.command('unzip -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5) - self.command('rm -f tmp_build' + testcaseId + '.zip', '\$', 5) - self.close() - else: - self.close() - - if buildStatus: - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - else: - logging.error('\u001B[1m Building OAI eNB Failed\u001B[0m') - self.CreateHtmlTestRow(self.Build_eNB_args, 'KO', ALL_PROCESSES_OK) - self.CreateHtmlTabFooter(False) - sys.exit(1) - - def BuildOAIUE(self): - if self.UEIPAddress == '' or self.ranRepository == '' or self.ranBranch == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) - self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) - # here add a check if git clone or git fetch went smoothly - self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) - self.command('git config user.name "OAI Jenkins"', '\$', 5) - self.command('ls *.txt', '\$', 5) - result = re.search('LAST_BUILD_INFO', str(self.ssh.before)) - if result is not None: - mismatch = False - self.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) - result = re.search(self.ranCommitID, str(self.ssh.before)) - if result is None: - mismatch = True - self.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): - result = re.search('YES', str(self.ssh.before)) - if result is None: - mismatch = True - self.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - result = re.search('develop', str(self.ssh.before)) - else: - result = re.search(self.ranTargetBranch, str(self.ssh.before)) - if result is None: - mismatch = True - else: - result = re.search('NO', str(self.ssh.before)) - if result is None: - mismatch = True - if not mismatch: - self.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - return - - self.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30) - # if the commit ID is provided use it to point to it - if self.ranCommitID != '': - self.command('git checkout -f ' + self.ranCommitID, '\$', 5) - # if the branch is not develop, then it is a merge request and we need to do - # the potential merge. Note that merge conflicts should already been checked earlier - if (self.ranAllowMerge): - if self.ranTargetBranch == '': - if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): - self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) - else: - logging.debug('Merging with the target branch: ' + self.ranTargetBranch) - self.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('mkdir -p log', '\$', 5) - self.command('chmod 777 log', '\$', 5) - # no need to remove in log (git clean did the trick) - self.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee compile_oai_ue.log', 'Bypassing the Tests|build have failed', 600) - self.command('ls lte_build_oai/build', '\$', 3) - self.command('ls lte_build_oai/build', '\$', 3) - buildStatus = True - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is None: - buildStatus = False - self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) - self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) - self.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5) - if buildStatus: - # Generating a BUILD INFO file - self.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) - self.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): - self.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - self.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - self.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - self.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) - self.close() - self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') - else: - self.close() - logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') - self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE') - self.CreateHtmlTabFooter(False) - sys.exit(1) - - def InitializeHSS(self): - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - logging.debug('Using the OAI EPC Release 14 Cassandra-based HSS') - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - logging.debug('\u001B[1m Launching tshark on all interfaces \u001B[0m') - EPC_PcapFileName = 'epc_' + self.testCase_id + '.pcap' - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f ' + EPC_PcapFileName, '\$', 5) - self.command('echo $USER; nohup sudo tshark -f "tcp port not 22 and port not 53" -i any -w ' + self.EPCSourceCodePath + '/scripts/' + EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S mkdir -p logs', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss_' + self.testCase_id + '.log logs/hss*.*', '\$', 5) - self.command('echo "oai_hss -j /usr/local/etc/oai/hss_rel14.json" > ./my-hss.sh', '\$', 5) - self.command('chmod 755 ./my-hss.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=hss_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/hss_' + self.testCase_id + '.log ./my-hss.sh', '\$', 5) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - logging.debug('Using the OAI EPC HSS') - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_hss 2>&1 | stdbuf -o0 awk \'{ print strftime("[%Y/%m/%d %H:%M:%S] ",systime()) $0 }\' | stdbuf -o0 tee -a hss_' + self.testCase_id + '.log &', 'Core state: 2 -> 3', 35) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - logging.debug('Using the ltebox simulated HSS') - self.command('if [ -d ' + self.EPCSourceCodePath + '/scripts ]; then echo ' + self.eNBPassword + ' | sudo -S rm -Rf ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) - self.command('mkdir -p ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('cd /opt/hss_sim0609', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss.log daemon.log', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S echo "Starting sudo session" && sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real ', '\$', 5) - else: - logging.error('This option should not occur!') - self.close() - self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) - - def InitializeMME(self): - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - logging.debug('Using the OAI EPC Release 14 MME') - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f mme_' + self.testCase_id + '.log', '\$', 5) - self.command('echo "./run_mme --config-file /usr/local/etc/oai/mme.conf --set-virt-if" > ./my-mme.sh', '\$', 5) - self.command('chmod 755 ./my-mme.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=mme_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/mme_' + self.testCase_id + '.log ./my-mme.sh', '\$', 5) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('stdbuf -o0 hostname', '\$', 5) - result = re.search('hostname\\\\r\\\\n(?P<host_name>[a-zA-Z0-9\-\_]+)\\\\r\\\\n', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m Hostname Not Found! \u001B[0m') - sys.exit(1) - host_name = result.group('host_name') - self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_mme 2>&1 | stdbuf -o0 tee -a mme_' + self.testCase_id + '.log &', 'MME app initialization complete', 100) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cd /opt/ltebox/tools', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_mme', '\$', 5) - else: - logging.error('This option should not occur!') - self.close() - self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) - - def InitializeSPGW(self): - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - logging.debug('Using the OAI EPC Release 14 SPGW-CUPS') - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f spgwc_' + self.testCase_id + '.log spgwu_' + self.testCase_id + '.log', '\$', 5) - self.command('echo "spgwc -c /usr/local/etc/oai/spgw_c.conf" > ./my-spgwc.sh', '\$', 5) - self.command('chmod 755 ./my-spgwc.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=spgwc_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwc_' + self.testCase_id + '.log ./my-spgwc.sh', '\$', 5) - time.sleep(5) - self.command('echo "spgwu -c /usr/local/etc/oai/spgw_u.conf" > ./my-spgwu.sh', '\$', 5) - self.command('chmod 755 ./my-spgwu.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=spgwu_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwu_' + self.testCase_id + '.log ./my-spgwu.sh', '\$', 5) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_spgw 2>&1 | stdbuf -o0 tee -a spgw_' + self.testCase_id + '.log &', 'Initializing SPGW-APP task interface: DONE', 30) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cd /opt/ltebox/tools', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_xGw', '\$', 5) - else: - logging.error('This option should not occur!') - self.close() - self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) - - def CheckFlexranCtrlInstallation(self): - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '': - return - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('ls -ls /opt/flexran_rtc/*/rt_controller', '\$', 5) - result = re.search('/opt/flexran_rtc/build/rt_controller', str(self.ssh.before)) - if result is not None: - self.flexranCtrlInstalled = True - logging.debug('Flexran Controller is installed') - self.close() - - def InitializeFlexranCtrl(self): - if self.flexranCtrlInstalled == False: - return - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd /opt/flexran_rtc', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f log/*.log', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5) - self.command('ps -aux | grep --color=never rt_controller', '\$', 5) - result = re.search('rt_controller -c ', str(self.ssh.before)) - if result is not None: - logging.debug('\u001B[1m Initialize FlexRan Controller Completed\u001B[0m') - self.flexranCtrlStarted = True - self.close() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def InitializeeNB(self): - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = False - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - # If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep -v "lo|tun"', '\$', 5) - result = re.search('interfaceToUse=(?P<eth_interface>[a-zA-Z0-9\-\_]+)done', str(self.ssh.before)) - if result is not None: - eth_interface = result.group('eth_interface') - logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m') - self.EPC_PcapFileName = 'enb_' + self.testCase_id + '_s1log.pcap' - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f /tmp/' + self.EPC_PcapFileName, '\$', 5) - self.command('echo $USER; nohup sudo tshark -f "host ' + lIpAddr +'" -i ' + eth_interface + ' -w /tmp/' + self.EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) - self.close() - self.open(lIpAddr, lUserName, lPassWord) - self.command('cd ' + lSourcePath, '\$', 5) - # Initialize_eNB_args usually start with -O and followed by the location in repository - full_config_file = self.Initialize_eNB_args.replace('-O ','') - extra_options = '' - extIdx = full_config_file.find('.conf') - if (extIdx > 0): - extra_options = full_config_file[extIdx + 5:] - # if tracer options is on, compiling and running T Tracer - result = re.search('T_stdout', str(extra_options)) - if result is not None: - logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m') - self.command('cd common/utils/T/tracer', '\$', 5) - self.command('make', '\$', 10) - self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', lUserName, 5) - self.command('cd ' + lSourcePath, '\$', 5) - full_config_file = full_config_file[:extIdx + 5] - config_path, config_file = os.path.split(full_config_file) - else: - sys.exit('Insufficient Parameter') - ci_full_config_file = config_path + '/ci-' + config_file - rruCheck = False - result = re.search('^rru|^rcc|^du.band', str(config_file)) - if result is not None: - rruCheck = True - # do not reset board twice in IF4.5 case - result = re.search('^rru|^enb|^du.band', str(config_file)) - if result is not None: - self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 10) - result = re.search('type: b200', str(self.ssh.before)) - if result is not None: - logging.debug('Found a B2xx device --> resetting it') - self.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) - # Reloading FGPA bin firmware - self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 15) - # Make a copy and adapt to EPC / eNB IP addresses - self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) - self.command('sed -i -e \'s/CI_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/CI_RRU1_IP_ADDR/' + self.eNB1IPAddress + '/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/CI_RRU2_IP_ADDR/' + self.eNB2IPAddress + '/\' ' + ci_full_config_file, '\$', 2); - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "yes";/\' ' + ci_full_config_file, '\$', 2); - else: - self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "no";/\' ' + ci_full_config_file, '\$', 2); - # Launch eNB with the modified config file - self.command('source oaienv', '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) - self.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log' - if extra_options != '': - self.eNBOptions[int(self.eNB_instance)] = extra_options - time.sleep(6) - doLoop = True - loopCounter = 10 - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - # In case of T tracer recording, we may need to kill it - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - self.command('killall --signal SIGKILL record', '\$', 5) - self.close() - doLoop = False - logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m') - self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', ALL_PROCESSES_OK) - # In case of T tracer recording, we need to kill tshark on EPC side - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) - if self.EPC_PcapFileName != '': - time.sleep(0.5) - self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5) - self.close() - time.sleep(1) - if self.EPC_PcapFileName != '': - copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.') - if (copyin_res == 0): - self.copyout(lIpAddr, lUserName, lPassWord, self.EPC_PcapFileName, lSourcePath + '/cmake_targets/.') - self.prematureExit = True - return - else: - self.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting"', '\$', 4) - if rruCheck: - result = re.search('wait RUs', str(self.ssh.before)) - else: - result = re.search('got sync|Starting F1AP at CU', str(self.ssh.before)) - if result is None: - time.sleep(6) - else: - doLoop = False - self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK) - logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') - time.sleep(10) - - self.close() - - def InitializeUE_common(self, device_id, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if not self.ADBCentralized: - # Reboot UE - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesRebootCmd[idx], '\$', 60) - # Wait - #time.sleep(60) - # Put in LTE-Mode only - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode 11"\'', '\$', 60) - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode1 11"\'', '\$', 60) - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode2 11"\'', '\$', 60) - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode3 11"\'', '\$', 60) - # enable data service - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - # we need to do radio on/off cycle to make sure of above changes - # airplane mode off // radio on - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - #time.sleep(10) - # airplane mode on // radio off - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - - # normal procedure without reboot - # enable data service - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - # airplane mode on // radio off - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - self.close() - return - # enable data service - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) - - # The following commands are deprecated since we no longer work on Android 7+ - # self.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10) - # self.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60) - # a dedicated script has to be installed inside the UE - # airplane mode on means call /data/local/tmp/off - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - #airplane mode off means call /data/local/tmp/on - logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m') - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def InitializeUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.InitializeUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def InitializeOAIUE(self): - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is None: - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - # b2xx_fx3_utils reset procedure - self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 10) - result = re.search('type: b200', str(self.ssh.before)) - if result is not None: - logging.debug('Found a B2xx device --> resetting it') - self.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) - # Reloading FGPA bin firmware - self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 15) - else: - logging.debug('Did not find any B2xx device') - self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd cmake_targets/lte_build_oai/build', '\$', 5) - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - # We may have to regenerate the .u* files - if result is None: - self.command('ls /tmp/*.sed', '\$', 5) - result = re.search('adapt_usim_parameters', str(self.ssh.before)) - if result is not None: - self.command('sed -f /tmp/adapt_usim_parameters.sed ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) - else: - self.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5) - # Launch UE with the modified config file - self.command('echo "ulimit -c unlimited && ./lte-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - self.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - self.UELogFile = 'ue_' + self.testCase_id + '.log' - - # We are now looping several times to hope we really sync w/ an eNB - doOutterLoop = True - outterLoopCounter = 5 - gotSyncStatus = True - fullSyncStatus = True - while (doOutterLoop): - self.command('cd ' + self.UESourceCodePath + '/cmake_targets/lte_build_oai/build', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/lte_build_oai/build -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - time.sleep(6) - self.command('cd ../..', '\$', 5) - doLoop = True - loopCounter = 10 - gotSyncStatus = True - # the 'got sync' message is for the UE threads synchronization - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - # Here should never occur - logging.error('"got sync" message never showed!') - gotSyncStatus = False - doLoop = False - continue - self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) - result = re.search('got sync', str(self.ssh.before)) - if result is None: - time.sleep(6) - else: - doLoop = False - logging.debug('Found "got sync" message!') - if gotSyncStatus == False: - # we certainly need to stop the lte-uesoftmodem process if it is still running! - self.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) - time.sleep(3) - # We are now checking if sync w/ eNB DOES NOT OCCUR - # Usually during the cell synchronization stage, the UE returns with No cell synchronization message - doLoop = True - loopCounter = 10 - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - # Here we do have a great chance that the UE did cell-sync w/ eNB - doLoop = False - doOutterLoop = False - fullSyncStatus = True - continue - self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) - result = re.search('No cell synchronization found', str(self.ssh.before)) - if result is None: - time.sleep(6) - else: - doLoop = False - fullSyncStatus = False - logging.debug('Found: "No cell synchronization" message! --> try again') - time.sleep(6) - self.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) - outterLoopCounter = outterLoopCounter - 1 - if (outterLoopCounter == 0): - doOutterLoop = False - - if fullSyncStatus and gotSyncStatus: - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is None: - self.command('ifconfig oaitun_ue1', '\$', 4) - # ifconfig output is different between ubuntu 16 and ubuntu 18 - result = re.search('inet addr:1|inet 1', str(self.ssh.before)) - if result is not None: - logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m') - tunnelInterfaceStatus = True - else: - logging.debug(str(self.ssh.before)) - logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') - tunnelInterfaceStatus = False - else: - tunnelInterfaceStatus = True - - self.close() - if fullSyncStatus and gotSyncStatus and tunnelInterfaceStatus: - self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') - logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m') - if (self.ADBIPAddress != 'none'): - self.UEDevices = [] - self.UEDevices.append('OAI-UE') - self.UEDevicesStatus = [] - self.UEDevicesStatus.append(UE_STATUS_DETACHED) - else: - self.htmlUEFailureMsg = 'oaitun_ue1 interface is either NOT mounted or NOT configured' - self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') - logging.error('\033[91mInitialize OAI UE Failed! \033[0m') - self.AutoTerminateUEandeNB() - - def checkDevTTYisUnlocked(self): - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - count = 0 - while count < 5: - self.command('echo ' + self.ADBPassword + ' | sudo -S lsof | grep ttyUSB0', '\$', 10) - result = re.search('picocom', str(self.ssh.before)) - if result is None: - count = 10 - else: - time.sleep(5) - count = count + 1 - self.close() - - def InitializeCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.picocom_closure = True - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - self.command('AT', 'OK|ERROR', 5) - self.command('AT', 'OK', 5) - # Disabling the Radio - self.command('AT+CFUN=0', 'OK', 5) - logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') - # Checking if auto-attach is enabled - self.command('AT^AUTOATT?', 'OK', 5) - result = re.search('AUTOATT: (?P<state>[0-9\-]+)', str(self.ssh.before)) - if result is not None: - if result.group('state') is not None: - autoAttachState = int(result.group('state')) - if autoAttachState is not None: - if autoAttachState == 0: - self.command('AT^AUTOATT=1', 'OK', 5) - logging.debug('\u001B[1m Auto-Attach enabled\u001B[0m') - else: - logging.debug('\u001B[1;37;41m Could not check Auto-Attach! \u001B[0m') - # Force closure of picocom but device might still be locked - self.close() - self.picocom_closure = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.checkDevTTYisUnlocked() - - def TerminateCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.picocom_closure = True - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - self.command('AT', 'OK|ERROR', 5) - self.command('AT', 'OK', 5) - # Disabling the Radio - self.command('AT+CFUN=0', 'OK', 5) - logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') - self.close() - self.picocom_closure = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.checkDevTTYisUnlocked() - - def AttachCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.picocom_closure = True - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - self.command('AT', 'OK|ERROR', 5) - self.command('AT', 'OK', 5) - # Enabling the Radio - self.command('AT+CFUN=1', 'SIMSTORE,READY', 5) - logging.debug('\u001B[1m Cellular Functionality enabled\u001B[0m') - time.sleep(4) - # We should check if we register - count = 0 - attach_cnt = 0 - attach_status = False - while count < 5: - self.command('AT+CEREG?', 'OK', 5) - result = re.search('CEREG: 2,(?P<state>[0-9\-]+),', str(self.ssh.before)) - if result is not None: - mDataConnectionState = int(result.group('state')) - if mDataConnectionState is not None: - if mDataConnectionState == 1: - count = 10 - attach_status = True - result = re.search('CEREG: 2,1,"(?P<networky>[0-9A-Z]+)","(?P<networkz>[0-9A-Z]+)"', str(self.ssh.before)) - if result is not None: - networky = result.group('networky') - networkz = result.group('networkz') - logging.debug('\u001B[1m CAT-M module attached to eNB (' + str(networky) + '/' + str(networkz) + ')\u001B[0m') - else: - logging.debug('\u001B[1m CAT-M module attached to eNB\u001B[0m') - else: - logging.debug('+CEREG: 2,' + str(mDataConnectionState)) - attach_cnt = attach_cnt + 1 - else: - logging.debug(str(self.ssh.before)) - attach_cnt = attach_cnt + 1 - count = count + 1 - time.sleep(1) - if attach_status: - self.command('AT+CESQ', 'OK', 5) - result = re.search('CESQ: 99,99,255,255,(?P<rsrq>[0-9]+),(?P<rsrp>[0-9]+)', str(self.ssh.before)) - if result is not None: - nRSRQ = int(result.group('rsrq')) - nRSRP = int(result.group('rsrp')) - if (nRSRQ is not None) and (nRSRP is not None): - logging.debug(' RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB') - logging.debug(' RSRP = ' + str(-140+nRSRP) + ' dBm') - self.close() - self.picocom_closure = False - html_queue = SimpleQueue() - self.checkDevTTYisUnlocked() - if attach_status: - html_cell = '<pre style="background-color:white">CAT-M module Attachment Completed in ' + str(attach_cnt+4) + ' seconds' - if (nRSRQ is not None) and (nRSRP is not None): - html_cell += '\n RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB' - html_cell += '\n RSRP = ' + str(-140+nRSRP) + ' dBm</pre>' - else: - html_cell += '</pre>' - html_queue.put(html_cell) - self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) - else: - logging.error('\u001B[1m CAT-M module Attachment Failed\u001B[0m') - html_cell = '<pre style="background-color:white">CAT-M module Attachment Failed</pre>' - html_queue.put(html_cell) - self.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) - self.AutoTerminateUEandeNB() - - def PingCatM(self): - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - try: - statusQueue = SimpleQueue() - lock = Lock() - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE): - logging.debug('Using the OAI EPC HSS: not implemented yet') - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - else: - self.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5) - result = re.search('Allocated ipv4 addr: (?P<ipaddr>[0-9\.]+) from Pool', str(self.ssh.before)) - if result is not None: - moduleIPAddr = result.group('ipaddr') - else: - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - device_id = 'catm' - ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + str(moduleIPAddr) + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with UE (' + str(moduleIPAddr) + ') crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before)) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before)) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - lock.acquire() - logging.debug('\u001B[1;37;44m ping result (' + moduleIPAddr + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - lock.release() - self.close() - html_cell = '<pre style="background-color:white">CAT-M module\nIP Address : ' + moduleIPAddr + '\n' + qMsg + '</pre>' - statusQueue.put(html_cell) - if (packetLossOK): - self.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue) - else: - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue) - self.AutoTerminateUEandeNB() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AttachUE_common(self, device_id, statusQueue, lock, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) - else: - # airplane mode off // radio on - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - time.sleep(2) - max_count = 45 - count = max_count - while count > 0: - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep -m 1 mDataConnectionState', '\$', 15) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep -m 1 mDataConnectionState', '\$', 60) - result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put('mDataConnectionState Not Found!') - lock.release() - break - mDataConnectionState = int(result.group('state')) - if mDataConnectionState == 2: - logging.debug('\u001B[1mUE (' + device_id + ') Attach Completed\u001B[0m') - lock.acquire() - statusQueue.put(max_count - count) - statusQueue.put(device_id) - statusQueue.put('Attach Completed') - lock.release() - break - count = count - 1 - if count == 15 or count == 30: - logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m') - if self.ADBCentralized: - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - time.sleep(0.5) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - time.sleep(0.5) - logging.debug('\u001B[1mWait UE (' + device_id + ') a second until mDataConnectionState=2 (' + str(max_count-count) + ' times)\u001B[0m') - time.sleep(1) - if count == 0: - logging.debug('\u001B[1;37;41m UE (' + device_id + ') Attach Failed \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put('Attach Failed') - lock.release() - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AttachUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - status_queue = SimpleQueue() - lock = Lock() - nb_ue_to_connect = 0 - for device_id in self.UEDevices: - if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach): - self.UEDevicesStatus[nb_ue_to_connect] = UE_STATUS_ATTACHING - p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,)) - p.daemon = True - p.start() - multi_jobs.append(p) - nb_ue_to_connect = nb_ue_to_connect + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - self.CreateHtmlTestRow('N/A', 'KO', ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - return - else: - attach_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - attach_status = False - device_id = status_queue.get() - message = status_queue.get() - if (count < 0): - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>' - else: - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds</pre>' - html_queue.put(html_cell) - if (attach_status): - cnt = 0 - while cnt < len(self.UEDevices): - if self.UEDevicesStatus[cnt] == UE_STATUS_ATTACHING: - self.UEDevicesStatus[cnt] = UE_STATUS_ATTACHED - cnt += 1 - self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - logging.debug('Waiting 5 seconds to fill up record file') - time.sleep(5) - else: - self.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def DetachUE_common(self, device_id, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DetachUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - cnt = 0 - for device_id in self.UEDevices: - self.UEDevicesStatus[cnt] = UE_STATUS_DETACHING - p = Process(target = self.DetachUE_common, args = (device_id,cnt,)) - p.daemon = True - p.start() - multi_jobs.append(p) - cnt += 1 - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - logging.debug('Waiting 5 seconds to fill up record file') - time.sleep(5) - cnt = 0 - while cnt < len(self.UEDevices): - self.UEDevicesStatus[cnt] = UE_STATUS_DETACHED - cnt += 1 - - def RebootUE_common(self, device_id): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - previousmDataConnectionStates = [] - # Save mDataConnectionState - self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') - sys.exit(1) - previousmDataConnectionStates.append(int(result.group('state'))) - # Reboot UE - self.command('stdbuf -o0 adb -s ' + device_id + ' shell reboot', '\$', 10) - time.sleep(60) - previousmDataConnectionState = previousmDataConnectionStates.pop(0) - count = 180 - while count > 0: - count = count - 1 - self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', str(self.ssh.before)) - if result is None: - mDataConnectionState = None - else: - mDataConnectionState = int(result.group('state')) - logging.debug('mDataConnectionState = ' + result.group('state')) - if mDataConnectionState is None or (previousmDataConnectionState == 2 and mDataConnectionState != 2): - logging.debug('\u001B[1mWait UE (' + device_id + ') a second until reboot completion (' + str(180-count) + ' times)\u001B[0m') - time.sleep(1) - else: - logging.debug('\u001B[1mUE (' + device_id + ') Reboot Completed\u001B[0m') - break - if count == 0: - logging.debug('\u001B[1;37;41m UE (' + device_id + ') Reboot Failed \u001B[0m') - sys.exit(1) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def RebootUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - multi_jobs = [] - for device_id in self.UEDevices: - p = Process(target = self.RebootUE_common, args = (device_id,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def DataDisableUE_common(self, device_id, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # disable data service - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data disable"', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data disable"\'', '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Disabled Data Service\u001B[0m') - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DataDisableUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.DataDisableUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def DataEnableUE_common(self, device_id, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # enable data service - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Enabled Data Service\u001B[0m') - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DataEnableUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.DataEnableUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def GetAllUEDevices(self, terminate_ue_flag): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - self.command('adb devices', '\$', 15) - self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",str(self.ssh.before)) - self.close() - else: - if (os.path.isfile('./phones_list.txt')): - os.remove('./phones_list.txt') - self.command('ls /etc/*/phones*.txt', '\$', 5) - result = re.search('/etc/ci/phones_list.txt', str(self.ssh.before)) - self.close() - if (result is not None) and (len(self.UEDevices) == 0): - self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, '/etc/ci/phones_list.txt', '.') - if (os.path.isfile('./phones_list.txt')): - phone_list_file = open('./phones_list.txt', 'r') - for line in phone_list_file.readlines(): - line = line.strip() - result = re.search('^#', line) - if result is not None: - continue - comma_split = line.split(",") - self.UEDevices.append(comma_split[0]) - self.UEDevicesRemoteServer.append(comma_split[1]) - self.UEDevicesRemoteUser.append(comma_split[2]) - self.UEDevicesOffCmd.append(comma_split[3]) - self.UEDevicesOnCmd.append(comma_split[4]) - self.UEDevicesRebootCmd.append(comma_split[5]) - phone_list_file.close() - - if terminate_ue_flag == False: - if len(self.UEDevices) == 0: - logging.debug('\u001B[1;37;41m UE Not Found! \u001B[0m') - sys.exit(1) - if len(self.UEDevicesStatus) == 0: - cnt = 0 - while cnt < len(self.UEDevices): - self.UEDevicesStatus.append(UE_STATUS_DETACHED) - cnt += 1 - - def GetAllCatMDevices(self, terminate_ue_flag): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - self.command('lsusb | egrep "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15) - self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",str(self.ssh.before)) - else: - if (os.path.isfile('./modules_list.txt')): - os.remove('./modules_list.txt') - self.command('ls /etc/*/modules*.txt', '\$', 5) - result = re.search('/etc/ci/modules_list.txt', str(self.ssh.before)) - self.close() - if result is not None: - logging.debug('Found a module list file on ADB server') - if terminate_ue_flag == False: - if len(self.CatMDevices) == 0: - logging.debug('\u001B[1;37;41m CAT-M UE Not Found! \u001B[0m') - sys.exit(1) - self.close() - - def CheckUEStatus_common(self, lock, device_id, statusQueue, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry"', '\$', 15) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\'', '\$', 60) - result = re.search('mServiceState=(?P<serviceState>[0-9]+)', str(self.ssh.before)) - serviceState = 'Service State: UNKNOWN' - if result is not None: - lServiceState = int(result.group('serviceState')) - if lServiceState == 3: - serviceState = 'Service State: RADIO_POWERED_OFF' - if lServiceState == 1: - serviceState = 'Service State: OUT_OF_SERVICE' - if lServiceState == 0: - serviceState = 'Service State: IN_SERVICE' - if lServiceState == 2: - serviceState = 'Service State: EMERGENCY_ONLY' - result = re.search('mDataConnectionState=(?P<dataConnectionState>[0-9]+)', str(self.ssh.before)) - dataConnectionState = 'Data State: UNKNOWN' - if result is not None: - lDataConnectionState = int(result.group('dataConnectionState')) - if lDataConnectionState == 0: - dataConnectionState = 'Data State: DISCONNECTED' - if lDataConnectionState == 1: - dataConnectionState = 'Data State: CONNECTING' - if lDataConnectionState == 2: - dataConnectionState = 'Data State: CONNECTED' - if lDataConnectionState == 3: - dataConnectionState = 'Data State: SUSPENDED' - result = re.search('mDataConnectionReason=(?P<dataConnectionReason>[0-9a-zA-Z_]+)', str(self.ssh.before)) - dataConnectionReason = 'Data Reason: UNKNOWN' - if result is not None: - dataConnectionReason = 'Data Reason: ' + result.group('dataConnectionReason') - lock.acquire() - logging.debug('\u001B[1;37;44m Status Check (' + str(device_id) + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + serviceState + '\u001B[0m') - logging.debug('\u001B[1;34m ' + dataConnectionState + '\u001B[0m') - logging.debug('\u001B[1;34m ' + dataConnectionReason + '\u001B[0m') - statusQueue.put(0) - statusQueue.put(device_id) - qMsg = serviceState + '\n' + dataConnectionState + '\n' + dataConnectionReason - statusQueue.put(qMsg) - lock.release() - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckStatusUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - multi_jobs = [] - lock = Lock() - status_queue = SimpleQueue() - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.CheckUEStatus_common, args = (lock,device_id,status_queue,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd /opt/flexran_rtc', '\$', 5) - self.command('curl http://localhost:9999/stats | jq \'.\' > log/check_status_' + self.testCase_id + '.log 2>&1', '\$', 5) - self.command('cat log/check_status_' + self.testCase_id + '.log | jq \'.eNB_config[0].UE\' | grep -c rnti | sed -e "s#^#Nb Connected UE = #"', '\$', 5) - result = re.search('Nb Connected UE = (?P<nb_ues>[0-9]+)', str(self.ssh.before)) - passStatus = True - if result is not None: - nb_ues = int(result.group('nb_ues')) - htmlOptions = 'Nb Connected UE(s) to eNB = ' + str(nb_ues) - logging.debug('\u001B[1;37;44m ' + htmlOptions + ' \u001B[0m') - if self.expectedNbOfConnectedUEs > -1: - if nb_ues != self.expectedNbOfConnectedUEs: - passStatus = False - else: - htmlOptions = 'N/A' - self.close() - else: - passStatus = True - htmlOptions = 'N/A' - - if (status_queue.empty()): - self.CreateHtmlTestRow(htmlOptions, 'KO', ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - check_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - check_status = False - device_id = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>' - html_queue.put(html_cell) - if check_status and passStatus: - self.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def GetAllUEIPAddresses(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - ue_ip_status = 0 - self.UEIPAddresses = [] - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('ifconfig oaitun_ue1', '\$', 4) - result = re.search('inet addr:(?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|inet (?P<ueipaddress2>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', str(self.ssh.before)) - if result is not None: - if result.group('ueipaddress') is not None: - UE_IPAddress = result.group('ueipaddress') - else: - UE_IPAddress = result.group('ueipaddress2') - logging.debug('\u001B[1mUE (' + self.UEDevices[0] + ') IP Address is ' + UE_IPAddress + '\u001B[0m') - self.UEIPAddresses.append(UE_IPAddress) - else: - logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') - ue_ip_status -= 1 - self.close() - return ue_ip_status - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - idx = 0 - for device_id in self.UEDevices: - if self.UEDevicesStatus[idx] != UE_STATUS_ATTACHED: - idx += 1 - continue - count = 0 - while count < 4: - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "ip addr show | grep rmnet"', '\$', 15) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ip addr show | grep rmnet"\'', '\$', 60) - result = re.search('inet (?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+[0-9a-zA-Z\.\s]+', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') - time.sleep(1) - count += 1 - else: - count = 10 - if count < 9: - ue_ip_status -= 1 - continue - UE_IPAddress = result.group('ueipaddress') - logging.debug('\u001B[1mUE (' + device_id + ') IP Address is ' + UE_IPAddress + '\u001B[0m') - for ueipaddress in self.UEIPAddresses: - if ueipaddress == UE_IPAddress: - logging.debug('\u001B[1mUE (' + device_id + ') IP Address ' + UE_IPAddress + ': has already been allocated to another device !' + '\u001B[0m') - ue_ip_status -= 1 - continue - self.UEIPAddresses.append(UE_IPAddress) - idx += 1 - self.close() - return ue_ip_status - - def ping_iperf_wrong_exit(self, lock, UE_IPAddress, device_id, statusQueue, message): - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(message) - lock.release() - - def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue): - try: - # 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 - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - launchFromEpc = False - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - - if launchFromEpc: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) - ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) - else: - cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' - message = cmd + '\n' - logging.debug(cmd) - ret = subprocess.run(cmd, shell=True) - ping_status = ret.returncode - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'ping_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cat ' + self.EPCSourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before)) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before)) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - lock.acquire() - logging.debug('\u001B[1;37;44m ping result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - if (packetLossOK): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(qMsg) - lock.release() - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def PingNoS1_wrong_exit(self, qMsg): - html_queue = SimpleQueue() - html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>' - html_queue.put(html_cell) - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - - def PingNoS1(self): - check_eNB = True - check_OAI_UE = True - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) - if ping_from_eNB is not None: - if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - else: - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': - Usage() - sys.exit('Insufficient Parameter') - try: - if ping_from_eNB is not None: - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets/', '\$', 5) - else: - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5) - self.command('cd cmake_targets', '\$', 5) - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '.log', '\$', int(ping_time[0])*1.5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with OAI UE crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before)) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before)) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - logging.debug('\u001B[1;37;44m OAI UE ping result \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - self.close() - html_queue = SimpleQueue() - ip_addr = 'TBD' - html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>' - html_queue.put(html_cell) - if packetLossOK: - self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - - # copying on the EPC server for logCollection - if ping_from_eNB is not None: - copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') - else: - copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') - if (copyin_res == 0): - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'ping_' + self.testCase_id + '.log', self.EPCSourceCodePath + '/scripts') - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def Ping(self): - result = re.search('noS1', str(self.Initialize_eNB_args)) - if result is not None: - self.PingNoS1() - return - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - check_OAI_UE = True - else: - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ueIpStatus = self.GetAllUEIPAddresses() - if (ueIpStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - i = 0 - lock = Lock() - status_queue = SimpleQueue() - for UE_IPAddress in self.UEIPAddresses: - device_id = self.UEDevices[i] - p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i = i + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - self.CreateHtmlTestRow(self.ping_args, 'KO', ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - ping_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - ping_status = False - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' - html_queue.put(html_cell) - if (ping_status): - self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def Iperf_ComputeTime(self): - result = re.search('-t (?P<iperf_time>\d+)', str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Iperf time Not Found! \u001B[0m') - sys.exit(1) - return result.group('iperf_time') - - def Iperf_ComputeModifiedBW(self, idx, ue_num): - result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Iperf bandwidth Not Found! \u001B[0m') - sys.exit(1) - iperf_bandwidth = result.group('iperf_bandwidth') - if self.iperf_profile == 'balanced': - iperf_bandwidth_new = float(iperf_bandwidth)/ue_num - if self.iperf_profile == 'single-ue': - iperf_bandwidth_new = float(iperf_bandwidth) - if self.iperf_profile == 'unbalanced': - # residual is 2% of max bw - residualBW = float(iperf_bandwidth) / 50 - if idx == 0: - iperf_bandwidth_new = float(iperf_bandwidth) - ((ue_num - 1) * residualBW) - else: - iperf_bandwidth_new = residualBW - iperf_bandwidth_str = '-b ' + iperf_bandwidth - iperf_bandwidth_str_new = '-b ' + ('%.2f' % iperf_bandwidth_new) - result = re.sub(iperf_bandwidth_str, iperf_bandwidth_str_new, str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Calculate Iperf bandwidth Failed! \u001B[0m') - sys.exit(1) - return result - - def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - self.command('awk -f /tmp/tcp_iperf_stats.awk /tmp/CI-eNB/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('Avg Bitrate : (?P<average>[0-9\.]+ Mbits\/sec) Max Bitrate : (?P<maximum>[0-9\.]+ Mbits\/sec) Min Bitrate : (?P<minimum>[0-9\.]+ Mbits\/sec)', str(self.ssh.before)) - if result is not None: - avgbitrate = result.group('average') - maxbitrate = result.group('maximum') - minbitrate = result.group('minimum') - lock.acquire() - logging.debug('\u001B[1;37;44m TCP iperf result (' + UE_IPAddress + ') \u001B[0m') - msg = 'TCP Stats :\n' - if avgbitrate is not None: - logging.debug('\u001B[1;34m Avg Bitrate : ' + avgbitrate + '\u001B[0m') - msg += 'Avg Bitrate : ' + avgbitrate + '\n' - if maxbitrate is not None: - logging.debug('\u001B[1;34m Max Bitrate : ' + maxbitrate + '\u001B[0m') - msg += 'Max Bitrate : ' + maxbitrate + '\n' - if minbitrate is not None: - logging.debug('\u001B[1;34m Min Bitrate : ' + minbitrate + '\u001B[0m') - msg += 'Min Bitrate : ' + minbitrate + '\n' - statusQueue.put(0) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - return 0 - - def Iperf_analyzeV2Output(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - result = re.search('-u', str(iperf_real_options)) - if result is None: - return self.Iperf_analyzeV2TCPOutput(lock, UE_IPAddress, device_id, statusQueue, iperf_real_options) - - result = re.search('Server Report:', str(self.ssh.before)) - if result is None: - result = re.search('read failed: Connection refused', str(self.ssh.before)) - if result is not None: - logging.debug('\u001B[1;37;41m Could not connect to iperf server! \u001B[0m') - else: - logging.debug('\u001B[1;37;41m Server Report and Connection refused Not Found! \u001B[0m') - return -1 - # Computing the requested bandwidth in float - result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(iperf_real_options)) - if result is not None: - req_bandwidth = result.group('iperf_bandwidth') - req_bw = float(req_bandwidth) - result = re.search('-b [0-9\.]+K', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Kbits/sec' % req_bw - req_bw = req_bw * 1000 - result = re.search('-b [0-9\.]+M', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Mbits/sec' % req_bw - req_bw = req_bw * 1000000 - result = re.search('-b [0-9\.]+G', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Gbits/sec' % req_bw - req_bw = req_bw * 1000000000 - - result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', str(self.ssh.before)) - if result is not None: - bitrate = result.group('bitrate') - packetloss = result.group('packetloss') - jitter = result.group('jitter') - lock.acquire() - logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') - iperfStatus = True - msg = 'Req Bitrate : ' + req_bandwidth + '\n' - logging.debug('\u001B[1;34m Req Bitrate : ' + req_bandwidth + '\u001B[0m') - if bitrate is not None: - msg += 'Bitrate : ' + bitrate + '\n' - logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') - result = re.search('(?P<real_bw>[0-9\.]+) [KMG]bits/sec', str(bitrate)) - if result is not None: - actual_bw = float(str(result.group('real_bw'))) - result = re.search('[0-9\.]+ K', bitrate) - if result is not None: - actual_bw = actual_bw * 1000 - result = re.search('[0-9\.]+ M', bitrate) - if result is not None: - actual_bw = actual_bw * 1000000 - result = re.search('[0-9\.]+ G', bitrate) - if result is not None: - actual_bw = actual_bw * 1000000000 - br_loss = 100 * actual_bw / req_bw - bitperf = '%.2f ' % br_loss - msg += 'Bitrate Perf: ' + bitperf + '%\n' - logging.debug('\u001B[1;34m Bitrate Perf: ' + bitperf + '%\u001B[0m') - if packetloss is not None: - msg += 'Packet Loss : ' + packetloss + '%\n' - logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') - if float(packetloss) > float(self.iperf_packetloss_threshold): - msg += 'Packet Loss too high!\n' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - iperfStatus = False - if jitter is not None: - msg += 'Jitter : ' + jitter + '\n' - logging.debug('\u001B[1;34m Jitter : ' + jitter + '\u001B[0m') - if (iperfStatus): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - return 0 - 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')): - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') - return - # Computing the requested bandwidth in float - result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(iperf_real_options)) - if result is None: - logging.debug('Iperf bandwidth Not Found!') - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not compute Iperf bandwidth!') - return - else: - req_bandwidth = result.group('iperf_bandwidth') - req_bw = float(req_bandwidth) - result = re.search('-b [0-9\.]+K', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Kbits/sec' % req_bw - req_bw = req_bw * 1000 - result = re.search('-b [0-9\.]+M', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Mbits/sec' % req_bw - req_bw = req_bw * 1000000 - result = re.search('-b [0-9\.]+G', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Gbits/sec' % req_bw - req_bw = req_bw * 1000000000 - - server_file = open('iperf_server_' + self.testCase_id + '_' + device_id + '.log', 'r') - br_sum = 0.0 - ji_sum = 0.0 - pl_sum = 0 - ps_sum = 0 - row_idx = 0 - for line in server_file.readlines(): - 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') - packetlost = result.group('lostPack') - packetsent = result.group('sentPack') - br = bitrate.split(' ') - ji = jitter.split(' ') - row_idx = row_idx + 1 - curr_br = float(br[0]) - pl_sum = pl_sum + int(packetlost) - ps_sum = ps_sum + int(packetsent) - if (br[1] == 'Kbits/sec'): - curr_br = curr_br * 1000 - if (br[1] == 'Mbits/sec'): - curr_br = curr_br * 1000 * 1000 - br_sum = curr_br + br_sum - ji_sum = float(ji[0]) + ji_sum - if (row_idx > 0): - br_sum = br_sum / row_idx - ji_sum = ji_sum / row_idx - br_loss = 100 * br_sum / req_bw - if (br_sum > 1000): - br_sum = br_sum / 1000 - if (br_sum > 1000): - br_sum = br_sum / 1000 - bitrate = '%.2f Mbits/sec' % br_sum - else: - bitrate = '%.2f Kbits/sec' % br_sum - else: - bitrate = '%.2f bits/sec' % br_sum - bitperf = '%.2f ' % br_loss - bitperf += '%' - jitter = '%.2f ms' % (ji_sum) - if (ps_sum > 0): - pl = float(100 * pl_sum / ps_sum) - packetloss = '%2.1f ' % (pl) - packetloss += '%' - else: - packetloss = 'unknown' - lock.acquire() - if (br_loss < 90): - statusQueue.put(1) - else: - statusQueue.put(0) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - req_msg = 'Req Bitrate : ' + req_bandwidth - bir_msg = 'Bitrate : ' + bitrate - brl_msg = 'Bitrate Perf: ' + bitperf - jit_msg = 'Jitter : ' + jitter - pal_msg = 'Packet Loss : ' + packetloss - statusQueue.put(req_msg + '\n' + bir_msg + '\n' + brl_msg + '\n' + jit_msg + '\n' + pal_msg + '\n') - logging.debug('\u001B[1;37;45m iperf result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;35m ' + req_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + bir_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + brl_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + jit_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + pal_msg + '\u001B[0m') - lock.release() - else: - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') - - server_file.close() - - - def Iperf_analyzeV3Output(self, lock, UE_IPAddress, device_id, statusQueue): - result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P<packetloss>[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', str(self.ssh.before)) - if result is None: - result = re.search('(?P<error>iperf: error - [a-zA-Z0-9 :]+)', str(self.ssh.before)) - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - if result is not None: - logging.debug('\u001B[1;37;41m ' + result.group('error') + ' \u001B[0m') - statusQueue.put(result.group('error')) - else: - logging.debug('\u001B[1;37;41m Bitrate and/or Packet Loss Not Found! \u001B[0m') - statusQueue.put('Bitrate and/or Packet Loss Not Found!') - lock.release() - - bitrate = result.group('bitrate') - packetloss = result.group('packetloss') - lock.acquire() - logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') - msg = 'Bitrate : ' + bitrate + '\n' - iperfStatus = True - if packetloss is not None: - logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') - msg += 'Packet Loss : ' + packetloss + '%\n' - if float(packetloss) > float(self.iperf_packetloss_threshold): - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - msg += 'Packet Loss too high!\n' - iperfStatus = False - if (iperfStatus): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - - def Iperf_UL_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): - udpIperf = True - result = re.search('-u', str(self.iperf_args)) - if result is None: - udpIperf = False - ipnumbers = UE_IPAddress.split('.') - if (len(ipnumbers) == 4): - ipnumbers[3] = '1' - EPC_Iperf_UE_IPAddress = ipnumbers[0] + '.' + ipnumbers[1] + '.' + ipnumbers[2] + '.' + ipnumbers[3] - - # Launch iperf server on EPC side (true for ltebox and old open-air-cn0 - # But for OAI-Rel14-CUPS, we launch from python executor and we are using its IP address as iperf client address - launchFromEpc = True - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - launchFromEpc = False - cmd = 'hostname -I' - ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') - if ret.stdout is not None: - EPC_Iperf_UE_IPAddress = ret.stdout.strip() - port = 5001 + idx - if launchFromEpc: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if udpIperf: - self.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) - else: - self.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) - self.close() - else: - if self.ueIperfVersion == self.dummyIperfVersion: - prefix = '' - else: - prefix = '' - if self.ueIperfVersion == '2.0.5': - prefix = '/opt/iperf-2.0.5/bin/' - if udpIperf: - cmd = 'nohup ' + prefix + 'iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' - else: - cmd = 'nohup ' + prefix + 'iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' - logging.debug(cmd) - subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') - time.sleep(0.5) - - # Launch iperf client on UE - if (device_id == 'OAI-UE'): - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - else: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - iperf_time = self.Iperf_ComputeTime() - time.sleep(0.5) - - if udpIperf: - modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) - else: - modified_options = str(self.iperf_args) - modified_options = modified_options.replace('-R','') - time.sleep(0.5) - - self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if (device_id == 'OAI-UE'): - iperf_status = self.command('iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + ' -B ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - if self.ADBCentralized: - iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - iperf_status = self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '"\' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - self.command('fromdos -o iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - self.command('cat iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - # TIMEOUT Case - if iperf_status < 0: - self.close() - message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) - self.close() - - # Kill iperf server on EPC side - if launchFromEpc: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('killall --signal SIGKILL iperf', self.EPCUserName, 5) - self.close() - else: - cmd = 'killall --signal SIGKILL iperf' - logging.debug(cmd) - subprocess.run(cmd, shell=True) - time.sleep(1) - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - # in case of failure, retrieve server log - if (clientStatus == -1) or (clientStatus == -2): - if launchFromEpc: - time.sleep(1) - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) - # in case of OAI-UE - if (device_id == 'OAI-UE'): - self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.') - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - - def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): - try: - # Single-UE profile -- iperf only on one UE - if self.iperf_profile == 'single-ue' and idx != 0: - return - useIperf3 = False - udpIperf = True - - self.ueIperfVersion = '2.0.5' - if (device_id != 'OAI-UE'): - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it - self.command('if [ ! -d ' + self.EPCSourceCodePath + '/scripts ]; then mkdir -p ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - # Checking if iperf / iperf3 are installed - if self.ADBCentralized: - self.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ls /data/local/tmp"\'', '\$', 60) - result = re.search('iperf3', str(self.ssh.before)) - if result is None: - result = re.search('iperf', str(self.ssh.before)) - if result is None: - message = 'Neither iperf nor iperf3 installed on UE!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - else: - if self.ADBCentralized: - self.command('adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"', '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"\'', '\$', 60) - result = re.search('iperf version 2.0.5', str(self.ssh.before)) - if result is not None: - self.ueIperfVersion = '2.0.5' - result = re.search('iperf version 2.0.10', str(self.ssh.before)) - if result is not None: - self.ueIperfVersion = '2.0.10' - else: - useIperf3 = True - self.close() - else: - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('iperf --version', '\$', 5) - result = re.search('iperf version 2.0.5', str(self.ssh.before)) - if result is not None: - self.ueIperfVersion = '2.0.5' - result = re.search('iperf version 2.0.10', str(self.ssh.before)) - if result is not None: - self.ueIperfVersion = '2.0.10' - self.close() - # in case of iperf, UL has its own function - if (not useIperf3): - result = re.search('-R', str(self.iperf_args)) - if result is not None: - self.Iperf_UL_common(lock, UE_IPAddress, device_id, idx, ue_num, statusQueue) - return - - # Launch the IPERF server on the UE side for DL - if (device_id == 'OAI-UE'): - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('-u', str(self.iperf_args)) - if result is None: - self.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) - udpIperf = False - else: - self.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) - else: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - if self.ADBCentralized: - if (useIperf3): - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) - else: - self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('-u', str(self.iperf_args)) - if result is None: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) - udpIperf = False - else: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) - else: - self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - self.command('echo $USER; nohup ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" \' 2>&1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 60) - - time.sleep(0.5) - self.close() - - # 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 - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - launchFromEpc = False - if launchFromEpc: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - iperf_time = self.Iperf_ComputeTime() - time.sleep(0.5) - - if udpIperf: - modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) - else: - modified_options = str(self.iperf_args) - time.sleep(0.5) - - if launchFromEpc: - self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - else: - if (os.path.isfile('iperf_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_' + self.testCase_id + '_' + device_id + '.log') - if (useIperf3): - self.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - - clientStatus = 0 - self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue) - else: - if launchFromEpc: - iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - if self.ueIperfVersion == self.dummyIperfVersion: - prefix = '' - else: - prefix = '' - if self.ueIperfVersion == '2.0.5': - prefix = '/opt/iperf-2.0.5/bin/' - cmd = prefix + 'iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log' - message = cmd + '\n' - logging.debug(cmd) - ret = subprocess.run(cmd, shell=True) - iperf_status = ret.returncode - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cat ' + self.EPCSourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if iperf_status < 0: - if launchFromEpc: - self.close() - message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) - self.close() - - # Kill the IPERF server that runs in background - if (device_id == 'OAI-UE'): - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('killall iperf', '\$', 5) - else: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps" | grep --color=never iperf | grep -v grep\'', '\$', 60) - result = re.search('shell +(?P<pid>\d+)', str(self.ssh.before)) - if result is not None: - pid_iperf = result.group('pid') - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) - self.close() - # if the client report is absent, try to analyze the server log file - if (clientStatus == -1): - time.sleep(1) - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - if (device_id == 'OAI-UE'): - self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - else: - self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - self.command('fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) - - # in case of OAI UE: - if (device_id == 'OAI-UE'): - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - if not launchFromEpc: - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - else: - self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def IperfNoS1(self): - if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = True - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - server_on_enb = re.search('-R', str(self.iperf_args)) - if server_on_enb is not None: - iServerIPAddr = self.eNBIPAddress - iServerUser = self.eNBUserName - iServerPasswd = self.eNBPassword - iClientIPAddr = self.UEIPAddress - iClientUser = self.UEUserName - iClientPasswd = self.UEPassword - else: - iServerIPAddr = self.UEIPAddress - iServerUser = self.UEUserName - iServerPasswd = self.UEPassword - iClientIPAddr = self.eNBIPAddress - iClientUser = self.eNBUserName - iClientPasswd = self.eNBPassword - # Starting the iperf server - self.open(iServerIPAddr, iServerUser, iServerPasswd) - # args SHALL be "-c client -u any" - # -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1 - # -B 10.0.1.1 -u -s -i 1 -fm - server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args)) - server_options = server_options.replace('-c','-B') - self.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5) - self.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5) - time.sleep(0.5) - self.close() - - # Starting the iperf client - modified_options = self.Iperf_ComputeModifiedBW(0, 1) - modified_options = modified_options.replace('-R','') - iperf_time = self.Iperf_ComputeTime() - self.open(iClientIPAddr, iClientUser, iClientPasswd) - self.command('rm -f /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', 5) - iperf_status = self.command('stdbuf -o0 iperf ' + modified_options + ' 2>&1 | stdbuf -o0 tee /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', int(iperf_time)*5.0) - status_queue = SimpleQueue() - lock = Lock() - if iperf_status < 0: - message = 'iperf on OAI UE crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - clientStatus = -2 - else: - clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) - self.close() - - # Stopping the iperf server - self.open(iServerIPAddr, iServerUser, iServerPasswd) - self.command('killall --signal SIGKILL iperf', '\$', 5) - time.sleep(0.5) - self.close() - if (clientStatus == -1): - if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '.log') - self.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) - - # copying on the EPC server for logCollection - copyin_res = self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') - if (copyin_res == 0): - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') - copyin_res = self.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log') - if (copyin_res == 0): - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') - iperf_noperf = False - if status_queue.empty(): - iperf_status = False - else: - iperf_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - iperf_status = False - if (count > 0): - iperf_noperf = True - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' - html_queue.put(html_cell) - if (iperf_noperf and iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) - elif (iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def Iperf(self): - result = re.search('noS1', str(self.Initialize_eNB_args)) - if result is not None: - self.IperfNoS1() - return - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - check_OAI_UE = True - else: - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ueIpStatus = self.GetAllUEIPAddresses() - if (ueIpStatus < 0): - self.CreateHtmlTestRow(self.iperf_args, 'KO', UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB() - return - - self.dummyIperfVersion = '2.0.10' - #cmd = 'iperf --version' - #logging.debug(cmd + '\n') - #iperfStdout = subprocess.check_output(cmd, shell=True, universal_newlines=True) - #result = re.search('iperf version 2.0.5', str(iperfStdout.strip())) - #if result is not None: - # dummyIperfVersion = '2.0.5' - #result = re.search('iperf version 2.0.10', str(iperfStdout.strip())) - #if result is not None: - # dummyIperfVersion = '2.0.10' - - multi_jobs = [] - i = 0 - ue_num = len(self.UEIPAddresses) - lock = Lock() - status_queue = SimpleQueue() - for UE_IPAddress in self.UEIPAddresses: - device_id = self.UEDevices[i] - p = Process(target = SSH.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i = i + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - self.CreateHtmlTestRow(self.iperf_args, 'KO', ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - iperf_status = True - iperf_noperf = False - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - iperf_status = False - if (count > 0): - iperf_noperf = True - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' - html_queue.put(html_cell) - if (iperf_noperf and iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) - elif (iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def CheckProcessExist(self, check_eNB, check_OAI_UE): - multi_jobs = [] - status_queue = SimpleQueue() - # in noS1 config, no need to check status from EPC - result = re.search('noS1', str(self.Initialize_eNB_args)) - if result is None: - p = Process(target = SSH.CheckHSSProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = SSH.CheckMMEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = SSH.CheckSPGWProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - else: - if (check_eNB == False) and (check_OAI_UE == False): - return 0 - if check_eNB: - p = Process(target = SSH.CheckeNBProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - if check_OAI_UE: - p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - return -15 - else: - result = 0 - while (not status_queue.empty()): - status = status_queue.get() - if (status < 0): - result = status - if result == ENB_PROCESS_FAILED: - fileCheck = re.search('enb_', str(self.eNBLogFiles[0])) - if fileCheck is not None: - self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFiles[0], '.') - logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFiles[0]) - if logStatus < 0: - result = logStatus - self.eNBLogFiles[0] = '' - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.TerminateFlexranCtrl() - return result - - def CheckOAIUEProcessExist(self, initialize_OAI_UE_flag): - multi_jobs = [] - status_queue = SimpleQueue() - if initialize_OAI_UE_flag == False: - p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - return -15 - else: - result = 0 - while (not status_queue.empty()): - status = status_queue.get() - if (status < 0): - result = status - if result == OAI_UE_PROCESS_FAILED: - fileCheck = re.search('ue_', str(self.UELogFile)) - if fileCheck is not None: - self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') - logStatus = self.AnalyzeLogFile_UE(self.UELogFile) - if logStatus < 0: - result = logStatus - return result - - def CheckOAIUEProcess(self, status_queue): - try: - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m') - status_queue.put(OAI_UE_PROCESS_FAILED) - else: - status_queue.put(OAI_UE_PROCESS_OK) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckeNBProcess(self, status_queue): - try: - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-softmodem', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m') - status_queue.put(ENB_PROCESS_FAILED) - else: - status_queue.put(ENB_PROCESS_OK) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckHSSProcess(self, status_queue): - try: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('stdbuf -o0 ps -aux | grep --color=never hss | grep -v grep', '\$', 5) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - result = re.search('oai_hss -j', str(self.ssh.before)) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - result = re.search('hss_sim s6as diam_hss', str(self.ssh.before)) - else: - logging.error('This should not happen!') - if result is None: - logging.debug('\u001B[1;37;41m HSS Process Not Found! \u001B[0m') - status_queue.put(HSS_PROCESS_FAILED) - else: - status_queue.put(HSS_PROCESS_OK) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckMMEProcess(self, status_queue): - try: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('stdbuf -o0 ps -aux | grep --color=never mme | grep -v grep', '\$', 5) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - result = re.search('mme -c', str(self.ssh.before)) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - result = re.search('mme', str(self.ssh.before)) - else: - logging.error('This should not happen!') - if result is None: - logging.debug('\u001B[1;37;41m MME Process Not Found! \u001B[0m') - status_queue.put(MME_PROCESS_FAILED) - else: - status_queue.put(MME_PROCESS_OK) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckSPGWProcess(self, status_queue): - try: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5) - result = re.search('spgwu -c ', str(self.ssh.before)) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5) - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('stdbuf -o0 ps -aux | grep --color=never xGw | grep -v grep', '\$', 5) - result = re.search('xGw', str(self.ssh.before)) - else: - logging.error('This should not happen!') - if result is None: - logging.debug('\u001B[1;37;41m SPGW Process Not Found! \u001B[0m') - status_queue.put(SPGW_PROCESS_FAILED) - else: - status_queue.put(SPGW_PROCESS_OK) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AnalyzeLogFile_eNB(self, eNBlogFile): - if (not os.path.isfile('./' + eNBlogFile)): - return -1 - enb_log_file = open('./' + eNBlogFile, 'r') - exitSignalReceived = False - foundAssertion = False - msgAssertion = '' - msgLine = 0 - foundSegFault = False - foundRealTimeIssue = False - rrcSetupComplete = 0 - rrcReleaseRequest = 0 - rrcReconfigRequest = 0 - rrcReconfigComplete = 0 - rrcReestablishRequest = 0 - rrcReestablishComplete = 0 - rrcReestablishReject = 0 - rlcDiscardBuffer = 0 - rachCanceledProcedure = 0 - uciStatMsgCount = 0 - pdcpFailure = 0 - ulschFailure = 0 - cdrxActivationMessageCount = 0 - dropNotEnoughRBs = 0 - self.htmleNBFailureMsg = '' - isRRU = False - isSlave = False - slaveReceivesFrameResyncCmd = False - X2HO_state = X2_HO_REQ_STATE__IDLE - X2HO_inNbProcedures = 0 - X2HO_outNbProcedures = 0 - for line in enb_log_file.readlines(): - if X2HO_state == X2_HO_REQ_STATE__IDLE: - result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__TARGET_RECEIVES_REQ - result = re.search('source eNB receives the X2 HO ACK X2AP_HANDOVER_REQ_ACK', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK - if X2HO_state == X2_HO_REQ_STATE__TARGET_RECEIVES_REQ: - result = re.search('Received LTE_RRCConnectionReconfigurationComplete from UE', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE - if X2HO_state == X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE: - result = re.search('issue rrc_eNB_send_PATH_SWITCH_REQ', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ - if X2HO_state == X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ: - result = re.search('received path switch ack S1AP_PATH_SWITCH_REQ_ACK', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__IDLE - X2HO_inNbProcedures += 1 - if X2HO_state == X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK: - result = re.search('source eNB receives the X2 UE CONTEXT RELEASE X2AP_UE_CONTEXT_RELEASE', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__IDLE - X2HO_outNbProcedures += 1 - - if self.eNBOptions[int(self.eNB_instance)] != '': - res1 = re.search('max_rxgain (?P<requested_option>[0-9]+)', self.eNBOptions[int(self.eNB_instance)]) - res2 = re.search('max_rxgain (?P<applied_option>[0-9]+)', str(line)) - if res1 is not None and res2 is not None: - requested_option = int(res1.group('requested_option')) - applied_option = int(res2.group('applied_option')) - if requested_option == applied_option: - self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ok-circle"></span> Command line option(s) correctly applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n' - else: - self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ban-circle"></span> Command line option(s) NOT applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n' - result = re.search('Exiting OAI softmodem', str(line)) - if result is not None: - exitSignalReceived = True - result = re.search('[Ss]egmentation [Ff]ault', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('./lte_build_oai/build/lte-softmodem', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Aa]ssertion', str(line)) - if result is not None and not exitSignalReceived: - foundAssertion = True - result = re.search('LLL', str(line)) - if result is not None and not exitSignalReceived: - foundRealTimeIssue = True - if foundAssertion and (msgLine < 3): - msgLine += 1 - msgAssertion += str(line) - result = re.search('Setting function for RU', str(line)) - if result is not None: - isRRU = True - if isRRU: - result = re.search('RU 0 is_slave=yes', str(line)) - if result is not None: - isSlave = True - if isSlave: - result = re.search('Received RRU_frame_resynch command', str(line)) - if result is not None: - slaveReceivesFrameResyncCmd = True - result = re.search('LTE_RRCConnectionSetupComplete from UE', str(line)) - if result is not None: - rrcSetupComplete += 1 - result = re.search('Generate LTE_RRCConnectionRelease|Generate RRCConnectionRelease', str(line)) - if result is not None: - rrcReleaseRequest += 1 - result = re.search('Generate LTE_RRCConnectionReconfiguration', str(line)) - if result is not None: - rrcReconfigRequest += 1 - result = re.search('LTE_RRCConnectionReconfigurationComplete from UE rnti', str(line)) - if result is not None: - rrcReconfigComplete += 1 - result = re.search('LTE_RRCConnectionReestablishmentRequest', str(line)) - if result is not None: - rrcReestablishRequest += 1 - result = re.search('LTE_RRCConnectionReestablishmentComplete', str(line)) - if result is not None: - rrcReestablishComplete += 1 - result = re.search('LTE_RRCConnectionReestablishmentReject', str(line)) - if result is not None: - rrcReestablishReject += 1 - result = re.search('CDRX configuration activated after RRC Connection', str(line)) - if result is not None: - cdrxActivationMessageCount += 1 - result = re.search('uci->stat', str(line)) - if result is not None: - uciStatMsgCount += 1 - result = re.search('PDCP.*Out of Resources.*reason', str(line)) - if result is not None: - pdcpFailure += 1 - result = re.search('ULSCH in error in round', str(line)) - if result is not None: - ulschFailure += 1 - result = re.search('BAD all_segments_received', str(line)) - if result is not None: - rlcDiscardBuffer += 1 - result = re.search('Canceled RA procedure for UE rnti', str(line)) - if result is not None: - rachCanceledProcedure += 1 - result = re.search('dropping, not enough RBs', str(line)) - if result is not None: - dropNotEnoughRBs += 1 - enb_log_file.close() - logging.debug(' File analysis completed') - if uciStatMsgCount > 0: - statMsg = 'eNB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if pdcpFailure > 0: - statMsg = 'eNB showed ' + str(pdcpFailure) + ' "PDCP Out of Resources" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if ulschFailure > 0: - statMsg = 'eNB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if dropNotEnoughRBs > 0: - statMsg = 'eNB showed ' + str(dropNotEnoughRBs) + ' "dropping, not enough RBs" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if rrcSetupComplete > 0: - rrcMsg = 'eNB completed ' + str(rrcSetupComplete) + ' RRC Connection Setup(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rrcReleaseRequest > 0: - rrcMsg = 'eNB requested ' + str(rrcReleaseRequest) + ' RRC Connection Release(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rrcReconfigRequest > 0 or rrcReconfigComplete > 0: - rrcMsg = 'eNB requested ' + str(rrcReconfigRequest) + ' RRC Connection Reconfiguration(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReconfigComplete) + ' were completed' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rrcReestablishRequest > 0 or rrcReestablishComplete > 0 or rrcReestablishReject > 0: - rrcMsg = 'eNB requested ' + str(rrcReestablishRequest) + ' RRC Connection Reestablishment(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReestablishComplete) + ' were completed' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if X2HO_inNbProcedures > 0: - rrcMsg = 'eNB completed ' + str(X2HO_inNbProcedures) + ' X2 Handover Connection procedure(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if X2HO_outNbProcedures > 0: - rrcMsg = 'eNB completed ' + str(X2HO_outNbProcedures) + ' X2 Handover Release procedure(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if self.eNBOptions[int(self.eNB_instance)] != '': - res1 = re.search('drx_Config_present prSetup', self.eNBOptions[int(self.eNB_instance)]) - if res1 is not None: - if cdrxActivationMessageCount > 0: - rrcMsg = 'eNB activated the CDRX Configuration for ' + str(cdrxActivationMessageCount) + ' time(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - else: - rrcMsg = 'eNB did NOT ACTIVATE the CDRX Configuration' - logging.debug('\u001B[1;37;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rachCanceledProcedure > 0: - rachMsg = 'eNB cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)' - logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rachMsg + '\n' - if isRRU: - if isSlave: - if slaveReceivesFrameResyncCmd: - rruMsg = 'Slave RRU received the RRU_frame_resynch command from RAU' - logging.debug('\u001B[1;30;43m ' + rruMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rruMsg + '\n' - else: - rruMsg = 'Slave RRU DID NOT receive the RRU_frame_resynch command from RAU' - logging.debug('\u001B[1;37;41m ' + rruMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rruMsg + '\n' - self.prematureExit = True - return ENB_PROCESS_SLAVE_RRU_NOT_SYNCED - if foundSegFault: - logging.debug('\u001B[1;37;41m eNB ended with a Segmentation Fault! \u001B[0m') - return ENB_PROCESS_SEG_FAULT - if foundAssertion: - logging.debug('\u001B[1;37;41m eNB ended with an assertion! \u001B[0m') - self.htmleNBFailureMsg += msgAssertion - return ENB_PROCESS_ASSERTION - if foundRealTimeIssue: - logging.debug('\u001B[1;37;41m eNB faced real time issues! \u001B[0m') - self.htmleNBFailureMsg += 'eNB faced real time issues!\n' - #return ENB_PROCESS_REALTIME_ISSUE - if rlcDiscardBuffer > 0: - rlcMsg = 'eNB RLC discarded ' + str(rlcDiscardBuffer) + ' buffer(s)' - logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rlcMsg + '\n' - return ENB_PROCESS_REALTIME_ISSUE - return 0 - - def AnalyzeLogFile_UE(self, UElogFile): - if (not os.path.isfile('./' + UElogFile)): - return -1 - ue_log_file = open('./' + UElogFile, 'r') - exitSignalReceived = False - foundAssertion = False - msgAssertion = '' - msgLine = 0 - foundSegFault = False - foundRealTimeIssue = False - uciStatMsgCount = 0 - pdcpDataReqFailedCount = 0 - badDciCount = 0 - rrcConnectionRecfgComplete = 0 - no_cell_sync_found = False - mib_found = False - frequency_found = False - plmn_found = False - self.htmlUEFailureMsg = '' - for line in ue_log_file.readlines(): - result = re.search('Exiting OAI softmodem', str(line)) - if result is not None: - exitSignalReceived = True - result = re.search('System error|[Ss]egmentation [Ff]ault|======= Backtrace: =========|======= Memory map: ========', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('./lte-uesoftmodem', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Aa]ssertion', str(line)) - if result is not None and not exitSignalReceived: - foundAssertion = True - result = re.search('LLL', str(line)) - if result is not None and not exitSignalReceived: - foundRealTimeIssue = True - if foundAssertion and (msgLine < 3): - msgLine += 1 - msgAssertion += str(line) - result = re.search('uci->stat', str(line)) - if result is not None and not exitSignalReceived: - uciStatMsgCount += 1 - result = re.search('PDCP data request failed', str(line)) - if result is not None and not exitSignalReceived: - pdcpDataReqFailedCount += 1 - result = re.search('bad DCI 1A', str(line)) - if result is not None and not exitSignalReceived: - badDciCount += 1 - result = re.search('Generating RRCConnectionReconfigurationComplete', str(line)) - if result is not None: - rrcConnectionRecfgComplete += 1 - # No cell synchronization found, abandoning - result = re.search('No cell synchronization found, abandoning', str(line)) - if result is not None: - no_cell_sync_found = True - result = re.search("MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P<nidcell>\d{1,3}), N_RB_DL (?P<n_rb_dl>\d{1,3}), PHICH DURATION (?P<phich_duration>\d), PHICH RESOURCE (?P<phich_resource>.{1,4}), TX_ANT (?P<tx_ant>\d)", str(line)) - if result is not None and (not mib_found): - try: - mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2) - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " nidcell = " + result.group('nidcell') - self.htmlUEFailureMsg += mibMsg - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " n_rb_dl = " + result.group('n_rb_dl') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " phich_duration = " + result.group('phich_duration') - self.htmlUEFailureMsg += mibMsg - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " phich_resource = " + result.group('phich_resource') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " tx_ant = " + result.group('tx_ant') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mib_found = True - except Exception as e: - logging.error('\033[91m' + "MIB marker was not found" + '\033[0m') - result = re.search("Measured Carrier Frequency (?P<measured_carrier_frequency>\d{1,15}) Hz", str(line)) - if result is not None and (not frequency_found): - try: - mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz' - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - frequency_found = True - except Exception as e: - logging.error('\033[91m' + "Measured Carrier Frequency not found" + '\033[0m') - result = re.search("PLMN MCC (?P<mcc>\d{1,3}), MNC (?P<mnc>\d{1,3}), TAC", str(line)) - if result is not None and (not plmn_found): - try: - mibMsg = 'PLMN MCC = ' + result.group('mcc') + ' MNC = ' + result.group('mnc') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - plmn_found = True - except Exception as e: - logging.error('\033[91m' + "PLMN not found" + '\033[0m') - result = re.search("Found (?P<operator>[\w,\s]{1,15}) \(name from internal table\)", str(line)) - if result is not None: - try: - mibMsg = "The operator is: " + result.group('operator') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - except Exception as e: - logging.error('\033[91m' + "Operator name not found" + '\033[0m') - result = re.search("SIB5 InterFreqCarrierFreq element (.{1,4})/(.{1,4})", str(line)) - if result is not None: - try: - mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2) - self.htmlUEFailureMsg += mibMsg + ' -> ' - logging.debug('\033[94m' + mibMsg + '\033[0m') - except Exception as e: - logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m') - result = re.search("DL Carrier Frequency/ARFCN : (?P<carrier_frequency>\d{1,15}/\d{1,4})", str(line)) - if result is not None: - try: - freq = result.group('carrier_frequency') - new_freq = re.sub('/[0-9]+','',freq) - float_freq = float(new_freq) / 1000000 - self.htmlUEFailureMsg += 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz' - logging.debug('\033[94m' + " DL Carrier Frequency is: " + freq + '\033[0m') - except Exception as e: - logging.error('\033[91m' + " DL Carrier Frequency not found" + '\033[0m') - result = re.search("AllowedMeasBandwidth : (?P<allowed_bandwidth>\d{1,7})", str(line)) - if result is not None: - try: - prb = result.group('allowed_bandwidth') - self.htmlUEFailureMsg += ' -- PRB: ' + prb + '\n' - logging.debug('\033[94m' + " AllowedMeasBandwidth: " + prb + '\033[0m') - except Exception as e: - logging.error('\033[91m' + " AllowedMeasBandwidth not found" + '\033[0m') - ue_log_file.close() - if rrcConnectionRecfgComplete > 0: - statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)' - logging.debug('\033[94m' + statMsg + '\033[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if uciStatMsgCount > 0: - statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if pdcpDataReqFailedCount > 0: - statMsg = 'UE showed ' + str(pdcpDataReqFailedCount) + ' "PDCP data request failed" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if badDciCount > 0: - statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1A" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if foundSegFault: - logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') - return ENB_PROCESS_SEG_FAULT - if foundAssertion: - logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m') - self.htmlUEFailureMsg += 'UE showed an assertion!\n' - if not mib_found or not frequency_found: - return OAI_UE_PROCESS_ASSERTION - if foundRealTimeIssue: - logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m') - self.htmlUEFailureMsg += 'UE faced real time issues!\n' - #return ENB_PROCESS_REALTIME_ISSUE - if no_cell_sync_found and not mib_found: - logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m') - self.htmlUEFailureMsg += 'UE could not synchronize!\n' - return OAI_UE_PROCESS_COULD_NOT_SYNC - return 0 - - def TerminateeNB(self): - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(lIpAddr, lUserName, lPassWord) - self.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) - self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-softmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) - self.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5) - time.sleep(10) - self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-softmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) - time.sleep(5) - self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.close() - # If tracer options is on, stopping tshark on EPC side - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) - time.sleep(1) - if self.EPC_PcapFileName != '': - self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5) - self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.') - self.copyout(lIpAddr, lUserName, lPassWord, self.EPC_PcapFileName, lSourcePath + '/cmake_targets/.') - self.close() - logging.debug('\u001B[1m Replaying RAW record file\u001B[0m') - self.open(lIpAddr, lUserName, lPassWord) - self.command('cd ' + lSourcePath + '/common/utils/T/tracer/', '\$', 5) - enbLogFile = self.eNBLogFiles[int(self.eNB_instance)] - raw_record_file = enbLogFile.replace('.log', '_record.raw') - replay_log_file = enbLogFile.replace('.log', '_replay.log') - extracted_txt_file = enbLogFile.replace('.log', '_extracted_messages.txt') - extracted_log_file = enbLogFile.replace('.log', '_extracted_messages.log') - self.command('./extract_config -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + extracted_txt_file, '\$', 5) - self.command('echo $USER; nohup ./replay -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', lUserName, 5) - self.command('./textlog -d ' + lSourcePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + lSourcePath + '/cmake_targets/' + extracted_log_file, '\$', 5) - self.close() - self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + extracted_log_file, '.') - logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m') - logStatus = self.AnalyzeLogFile_eNB(extracted_log_file) - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.eNBLogFiles[int(self.eNB_instance)] = '' - else: - analyzeFile = False - if self.eNBLogFiles[int(self.eNB_instance)] != '': - analyzeFile = True - fileToAnalyze = self.eNBLogFiles[int(self.eNB_instance)] - self.eNBLogFiles[int(self.eNB_instance)] = '' - if analyzeFile: - copyin_res = self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + fileToAnalyze, '.') - if (copyin_res == -1): - logging.debug('\u001B[1;37;41m Could not copy eNB logfile to analyze it! \u001B[0m') - self.htmleNBFailureMsg = 'Could not copy eNB logfile to analyze it!' - self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE) - return - if self.eNB_serverId != '0': - self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/') - logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m ' + fileToAnalyze) - logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze) - if (logStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', logStatus) - self.preamtureExit = True - return - else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateHSS(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT oai_hss || true', '\$', 5) - time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep hss | grep -v grep', '\$', 5) - result = re.search('oai_hss -j', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL oai_hss || true', '\$', 5) - self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-hss.sh', '\$', 5) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_hss oai_hss || true', '\$', 5) - time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep hss | grep -v grep', '\$', 5) - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_hss oai_hss || true', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=simulated_hss --stop', '\$', 5) - time.sleep(1) - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL hss_sim', '\$', 5) - else: - logging.error('This should not happen!') - self.close() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateMME(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_mme mme || true', '\$', 5) - time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep mme | grep -v grep', '\$', 5) - result = re.search('mme -c', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_mme mme || true', '\$', 5) - self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-mme.sh', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cd /opt/ltebox/tools', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./stop_mme', '\$', 5) - else: - logging.error('This should not happen!') - self.close() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateSPGW(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT spgwc spgwu || true', '\$', 5) - time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5) - result = re.search('spgwc -c |spgwu -c ', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL spgwc spgwu || true', '\$', 5) - self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-spgw*.sh', '\$', 5) - self.command('stdbuf -o0 ps -aux | grep tshark | grep -v grep', '\$', 5) - result = re.search('-w ', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT tshark || true', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 ' + self.EPCSourceCodePath + '/scripts/*.pcap', '\$', 5) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_spgw spgw || true', '\$', 5) - time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5) - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_spgw spgw || true', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cd /opt/ltebox/tools', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./stop_xGw', '\$', 5) - else: - logging.error('This should not happen!') - self.close() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateFlexranCtrl(self): - if self.flexranCtrlInstalled == False or self.flexranCtrlStarted == False: - return - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5) - time.sleep(1) - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5) - time.sleep(1) - self.close() - self.flexranCtrlStarted = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateUE_common(self, device_id, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # back in airplane mode on (ie radio off) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') - - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"', '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"\'', '\$', 60) - result = re.search('shell +(?P<pid>\d+)', str(self.ssh.before)) - if result is not None: - pid_iperf = result.group('pid') - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"', '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def TerminateUE(self): - terminate_ue_flag = True - self.GetAllUEDevices(terminate_ue_flag) - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target= SSH.TerminateUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateOAIUE(self): - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - self.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.UEPassword + ' | sudo -S daemon --name=ue' + str(self.UE_instance) + '_daemon --stop', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT lte-uesoftmodem || true', '\$', 5) - time.sleep(10) - self.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL lte-uesoftmodem || true', '\$', 5) - time.sleep(5) - self.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - self.close() - result = re.search('ue_', str(self.UELogFile)) - if result is not None: - copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') - if (copyin_res == -1): - logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m') - self.htmlUEFailureMsg = 'Could not copy UE logfile to analyze it!' - self.CreateHtmlTestRow('N/A', 'KO', OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE') - self.UELogFile = '' - return - logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m') - logStatus = self.AnalyzeLogFile_UE(self.UELogFile) - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is not None: - ueAction = 'Sniffing' - else: - ueAction = 'Connection' - if (logStatus < 0): - logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') - self.htmlUEFailureMsg = '<b>' + ueAction + ' Failed</b>\n' + self.htmlUEFailureMsg - self.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') - # In case of sniffing on commercial eNBs we have random results - # Not an error then - if (logStatus != OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): - self.Initialize_OAI_UE_args = '' - self.AutoTerminateUEandeNB() - else: - logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') - self.htmlUEFailureMsg = '<b>' + ueAction + ' Completed</b>\n' + self.htmlUEFailureMsg - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.UELogFile = '' - else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def AutoTerminateUEandeNB(self): - if (self.ADBIPAddress != 'none'): - self.testCase_id = 'AUTO-KILL-UE' - self.desc = 'Automatic Termination of UE' - self.ShowTestID() - self.TerminateUE() - if (self.Initialize_OAI_UE_args != ''): - self.testCase_id = 'AUTO-KILL-UE' - self.desc = 'Automatic Termination of UE' - self.ShowTestID() - self.TerminateOAIUE() - if (self.Initialize_eNB_args != ''): - self.testCase_id = 'AUTO-KILL-eNB' - self.desc = 'Automatic Termination of eNB' - self.ShowTestID() - self.eNB_instance = '0' - self.TerminateeNB() - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.testCase_id = 'AUTO-KILL-flexran-ctl' - self.desc = 'Automatic Termination of FlexRan CTL' - self.ShowTestID() - self.TerminateFlexranCtrl() - self.prematureExit = True - - def IdleSleep(self): - time.sleep(self.idle_sleep_time) - self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK) - - def X2_Status(self, idx, fileName): - cmd = "curl --silent http://" + self.EPCIPAddress + ":9999/stats | jq '.' > " + fileName - message = cmd + '\n' - logging.debug(cmd) - subprocess.run(cmd, shell=True) - if idx == 0: - cmd = "jq '.mac_stats | length' " + fileName - strNbEnbs = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2NbENBs = int(strNbEnbs.strip()) - cnt = 0 - while cnt < self.x2NbENBs: - cmd = "jq '.mac_stats[" + str(cnt) + "].bs_id' " + fileName - bs_id = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2ENBBsIds[idx].append(bs_id.strip()) - cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats | length' " + fileName - stNbUEs = subprocess.check_output(cmd, shell=True, universal_newlines=True) - nbUEs = int(stNbUEs.strip()) - ueIdx = 0 - self.x2ENBConnectedUEs[idx].append([]) - while ueIdx < nbUEs: - cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats[" + str(ueIdx) + "].rnti' " + fileName - rnti = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2ENBConnectedUEs[idx][cnt].append(rnti.strip()) - ueIdx += 1 - cnt += 1 - - msg = "FlexRan Controller is connected to " + str(self.x2NbENBs) + " eNB(s)" - logging.debug(msg) - message += msg + '\n' - cnt = 0 - while cnt < self.x2NbENBs: - msg = " -- eNB: " + str(self.x2ENBBsIds[idx][cnt]) + " is connected to " + str(len(self.x2ENBConnectedUEs[idx][cnt])) + " UE(s)" - logging.debug(msg) - message += msg + '\n' - ueIdx = 0 - while ueIdx < len(self.x2ENBConnectedUEs[idx][cnt]): - msg = " -- UE rnti: " + str(self.x2ENBConnectedUEs[idx][cnt][ueIdx]) - logging.debug(msg) - message += msg + '\n' - ueIdx += 1 - cnt += 1 - return message - - def Perform_X2_Handover(self): - html_queue = SimpleQueue() - fullMessage = '<pre style="background-color:white">' - msg = 'Doing X2 Handover w/ option ' + self.x2_ho_options - logging.debug(msg) - fullMessage += msg + '\n' - if self.x2_ho_options == 'network': - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.x2ENBBsIds = [] - self.x2ENBConnectedUEs = [] - self.x2ENBBsIds.append([]) - self.x2ENBBsIds.append([]) - self.x2ENBConnectedUEs.append([]) - self.x2ENBConnectedUEs.append([]) - fullMessage += self.X2_Status(0, self.testCase_id + '_pre_ho.json') - - msg = "Activating the X2 Net control on each eNB" - logging.debug(msg) - fullMessage += msg + '\n' - eNB_cnt = self.x2NbENBs - cnt = 0 - while cnt < eNB_cnt: - cmd = "curl -XPOST http://" + self.EPCIPAddress + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1" - logging.debug(cmd) - fullMessage += cmd + '\n' - subprocess.run(cmd, shell=True) - cnt += 1 - # Waiting for the activation to be active - time.sleep(10) - msg = "Switching UE(s) from eNB to eNB" - logging.debug(msg) - fullMessage += msg + '\n' - cnt = 0 - while cnt < eNB_cnt: - ueIdx = 0 - while ueIdx < len(self.x2ENBConnectedUEs[0][cnt]): - cmd = "curl -XPOST http://" + self.EPCIPAddress + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1]) - logging.debug(cmd) - fullMessage += cmd + '\n' - subprocess.run(cmd, shell=True) - ueIdx += 1 - cnt += 1 - time.sleep(10) - # check - logging.debug("Checking the Status after X2 Handover") - fullMessage += self.X2_Status(1, self.testCase_id + '_post_ho.json') - cnt = 0 - x2Status = True - while cnt < eNB_cnt: - if len(self.x2ENBConnectedUEs[0][cnt]) == len(self.x2ENBConnectedUEs[1][cnt]): - x2Status = False - cnt += 1 - if x2Status: - msg = "X2 Handover was successful" - logging.debug(msg) - fullMessage += msg + '</pre>' - html_queue.put(fullMessage) - self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - else: - msg = "X2 Handover FAILED" - logging.error(msg) - fullMessage += msg + '</pre>' - html_queue.put(fullMessage) - self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', ALL_PROCESSES_OK) - - def LogCollectBuild(self): - if (self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != ''): - IPAddress = self.eNBIPAddress - UserName = self.eNBUserName - Password = self.eNBPassword - SourceCodePath = self.eNBSourceCodePath - elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''): - IPAddress = self.UEIPAddress - UserName = self.UEUserName - Password = self.UEPassword - SourceCodePath = self.UESourceCodePath - else: - sys.exit('Insufficient Parameter') - self.open(IPAddress, UserName, Password) - self.command('cd ' + SourceCodePath, '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('rm -f build.log.zip', '\$', 5) - self.command('zip build.log.zip build_log_*/*', '\$', 60) - self.close() - - def LogCollecteNB(self): - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('cd ' + self.eNBSourceCodePath, '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 60) - self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 5) - self.close() - - def LogCollectPing(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('rm -f ping.log.zip', '\$', 5) - self.command('zip ping.log.zip ping*.log', '\$', 60) - self.command('rm ping*.log', '\$', 5) - self.close() - - def LogCollectIperf(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('rm -f iperf.log.zip', '\$', 5) - self.command('zip iperf.log.zip iperf*.log', '\$', 60) - self.command('rm iperf*.log', '\$', 5) - self.close() - - def LogCollectHSS(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('rm -f hss.log.zip', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('zip hss.log.zip hss*.log', '\$', 60) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm hss*.log', '\$', 5) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('zip hss.log.zip logs/hss*.* *.pcap', '\$', 60) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f logs/hss*.* *.pcap', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cp /opt/hss_sim0609/hss.log .', '\$', 60) - self.command('zip hss.log.zip hss.log', '\$', 60) - else: - logging.error('This option should not occur!') - self.close() - - def LogCollectMME(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('rm -f mme.log.zip', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('zip mme.log.zip mme*.log', '\$', 60) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm mme*.log', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cp /opt/ltebox/var/log/*Log.0 .', '\$', 5) - self.command('zip mme.log.zip mmeLog.0 s1apcLog.0 s1apsLog.0 s11cLog.0 libLog.0 s1apCodecLog.0', '\$', 60) - else: - logging.error('This option should not occur!') - self.close() - - def LogCollectSPGW(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('rm -f spgw.log.zip', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('zip spgw.log.zip spgw*.log', '\$', 60) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm spgw*.log', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cp /opt/ltebox/var/log/xGwLog.0 .', '\$', 5) - self.command('zip spgw.log.zip xGwLog.0', '\$', 60) - else: - logging.error('This option should not occur!') - self.close() - - def LogCollectOAIUE(self): - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S rm -f ue.log.zip', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S zip ue.log.zip ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 60) - self.command('echo ' + self.UEPassword + ' | sudo -S rm ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 5) - self.close() - - def RetrieveSystemVersion(self, machine): - if self.eNBIPAddress == 'none' or self.UEIPAddress == 'none': - self.OsVersion = 'Ubuntu 16.04.5 LTS' - self.KernelVersion = '4.15.0-45-generic' - self.UhdVersion = '3.13.0.1-0' - self.UsrpBoard = 'B210' - self.CpuNb = '4' - self.CpuModel = 'Intel(R) Core(TM) i5-6200U' - self.CpuMHz = '2399.996 MHz' - return 0 - if machine == 'eNB': - if self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != '': - IPAddress = self.eNBIPAddress - UserName = self.eNBUserName - Password = self.eNBPassword - else: - return -1 - if machine == 'UE': - if self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != '': - IPAddress = self.UEIPAddress - UserName = self.UEUserName - Password = self.UEPassword - else: - return -1 - - self.open(IPAddress, UserName, Password) - self.command('lsb_release -a', '\$', 5) - result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', str(self.ssh.before)) - if result is not None: - self.OsVersion = result.group('os_type') - logging.debug('OS is: ' + self.OsVersion) - self.command('uname -r', '\$', 5) - result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', str(self.ssh.before)) - if result is not None: - self.KernelVersion = result.group('kernel_version') - logging.debug('Kernel Version is: ' + self.KernelVersion) - self.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) - result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', str(self.ssh.before)) - if result is not None: - self.UhdVersion = result.group('uhd_version') - logging.debug('UHD Version is: ' + self.UhdVersion) - self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 15) - result = re.search('product: (?P<usrp_board>[0-9A-Za-z]+)\\\\r\\\\n', str(self.ssh.before)) - if result is not None: - self.UsrpBoard = result.group('usrp_board') - logging.debug('USRP Board is: ' + self.UsrpBoard) - self.command('lscpu', '\$', 5) - result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', str(self.ssh.before)) - if result is not None: - self.CpuNb = result.group('nb_cpus') - logging.debug('nb_cpus: ' + self.CpuNb) - self.CpuModel = result.group('model') - logging.debug('model: ' + self.CpuModel) - self.CpuMHz = result.group('cpu_mhz') + ' MHz' - logging.debug('cpu_mhz: ' + self.CpuMHz) - self.close() - -#----------------------------------------------------------- -# HTML Reporting.... -#----------------------------------------------------------- - def CreateHtmlHeader(self): - if (not self.htmlHeaderCreated): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1m Creating HTML header \u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - self.htmlFile = open('test_results.html', 'w') - self.htmlFile.write('<!DOCTYPE html>\n') - self.htmlFile.write('<html class="no-js" lang="en-US">\n') - self.htmlFile.write('<head>\n') - self.htmlFile.write(' <meta name="viewport" content="width=device-width, initial-scale=1">\n') - self.htmlFile.write(' <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">\n') - self.htmlFile.write(' <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>\n') - self.htmlFile.write(' <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>\n') - self.htmlFile.write(' <title>Test Results for TEMPLATE_JOB_NAME job build #TEMPLATE_BUILD_ID</title>\n') - self.htmlFile.write('</head>\n') - self.htmlFile.write('<body><div class="container">\n') - self.htmlFile.write(' <br>\n') - self.htmlFile.write(' <table style="border-collapse: collapse; border: none;">\n') - self.htmlFile.write(' <tr style="border-collapse: collapse; border: none;">\n') - self.htmlFile.write(' <td style="border-collapse: collapse; border: none;">\n') - self.htmlFile.write(' <a href="http://www.openairinterface.org/">\n') - self.htmlFile.write(' <img src="http://www.openairinterface.org/wp-content/uploads/2016/03/cropped-oai_final_logo2.png" alt="" border="none" height=50 width=150>\n') - self.htmlFile.write(' </img>\n') - self.htmlFile.write(' </a>\n') - self.htmlFile.write(' </td>\n') - self.htmlFile.write(' <td style="border-collapse: collapse; border: none; vertical-align: center;">\n') - self.htmlFile.write(' <b><font size = "6">Job Summary -- Job: TEMPLATE_JOB_NAME -- Build-ID: TEMPLATE_BUILD_ID</font></b>\n') - self.htmlFile.write(' </td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - self.htmlFile.write(' <br>\n') - self.htmlFile.write(' <div class="alert alert-info"><strong> <span class="glyphicon glyphicon-dashboard"></span> TEMPLATE_STAGE_NAME</strong></div>\n') - self.htmlFile.write(' <table border = "1">\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-time"></span> Build Start Time (UTC) </td>\n') - self.htmlFile.write(' <td>TEMPLATE_BUILD_TIME</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-cloud-upload"></span> GIT Repository </td>\n') - self.htmlFile.write(' <td><a href="' + self.ranRepository + '">' + self.ranRepository + '</a></td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-wrench"></span> Job Trigger </td>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td>Merge-Request</td>\n') - else: - self.htmlFile.write(' <td>Push to Branch</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-out"></span> Source Branch </td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tree-deciduous"></span> Branch</td>\n') - self.htmlFile.write(' <td>' + self.ranBranch + '</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Source Commit ID </td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Commit ID </td>\n') - self.htmlFile.write(' <td>' + self.ranCommitID + '</td>\n') - self.htmlFile.write(' </tr>\n') - if self.ranAllowMerge != '': - commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.ranCommitID, shell=True, universal_newlines=True) - commit_message = commit_message.strip() - self.htmlFile.write(' <tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Source Commit Message </td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Commit Message </td>\n') - self.htmlFile.write(' <td>' + commit_message + '</td>\n') - self.htmlFile.write(' </tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-in"></span> Target Branch </td>\n') - if (self.ranTargetBranch == ''): - self.htmlFile.write(' <td>develop</td>\n') - else: - self.htmlFile.write(' <td>' + self.ranTargetBranch + '</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - - if (self.ADBIPAddress != 'none'): - terminate_ue_flag = True - self.GetAllUEDevices(terminate_ue_flag) - self.GetAllCatMDevices(terminate_ue_flag) - self.htmlUEConnected = len(self.UEDevices) - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server</h2>\n') - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n') - else: - self.UEDevices.append('OAI-UE') - self.htmlUEConnected = len(self.UEDevices) - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' OAI UE(s) is(are) connected to CI bench</h2>\n') - self.htmlFile.write(' <br>\n') - self.htmlFile.write(' <ul class="nav nav-pills">\n') - count = 0 - while (count < self.nbTestXMLfiles): - pillMsg = ' <li><a data-toggle="pill" href="#' - pillMsg += self.htmlTabRefs[count] - pillMsg += '">' - pillMsg += '__STATE_' + self.htmlTabNames[count] + '__' - pillMsg += self.htmlTabNames[count] - pillMsg += ' <span class="glyphicon glyphicon-' - pillMsg += self.htmlTabIcons[count] - pillMsg += '"></span></a></li>\n' - self.htmlFile.write(pillMsg) - count += 1 - self.htmlFile.write(' </ul>\n') - self.htmlFile.write(' <div class="tab-content">\n') - self.htmlFile.close() - - def CreateHtmlTabHeader(self): - if (not self.htmlHeaderCreated): - if (not os.path.isfile('test_results.html')): - self.CreateHtmlHeader() - self.htmlFile = open('test_results.html', 'a') - if (self.nbTestXMLfiles == 1): - self.htmlFile.write(' <div id="' + self.htmlTabRefs[0] + '" class="tab-pane fade">\n') - self.htmlFile.write(' <h3>Test Summary for <span class="glyphicon glyphicon-file"></span> ' + self.testXMLfiles[0] + '</h3>\n') - else: - self.htmlFile.write(' <div id="build-tab" class="tab-pane fade">\n') - self.htmlFile.write(' <table class="table" border = "1">\n') - self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n') - self.htmlFile.write(' <th>Relative Time (ms)</th>\n') - self.htmlFile.write(' <th>Test Id</th>\n') - self.htmlFile.write(' <th>Test Desc</th>\n') - self.htmlFile.write(' <th>Test Options</th>\n') - self.htmlFile.write(' <th>Test Status</th>\n') - if (self.htmlUEConnected == -1): - terminate_ue_flag = True - if (self.ADBIPAddress != 'none'): - self.GetAllUEDevices(terminate_ue_flag) - self.GetAllCatMDevices(terminate_ue_flag) - else: - self.UEDevices.append('OAI-UE') - self.htmlUEConnected = len(self.UEDevices) - - i = 0 - while (i < self.htmlUEConnected): - self.htmlFile.write(' <th>UE' + str(i) + ' Status</th>\n') - i += 1 - self.htmlFile.write(' </tr>\n') - self.htmlHeaderCreated = True - - def CreateHtmlTabFooter(self, passStatus): - if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th bgcolor = "#33CCFF" colspan=3>Final Tab Status</th>\n') - if passStatus: - self.htmlFile.write(' <th bgcolor = "green" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">PASS <span class="glyphicon glyphicon-ok"></span> </font></th>\n') - else: - self.htmlFile.write(' <th bgcolor = "red" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - self.htmlFile.write(' </div>\n') - self.htmlFile.close() - time.sleep(1) - if passStatus: - cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__//' test_results.html" - subprocess.run(cmd, shell=True) - else: - cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<span class=\"glyphicon glyphicon-remove\"><\/span>/' test_results.html" - subprocess.run(cmd, shell=True) - self.htmlFooterCreated = False - - def CreateHtmlFooter(self, passStatus): - if (os.path.isfile('test_results.html')): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1m Creating HTML footer \u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - - self.htmlFile = open('test_results.html', 'a') - self.htmlFile.write('</div>\n') - self.htmlFile.write(' <p></p>\n') - self.htmlFile.write(' <table class="table table-condensed">\n') - - machines = [ 'eNB', 'UE' ] - for machine in machines: - res = self.RetrieveSystemVersion(machine) - if res == -1: - continue - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th colspan=8>' + str(machine) + ' Server Characteristics</th>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td>OS Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.OsVersion + '</span></td>\n') - self.htmlFile.write(' <td>Kernel Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.KernelVersion + '</span></td>\n') - self.htmlFile.write(' <td>UHD Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.UhdVersion + '</span></td>\n') - self.htmlFile.write(' <td>USRP Board</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.UsrpBoard + '</span></td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td>Nb CPUs</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.CpuNb + '</span></td>\n') - self.htmlFile.write(' <td>CPU Model Name</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.CpuModel + '</span></td>\n') - self.htmlFile.write(' <td>CPU Frequency</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.CpuMHz + '</span></td>\n') - self.htmlFile.write(' <td></td>\n') - self.htmlFile.write(' <td></td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th colspan=5 bgcolor = "#33CCFF">Final Status</th>\n') - if passStatus: - self.htmlFile.write(' <th colspan=3 bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n') - else: - self.htmlFile.write(' <th colspan=3 bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - self.htmlFile.write(' <p></p>\n') - self.htmlFile.write(' <div class="well well-lg">End of Test Report -- Copyright <span class="glyphicon glyphicon-copyright-mark"></span> 2018 <a href="http://www.openairinterface.org/">OpenAirInterface</a>. All Rights Reserved.</div>\n') - self.htmlFile.write('</div></body>\n') - self.htmlFile.write('</html>\n') - self.htmlFile.close() - - def CreateHtmlTestRow(self, options, status, processesStatus, machine='eNB'): - if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - currentTime = int(round(time.time() * 1000)) - self.startTime - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + format(currentTime / 1000, '.1f') + '</td>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n') - self.htmlFile.write(' <td>' + self.desc + '</td>\n') - self.htmlFile.write(' <td>' + str(options) + '</td>\n') - if (str(status) == 'OK'): - self.htmlFile.write(' <td bgcolor = "lightgreen" >' + str(status) + '</td>\n') - elif (str(status) == 'KO'): - if (processesStatus == 0): - self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') - elif (processesStatus == ENB_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process not found</td>\n') - elif (processesStatus == OAI_UE_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - OAI UE process not found</td>\n') - elif (processesStatus == ENB_PROCESS_SEG_FAULT): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Segmentation Fault</td>\n') - elif (processesStatus == ENB_PROCESS_ASSERTION) or (processesStatus == OAI_UE_PROCESS_ASSERTION): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Assertion</td>\n') - elif (processesStatus == ENB_PROCESS_REALTIME_ISSUE): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process faced Real Time issue(s)</td>\n') - elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE) or (processesStatus == OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE): - self.htmlFile.write(' <td bgcolor = "orange" >OK?</td>\n') - elif (processesStatus == ENB_PROCESS_SLAVE_RRU_NOT_SYNCED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' Slave RRU could not synch</td>\n') - elif (processesStatus == OAI_UE_PROCESS_COULD_NOT_SYNC): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - UE could not sync</td>\n') - elif (processesStatus == HSS_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - HSS process not found</td>\n') - elif (processesStatus == MME_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - MME process not found</td>\n') - elif (processesStatus == SPGW_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - SPGW process not found</td>\n') - elif (processesStatus == UE_IP_ADDRESS_ISSUE): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - Could not retrieve UE IP address</td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') - else: - self.htmlFile.write(' <td bgcolor = "orange" >' + str(status) + '</td>\n') - if (len(str(self.htmleNBFailureMsg)) > 2): - cellBgColor = 'white' - result = re.search('ended with|faced real time issues', self.htmleNBFailureMsg) - if result is not None: - cellBgColor = 'red' - else: - result = re.search('showed|Reestablishment|Could not copy eNB logfile', self.htmleNBFailureMsg) - if result is not None: - cellBgColor = 'orange' - self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmleNBFailureMsg + '</pre></td>\n') - self.htmleNBFailureMsg = '' - elif (len(str(self.htmlUEFailureMsg)) > 2): - cellBgColor = 'white' - result = re.search('ended with|faced real time issues', self.htmlUEFailureMsg) - if result is not None: - cellBgColor = 'red' - else: - result = re.search('showed|Could not copy UE logfile|oaitun_ue1 interface is either NOT mounted or NOT configured', self.htmlUEFailureMsg) - if result is not None: - cellBgColor = 'orange' - self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmlUEFailureMsg + '</pre></td>\n') - self.htmlUEFailureMsg = '' - else: - i = 0 - while (i < self.htmlUEConnected): - self.htmlFile.write(' <td>-</td>\n') - i += 1 - self.htmlFile.write(' </tr>\n') - - def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue): - if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - currentTime = int(round(time.time() * 1000)) - self.startTime - addOrangeBK = False - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + format(currentTime / 1000, '.1f') + '</td>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n') - self.htmlFile.write(' <td>' + self.desc + '</td>\n') - self.htmlFile.write(' <td>' + str(options) + '</td>\n') - if (str(status) == 'OK'): - self.htmlFile.write(' <td bgcolor = "lightgreen" >' + str(status) + '</td>\n') - elif (str(status) == 'KO'): - self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') - else: - addOrangeBK = True - self.htmlFile.write(' <td bgcolor = "orange" >' + str(status) + '</td>\n') - i = 0 - while (i < self.htmlUEConnected): - if (i < ue_status): - if (not ue_queue.empty()): - if (addOrangeBK): - self.htmlFile.write(' <td bgcolor = "orange" >' + str(ue_queue.get()).replace('white', 'orange') + '</td>\n') - else: - self.htmlFile.write(' <td>' + str(ue_queue.get()) + '</td>\n') - else: - self.htmlFile.write(' <td>-</td>\n') - else: - self.htmlFile.write(' <td>-</td>\n') - i += 1 - self.htmlFile.write(' </tr>\n') - -#----------------------------------------------------------- -# ShowTestID() -#----------------------------------------------------------- - def ShowTestID(self): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1mTest ID:' + self.testCase_id + '\u001B[0m') - logging.debug('\u001B[1m' + self.desc + '\u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - -#----------------------------------------------------------- -# Usage() -#----------------------------------------------------------- -def Usage(): - print('----------------------------------------------------------------------------------------------------------------------') - print('main.py Ver:' + Version) - print('----------------------------------------------------------------------------------------------------------------------') - print('Usage: python main.py [options]') - print(' --help Show this help.') - print(' --mode=[Mode]') - print(' TesteNB') - print(' InitiateHtml, FinalizeHtml') - print(' TerminateeNB, TerminateUE, TerminateHSS, TerminateMME, TerminateSPGW') - print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf') - print('---------------------------------------------------------------------------------------------------- Git Options --') - print(' --ranRepository=[OAI RAN Repository URL]') - print(' --ranBranch=[OAI RAN Repository Branch]') - print(' --ranCommitID=[OAI RAN Repository Commit SHA-1]') - print(' --ranAllowMerge=[Allow Merge Request (with target branch) (true or false)]') - print(' --ranTargetBranch=[Target Branch in case of a Merge Request]') - print('--------------------------------------------------------------------------------------------- eNB Server Options --') - print(' --eNBIPAddress=[eNB\'s IP Address]') - print(' --eNBUserName=[eNB\'s Login User Name]') - print(' --eNBPassword=[eNB\'s Login Password]') - print(' --eNBSourceCodePath=[eNB\'s Source Code Path]') - print('------------------------------------------------------------------------------------------ OAI UE Server Options --') - print(' --UEIPAddress=[UE\'s IP Address]') - print(' --UEUserName=[UE\'s Login User Name]') - print(' --UEPassword=[UE\'s Login Password]') - print(' --UESourceCodePath=[UE\'s Source Code Path]') - print('--------------------------------------------------------------------------------------------- EPC Server Options --') - print(' --EPCIPAddress=[EPC\'s IP Address]') - print(' --EPCUserName=[EPC\'s Login User Name]') - print(' --EPCPassword=[EPC\'s Login Password]') - print(' --EPCSourceCodePath=[EPC\'s Source Code Path]') - print(' --EPCType=[EPC\'s Type: OAI or ltebox or OAI-Rel14-CUPS]') - print('--------------------------------------------------------------------------------------------- ABD Server Options --') - print(' --ADBIPAddress=[ADB\'s IP Address]') - print(' --ADBUserName=[ADB\'s Login User Name]') - print(' --ADBPassword=[ADB\'s Login Password]') - print('----------------------------------------------------------------------------------------------------------------------') - print(' --XMLTestFile=[XML Test File to be run]') - print('----------------------------------------------------------------------------------------------------------------------') - -def CheckClassValidity(action,id): - if action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover': - logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) - return False - return True - -def GetParametersFromXML(action): - if action == 'Build_eNB': - SSH.Build_eNB_args = test.findtext('Build_eNB_args') - SSH.eNB_instance = test.findtext('eNB_instance') - if (SSH.eNB_instance is None): - SSH.eNB_instance = '0' - SSH.eNB_serverId = test.findtext('eNB_serverId') - if (SSH.eNB_serverId is None): - SSH.eNB_serverId = '0' - xmlBgBuildField = test.findtext('backgroundBuild') - if (xmlBgBuildField is None): - SSH.backgroundBuild = False - else: - if re.match('true', xmlBgBuildField, re.IGNORECASE): - SSH.backgroundBuild = True - else: - SSH.backgroundBuild = False - - if action == 'WaitEndBuild_eNB': - SSH.Build_eNB_args = test.findtext('Build_eNB_args') - SSH.eNB_instance = test.findtext('eNB_instance') - if (SSH.eNB_instance is None): - SSH.eNB_instance = '0' - SSH.eNB_serverId = test.findtext('eNB_serverId') - if (SSH.eNB_serverId is None): - SSH.eNB_serverId = '0' - - if action == 'Initialize_eNB': - SSH.Initialize_eNB_args = test.findtext('Initialize_eNB_args') - SSH.eNB_instance = test.findtext('eNB_instance') - if (SSH.eNB_instance is None): - SSH.eNB_instance = '0' - SSH.eNB_serverId = test.findtext('eNB_serverId') - if (SSH.eNB_serverId is None): - SSH.eNB_serverId = '0' - - if action == 'Terminate_eNB': - SSH.eNB_instance = test.findtext('eNB_instance') - if (SSH.eNB_instance is None): - SSH.eNB_instance = '0' - SSH.eNB_serverId = test.findtext('eNB_serverId') - if (SSH.eNB_serverId is None): - SSH.eNB_serverId = '0' - - if action == 'Attach_UE': - nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach') - if (nbMaxUEtoAttach is None): - SSH.nbMaxUEtoAttach = -1 - else: - SSH.nbMaxUEtoAttach = int(nbMaxUEtoAttach) - - if action == 'CheckStatusUE': - expectedNBUE = test.findtext('expectedNbOfConnectedUEs') - if (expectedNBUE is None): - SSH.expectedNbOfConnectedUEs = -1 - else: - SSH.expectedNbOfConnectedUEs = int(expectedNBUE) - - if action == 'Build_OAI_UE': - SSH.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args') - - if action == 'Initialize_OAI_UE': - SSH.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args') - SSH.UE_instance = test.findtext('UE_instance') - if (SSH.UE_instance is None): - SSH.UE_instance = '0' - - if action == 'Terminate_OAI_UE': - SSH.eNB_instance = test.findtext('UE_instance') - if (SSH.UE_instance is None): - SSH.UE_instance = '0' - - if action == 'Ping' or action == 'Ping_CatM_module': - SSH.ping_args = test.findtext('ping_args') - SSH.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold') - - if action == 'Iperf': - SSH.iperf_args = test.findtext('iperf_args') - SSH.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold') - SSH.iperf_profile = test.findtext('iperf_profile') - if (SSH.iperf_profile is None): - SSH.iperf_profile = 'balanced' - else: - if SSH.iperf_profile != 'balanced' and SSH.iperf_profile != 'unbalanced' and SSH.iperf_profile != 'single-ue': - logging.debug('ERROR: test-case has wrong profile ' + SSH.iperf_profile) - SSH.iperf_profile = 'balanced' - - if action == 'IdleSleep': - string_field = test.findtext('idle_sleep_time_in_sec') - if (string_field is None): - SSH.idle_sleep_time = 5 - else: - SSH.idle_sleep_time = int(string_field) - - if action == 'Perform_X2_Handover': - string_field = test.findtext('x2_ho_options') - if (string_field is None): - SSH.x2_ho_options = 'network' - else: - if string_field != 'network': - logging.error('ERROR: test-case has wrong option ' + string_field) - SSH.x2_ho_options = 'network' - else: - SSH.x2_ho_options = string_field - - -#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 - -def receive_signal(signum, frame): - sys.exit(1) - -#----------------------------------------------------------- -# Parameter Check -#----------------------------------------------------------- -mode = '' -SSH = SSHConnection() - -argvs = sys.argv -argc = len(argvs) -cwd = os.getcwd() - -while len(argvs) > 1: - myArgv = argvs.pop(1) # 0th is this file's name - if re.match('^\-\-help$', myArgv, re.IGNORECASE): - Usage() - sys.exit(0) - elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE) - mode = matchReg.group(1) - elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE) - SSH.ranRepository = matchReg.group(1) - elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE) - doMerge = matchReg.group(1) - if ((doMerge == 'true') or (doMerge == 'True')): - SSH.ranAllowMerge = True - elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE) - SSH.ranBranch = matchReg.group(1) - elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE) - SSH.ranCommitID = matchReg.group(1) - elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE) - SSH.ranTargetBranch = matchReg.group(1) - elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.eNBIPAddress = matchReg.group(1) - elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB1IPAddress = matchReg.group(1) - elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB2IPAddress = matchReg.group(1) - elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) - SSH.eNBUserName = matchReg.group(1) - elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB1UserName = matchReg.group(1) - elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB2UserName = matchReg.group(1) - elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE) - SSH.eNBPassword = matchReg.group(1) - elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB1Password = matchReg.group(1) - elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB2Password = matchReg.group(1) - elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - SSH.eNBSourceCodePath = matchReg.group(1) - elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB1SourceCodePath = matchReg.group(1) - elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB2SourceCodePath = matchReg.group(1) - elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.EPCIPAddress = matchReg.group(1) - elif re.match('^\-\-EPCBranch=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCBranch=(.+)$', myArgv, re.IGNORECASE) - SSH.EPCBranch = matchReg.group(1) - elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE) - SSH.EPCUserName = matchReg.group(1) - elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE) - SSH.EPCPassword = matchReg.group(1) - elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - SSH.EPCSourceCodePath = matchReg.group(1) - elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE) - if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE): - SSH.EPCType = matchReg.group(1) - else: - sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS)') - elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.ADBIPAddress = matchReg.group(1) - elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE) - SSH.ADBUserName = matchReg.group(1) - elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE) - if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE): - if re.match('distributed', matchReg.group(1), re.IGNORECASE): - SSH.ADBCentralized = False - else: - SSH.ADBCentralized = True - else: - sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)') - elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE) - SSH.ADBPassword = matchReg.group(1) - elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) - SSH.testXMLfiles.append(matchReg.group(1)) - SSH.nbTestXMLfiles += 1 - elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.UEIPAddress = matchReg.group(1) - elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE) - SSH.UEUserName = matchReg.group(1) - elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE) - SSH.UEPassword = matchReg.group(1) - elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE) - SSH.UESourceCodePath = matchReg.group(1) -# reading repeatCounts from command line - elif re.match('^\-\-repeatCounts=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-repeatCounts=(.+)$', myArgv, re.IGNORECASE) - SSH.repeatCounts = int(matchReg.group(1)) - elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE) - finalStatus = matchReg.group(1) - if ((finalStatus == 'true') or (finalStatus == 'True')): - SSH.finalStatus = True - else: - Usage() - sys.exit('Invalid Parameter: ' + myArgv) - -if re.match('^TerminateeNB$', mode, re.IGNORECASE): - if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.eNB_serverId = '0' - SSH.eNB_instance = '0' - SSH.eNBSourceCodePath = '/tmp/' - SSH.TerminateeNB() -elif re.match('^TerminateUE$', mode, re.IGNORECASE): - if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''): - Usage() - sys.exit('Insufficient Parameter') - signal.signal(signal.SIGUSR1, receive_signal) - SSH.TerminateUE() -elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE): - if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '': - Usage() - sys.exit('Insufficient Parameter') - signal.signal(signal.SIGUSR1, receive_signal) - SSH.TerminateOAIUE() -elif re.match('^TerminateHSS$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.TerminateHSS() -elif re.match('^TerminateMME$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.TerminateMME() -elif re.match('^TerminateSPGW$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.TerminateSPGW() -elif re.match('^LogCollectBuild$', mode, re.IGNORECASE): - if (SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '') and (SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == ''): - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectBuild() -elif re.match('^LogCollecteNB$', mode, re.IGNORECASE): - if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollecteNB() -elif re.match('^LogCollectHSS$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectHSS() -elif re.match('^LogCollectMME$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectMME() -elif re.match('^LogCollectSPGW$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectSPGW() -elif re.match('^LogCollectPing$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectPing() -elif re.match('^LogCollectIperf$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectIperf() -elif re.match('^LogCollectOAIUE$', mode, re.IGNORECASE): - if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectOAIUE() -elif re.match('^InitiateHtml$', mode, re.IGNORECASE): - if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''): - Usage() - sys.exit('Insufficient Parameter') - count = 0 - foundCount = 0 - while (count < SSH.nbTestXMLfiles): - xml_test_file = cwd + "/" + SSH.testXMLfiles[count] - xml_test_file = sys.path[0] + "/" + SSH.testXMLfiles[count] - if (os.path.isfile(xml_test_file)): - xmlTree = ET.parse(xml_test_file) - xmlRoot = xmlTree.getroot() - SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) - SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count))) - SSH.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign')) - foundCount += 1 - count += 1 - if foundCount != SSH.nbTestXMLfiles: - SSH.nbTestXMLfiles = foundCount - SSH.CreateHtmlHeader() -elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): - SSH.CreateHtmlFooter(SSH.finalStatus) -elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE): - if re.match('^TesteNB$', mode, re.IGNORECASE): - if SSH.eNBIPAddress == '' or SSH.ranRepository == '' or SSH.ranBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - - if (SSH.EPCIPAddress != '') and (SSH.EPCIPAddress != 'none'): - SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/tcp_iperf_stats.awk", "/tmp") - SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/active_net_interfaces.awk", "/tmp") - else: - if SSH.UEIPAddress == '' or SSH.ranRepository == '' or SSH.ranBranch == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '': - Usage() - sys.exit('UE: Insufficient Parameter') - - #read test_case_list.xml file - # if no parameters for XML file, use default value - if (SSH.nbTestXMLfiles != 1): - xml_test_file = cwd + "/test_case_list.xml" - else: - xml_test_file = cwd + "/" + SSH.testXMLfiles[0] - - xmlTree = ET.parse(xml_test_file) - xmlRoot = xmlTree.getroot() - - exclusion_tests=xmlRoot.findtext('TestCaseExclusionList',default='') - requested_tests=xmlRoot.findtext('TestCaseRequestedList',default='') - if (SSH.nbTestXMLfiles == 1): - SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) - SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0')) -# repeatCounts not read from the xml file -# repeatCount = xmlRoot.findtext('repeatCount',default='1') -# SSH.repeatCounts.append(int(repeatCount)) - all_tests=xmlRoot.findall('testCase') - - exclusion_tests=exclusion_tests.split() - requested_tests=requested_tests.split() - - #check that exclusion tests are well formatted - #(6 digits or less than 6 digits followed by +) - for test in exclusion_tests: - if (not re.match('^[0-9]{6}$', test) and - not re.match('^[0-9]{1,5}\+$', test)): - logging.debug('ERROR: exclusion test is invalidly formatted: ' + test) - sys.exit(1) - else: - logging.debug(test) - - #check that requested tests are well formatted - #(6 digits or less than 6 digits followed by +) - #be verbose - for test in requested_tests: - if (re.match('^[0-9]{6}$', test) or - re.match('^[0-9]{1,5}\+$', test)): - logging.debug('INFO: test group/case requested: ' + test) - else: - logging.debug('ERROR: requested test is invalidly formatted: ' + test) - sys.exit(1) - if (SSH.EPCIPAddress != '') and (SSH.EPCIPAddress != 'none'): - SSH.CheckFlexranCtrlInstallation() - - #get the list of tests to be done - todo_tests=[] - for test in requested_tests: - if (test_in_list(test, exclusion_tests)): - logging.debug('INFO: test will be skipped: ' + test) - else: - #logging.debug('INFO: test will be run: ' + test) - todo_tests.append(test) - - signal.signal(signal.SIGUSR1, receive_signal) - - SSH.CreateHtmlTabHeader() - - cnt = 0 - SSH.prematureExit = True - SSH.startTime = int(round(time.time() * 1000)) -# repeatCounts becomes an integer (was SSH.repeatCounts[0] --> becomes SSH.repeatCounts) - while cnt < SSH.repeatCounts and SSH.prematureExit: - SSH.prematureExit = False - for test_case_id in todo_tests: - if SSH.prematureExit: - break - for test in all_tests: - if SSH.prematureExit: - break - id = test.get('id') - if test_case_id != id: - continue - SSH.testCase_id = id - SSH.desc = test.findtext('desc') - action = test.findtext('class') - if (CheckClassValidity(action, id) == False): - continue - SSH.ShowTestID() - GetParametersFromXML(action) - if action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Ping' or action == 'Iperf' or action == 'Reboot_UE' or action == 'DataDisable_UE' or action == 'DataEnable_UE' or action == 'CheckStatusUE': - if (SSH.ADBIPAddress != 'none'): - terminate_ue_flag = False - SSH.GetAllUEDevices(terminate_ue_flag) - if action == 'Build_eNB': - SSH.BuildeNB() - elif action == 'WaitEndBuild_eNB': - SSH.WaitBuildeNBisFinished() - elif action == 'Initialize_eNB': - SSH.InitializeeNB() - elif action == 'Terminate_eNB': - SSH.TerminateeNB() - elif action == 'Initialize_UE': - SSH.InitializeUE() - elif action == 'Terminate_UE': - SSH.TerminateUE() - elif action == 'Attach_UE': - SSH.AttachUE() - elif action == 'Detach_UE': - SSH.DetachUE() - elif action == 'DataDisable_UE': - SSH.DataDisableUE() - elif action == 'DataEnable_UE': - SSH.DataEnableUE() - elif action == 'CheckStatusUE': - SSH.CheckStatusUE() - elif action == 'Build_OAI_UE': - SSH.BuildOAIUE() - elif action == 'Initialize_OAI_UE': - SSH.InitializeOAIUE() - elif action == 'Terminate_OAI_UE': - SSH.TerminateOAIUE() - elif action == 'Initialize_CatM_module': - SSH.InitializeCatM() - elif action == 'Terminate_CatM_module': - SSH.TerminateCatM() - elif action == 'Attach_CatM_module': - SSH.AttachCatM() - elif action == 'Detach_CatM_module': - SSH.TerminateCatM() - elif action == 'Ping_CatM_module': - SSH.PingCatM() - elif action == 'Ping': - SSH.Ping() - elif action == 'Iperf': - SSH.Iperf() - elif action == 'Reboot_UE': - SSH.RebootUE() - elif action == 'Initialize_HSS': - SSH.InitializeHSS() - elif action == 'Terminate_HSS': - SSH.TerminateHSS() - elif action == 'Initialize_MME': - SSH.InitializeMME() - elif action == 'Terminate_MME': - SSH.TerminateMME() - elif action == 'Initialize_SPGW': - SSH.InitializeSPGW() - elif action == 'Terminate_SPGW': - SSH.TerminateSPGW() - elif action == 'Initialize_FlexranCtrl': - SSH.InitializeFlexranCtrl() - elif action == 'Terminate_FlexranCtrl': - SSH.TerminateFlexranCtrl() - elif action == 'IdleSleep': - SSH.IdleSleep() - elif action == 'Perform_X2_Handover': - SSH.Perform_X2_Handover() - else: - sys.exit('Invalid action') - cnt += 1 -# repeatCounts becomes an integer (was SSH.repeatCounts[0] --> becomes SSH.repeatCounts) - if cnt == SSH.repeatCounts and SSH.prematureExit: - logging.debug('Testsuite failed ' + str(cnt) + ' time(s)') - SSH.CreateHtmlTabFooter(False) - sys.exit('Failed Scenario') - else: - logging.info('Testsuite passed after ' + str(cnt) + ' time(s)') - SSH.CreateHtmlTabFooter(True) -else: - Usage() - sys.exit('Invalid mode') -sys.exit(0) diff --git a/ci-scripts/main-index-to-class.py b/ci-scripts/main-index-to-class.py deleted file mode 100644 index 68b9558740f3a4c97505b3e35357747f95be850e..0000000000000000000000000000000000000000 --- a/ci-scripts/main-index-to-class.py +++ /dev/null @@ -1,4921 +0,0 @@ -# /* -# * 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 -# */ -#--------------------------------------------------------------------- -# Python for CI of OAI-eNB + COTS-UE -# -# Required Python Version -# Python 3.x -# -# Required Python Package -# pexpect -#--------------------------------------------------------------------- - -#----------------------------------------------------------- -# Version -#----------------------------------------------------------- -Version = '0.1' - -#----------------------------------------------------------- -# Constants -#----------------------------------------------------------- -ALL_PROCESSES_OK = 0 -ENB_PROCESS_FAILED = -1 -ENB_PROCESS_OK = +1 -ENB_PROCESS_SEG_FAULT = -11 -ENB_PROCESS_ASSERTION = -12 -ENB_PROCESS_REALTIME_ISSUE = -13 -ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14 -ENB_PROCESS_SLAVE_RRU_NOT_SYNCED = -15 -HSS_PROCESS_FAILED = -2 -HSS_PROCESS_OK = +2 -MME_PROCESS_FAILED = -3 -MME_PROCESS_OK = +3 -SPGW_PROCESS_FAILED = -4 -SPGW_PROCESS_OK = +4 -UE_IP_ADDRESS_ISSUE = -5 -OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE = -20 -OAI_UE_PROCESS_COULD_NOT_SYNC = -21 -OAI_UE_PROCESS_ASSERTION = -22 -OAI_UE_PROCESS_FAILED = -23 -OAI_UE_PROCESS_NO_TUNNEL_INTERFACE = -24 -OAI_UE_PROCESS_OK = +6 - -UE_STATUS_DETACHED = 0 -UE_STATUS_DETACHING = 1 -UE_STATUS_ATTACHING = 2 -UE_STATUS_ATTACHED = 3 - -X2_HO_REQ_STATE__IDLE = 0 -X2_HO_REQ_STATE__TARGET_RECEIVES_REQ = 1 -X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE = 2 -X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ = 3 -X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK = 10 - -#----------------------------------------------------------- -# Import -#----------------------------------------------------------- -import sys # arg -import re # reg -import pexpect # pexpect -import time # sleep -import os -import subprocess -import xml.etree.ElementTree as ET -import logging -import datetime -import signal -from multiprocessing import Process, Lock, SimpleQueue -logging.basicConfig( - level=logging.DEBUG, - format="[%(asctime)s] %(name)s:%(levelname)s: %(message)s" -) - -#----------------------------------------------------------- -# Class Declaration -#----------------------------------------------------------- -class SSHConnection(): - def __init__(self): - self.FailReportCnt = 0 # FailReportCnt was an index inside the SSH instantiation (called "cnt"), now it becomes an object - self.prematureExit = False - self.ranRepository = '' - self.ranBranch = '' - self.ranAllowMerge = False - self.ranCommitID = '' - self.ranTargetBranch = '' - self.eNBIPAddress = '' - self.eNBUserName = '' - self.eNBPassword = '' - self.eNBSourceCodePath = '' - self.EPCIPAddress = '' - self.EPCUserName = '' - self.EPCPassword = '' - self.eNB1IPAddress = '' - self.eNB1UserName = '' - self.eNB1Password = '' - self.eNB1SourceCodePath = '' - self.eNB2IPAddress = '' - self.eNB2UserName = '' - self.eNB2Password = '' - self.eNB2SourceCodePath = '' - self.EPCSourceCodePath = '' - self.EPCType = '' - self.EPC_PcapFileName = '' - self.ADBIPAddress = '' - self.ADBUserName = '' - self.ADBPassword = '' - self.ADBCentralized = True - self.testCase_id = '' - self.testXMLfiles = [] - self.nbTestXMLfiles = 0 - self.desc = '' - self.Build_eNB_args = '' - self.backgroundBuild = False - self.backgroundBuildTestId = ['', '', ''] - self.Initialize_eNB_args = '' - self.eNB_instance = '' - self.eNB_serverId = '' - self.eNBLogFiles = ['', '', ''] - self.eNBOptions = ['', '', ''] - self.ping_args = '' - self.ping_packetloss_threshold = '' - self.iperf_args = '' - self.iperf_packetloss_threshold = '' - self.iperf_profile = '' - self.nbMaxUEtoAttach = -1 - self.UEDevices = [] - self.UEDevicesStatus = [] - self.UEDevicesRemoteServer = [] - self.UEDevicesRemoteUser = [] - self.UEDevicesOffCmd = [] - self.UEDevicesOnCmd = [] - self.UEDevicesRebootCmd = [] - self.CatMDevices = [] - self.UEIPAddresses = [] - self.htmlFile = '' - self.htmlHeaderCreated = False - self.htmlFooterCreated = False - self.htmlUEConnected = -1 - self.htmleNBFailureMsg = '' - self.htmlUEFailureMsg = '' - self.picocom_closure = False - self.idle_sleep_time = 0 - self.x2_ho_options = 'network' - self.x2NbENBs = 0 - self.x2ENBBsIds = [] - self.x2ENBConnectedUEs = [] - self.htmlTabRefs = [] - self.htmlTabNames = [] - self.htmlTabIcons = [] - self.repeatCounts = [] - self.finalStatus = False - self.OsVersion = '' - self.KernelVersion = '' - self.UhdVersion = '' - self.UsrpBoard = '' - self.CpuNb = '' - self.CpuModel = '' - self.CpuMHz = '' - self.UEIPAddress = '' - self.UEUserName = '' - self.UEPassword = '' - self.UE_instance = '' - self.UESourceCodePath = '' - self.UELogFile = '' - self.Build_OAI_UE_args = '' - self.Initialize_OAI_UE_args = '' - self.flexranCtrlInstalled = False - self.flexranCtrlStarted = False - self.expectedNbOfConnectedUEs = 0 - self.startTime = 0 - - def open(self, ipaddress, username, password): - count = 0 - connect_status = False - while count < 4: - self.ssh = pexpect.spawn('ssh', [username + '@' + ipaddress], timeout = 5) - self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - self.ssh.sendline('yes') - self.ssh.expect('password:') - self.ssh.sendline(password) - self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - count = 10 - connect_status = True - else: - logging.debug('self.sshresponse = ' + str(self.sshresponse)) - elif self.sshresponse == 1: - self.ssh.sendline(password) - self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - count = 10 - connect_status = True - else: - logging.debug('self.sshresponse = ' + str(self.sshresponse)) - elif self.sshresponse == 2: - # Checking if we are really on the remote client defined by its IP address - self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', '\$', 5) - result = re.search(str(ipaddress), str(self.ssh.before)) - if result is None: - self.close() - else: - count = 10 - connect_status = True - else: - # debug output - logging.debug(str(self.ssh.before)) - logging.debug('self.sshresponse = ' + str(self.sshresponse)) - # adding a tempo when failure - if not connect_status: - time.sleep(1) - count += 1 - if connect_status: - pass - else: - sys.exit('SSH Connection Failed') - - def command(self, commandline, expectedline, timeout): - logging.debug(commandline) - self.ssh.timeout = timeout - self.ssh.sendline(commandline) - self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - return 0 - elif self.sshresponse == 1: - logging.debug('\u001B[1;37;41m Unexpected EOF \u001B[0m') - logging.debug('Expected Line : ' + expectedline) - sys.exit(self.sshresponse) - elif self.sshresponse == 2: - logging.debug('\u001B[1;37;41m Unexpected TIMEOUT \u001B[0m') - logging.debug('Expected Line : ' + expectedline) - result = re.search('ping |iperf |picocom', str(commandline)) - if result is None: - logging.debug(str(self.ssh.before)) - sys.exit(self.sshresponse) - else: - return -1 - else: - logging.debug('\u001B[1;37;41m Unexpected Others \u001B[0m') - logging.debug('Expected Line : ' + expectedline) - sys.exit(self.sshresponse) - - def close(self): - self.ssh.timeout = 5 - self.ssh.sendline('exit') - self.sshresponse = self.ssh.expect([pexpect.EOF, pexpect.TIMEOUT]) - if self.sshresponse == 0: - pass - elif self.sshresponse == 1: - if not self.picocom_closure: - logging.debug('\u001B[1;37;41m Unexpected TIMEOUT during closing\u001B[0m') - else: - logging.debug('\u001B[1;37;41m Unexpected Others during closing\u001B[0m') - - def copyin(self, ipaddress, username, password, source, destination): - count = 0 - copy_status = False - logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination) - while count < 10: - scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 100) - scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0: - scp_spawn.sendline('yes') - scp_spawn.expect('password:') - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0: - count = 10 - copy_status = True - else: - logging.debug('1 - scp_response = ' + str(scp_response)) - elif scp_response == 1: - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0 or scp_response == 3: - count = 10 - copy_status = True - else: - logging.debug('2 - scp_response = ' + str(scp_response)) - elif scp_response == 2: - count = 10 - copy_status = True - else: - logging.debug('3 - scp_response = ' + str(scp_response)) - # adding a tempo when failure - if not copy_status: - time.sleep(1) - count += 1 - if copy_status: - return 0 - else: - return -1 - - def copyout(self, ipaddress, username, password, source, destination): - count = 0 - copy_status = False - logging.debug('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination) - while count < 4: - scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 100) - scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0: - scp_spawn.sendline('yes') - scp_spawn.expect('password:') - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0: - count = 10 - copy_status = True - else: - logging.debug('1 - scp_response = ' + str(scp_response)) - elif scp_response == 1: - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0 or scp_response == 3: - count = 10 - copy_status = True - else: - logging.debug('2 - scp_response = ' + str(scp_response)) - elif scp_response == 2: - count = 10 - copy_status = True - else: - logging.debug('3 - scp_response = ' + str(scp_response)) - # adding a tempo when failure - if not copy_status: - time.sleep(1) - count += 1 - if copy_status: - pass - else: - sys.exit('SCP failed') - - def BuildeNB(self): - if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '': - Usage() - sys.exit('Insufficient Parameter') - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(lIpAddr, lUserName, lPassWord) - self.command('mkdir -p ' + lSourcePath, '\$', 5) - self.command('cd ' + lSourcePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) - # Raphael: here add a check if git clone or git fetch went smoothly - self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) - self.command('git config user.name "OAI Jenkins"', '\$', 5) - # Checking the BUILD INFO file - if not self.backgroundBuild: - self.command('ls *.txt', '\$', 5) - result = re.search('LAST_BUILD_INFO', str(self.ssh.before)) - if result is not None: - mismatch = False - self.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) - result = re.search(self.ranCommitID, str(self.ssh.before)) - if result is None: - mismatch = True - self.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): - result = re.search('YES', str(self.ssh.before)) - if result is None: - mismatch = True - self.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - result = re.search('develop', str(self.ssh.before)) - else: - result = re.search(self.ranTargetBranch, str(self.ssh.before)) - if result is None: - mismatch = True - else: - result = re.search('NO', str(self.ssh.before)) - if result is None: - mismatch = True - if not mismatch: - self.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - return - - self.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30) - # if the commit ID is provided use it to point to it - if self.ranCommitID != '': - self.command('git checkout -f ' + self.ranCommitID, '\$', 5) - # if the branch is not develop, then it is a merge request and we need to do - # the potential merge. Note that merge conflicts should already been checked earlier - if (self.ranAllowMerge): - if self.ranTargetBranch == '': - if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): - self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) - else: - logging.debug('Merging with the target branch: ' + self.ranTargetBranch) - self.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('mkdir -p log', '\$', 5) - self.command('chmod 777 log', '\$', 5) - # no need to remove in log (git clean did the trick) - if self.backgroundBuild: - self.command('echo "./build_oai ' + self.Build_eNB_args + '" > ./my-lte-softmodem-build.sh', '\$', 5) - self.command('chmod 775 ./my-lte-softmodem-build.sh', '\$', 5) - self.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=build_enb_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ./my-lte-softmodem-build.sh', '\$', 5) - self.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - self.backgroundBuildTestId[int(self.eNB_instance)] = self.testCase_id - return - self.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee compile_oai_enb.log', 'Bypassing the Tests|build have failed', 1500) - self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.testCase_id) - - def WaitBuildeNBisFinished(self): - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(lIpAddr, lUserName, lPassWord) - count = 40 - buildOAIprocess = True - while (count > 0) and buildOAIprocess: - self.command('ps aux | grep --color=never build_ | grep -v grep', '\$', 3) - result = re.search('build_oai', str(self.ssh.before)) - if result is None: - buildOAIprocess = False - else: - count -= 1 - time.sleep(30) - self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.backgroundBuildTestId[int(self.eNB_instance)]) - - def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId): - self.command('cd ' + lSourcePath + '/cmake_targets', '\$', 3) - self.command('ls lte_build_oai/build', '\$', 3) - self.command('ls lte_build_oai/build', '\$', 3) - buildStatus = True - result = re.search('lte-softmodem', str(self.ssh.before)) - if result is None: - buildStatus = False - else: - # Generating a BUILD INFO file - self.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) - self.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): - self.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - self.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - self.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - self.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) - self.command('mkdir -p build_log_' + testcaseId, '\$', 5) - self.command('mv log/* ' + 'build_log_' + testcaseId, '\$', 5) - self.command('mv compile_oai_enb.log ' + 'build_log_' + testcaseId, '\$', 5) - if self.eNB_serverId != '0': - self.command('cd cmake_targets', '\$', 5) - self.command('if [ -e tmp_build' + testcaseId + '.zip ]; then rm -f tmp_build' + testcaseId + '.zip; fi', '\$', 5) - self.command('zip -r -qq tmp_build' + testcaseId + '.zip build_log_' + testcaseId, '\$', 5) - self.close() - if (os.path.isfile('./tmp_build' + testcaseId + '.zip')): - os.remove('./tmp_build' + testcaseId + '.zip') - self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/tmp_build' + testcaseId + '.zip', '.') - if (os.path.isfile('./tmp_build' + testcaseId + '.zip')): - self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './tmp_build' + testcaseId + '.zip', self.eNBSourceCodePath + '/cmake_targets/.') - os.remove('./tmp_build' + testcaseId + '.zip') - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5) - self.command('unzip -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5) - self.command('rm -f tmp_build' + testcaseId + '.zip', '\$', 5) - self.close() - else: - self.close() - - if buildStatus: - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - else: - logging.error('\u001B[1m Building OAI eNB Failed\u001B[0m') - self.CreateHtmlTestRow(self.Build_eNB_args, 'KO', ALL_PROCESSES_OK) - self.CreateHtmlTabFooter(False) - sys.exit(1) - - def BuildOAIUE(self): - if self.UEIPAddress == '' or self.ranRepository == '' or self.ranBranch == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) - self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) - # here add a check if git clone or git fetch went smoothly - self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) - self.command('git config user.name "OAI Jenkins"', '\$', 5) - self.command('ls *.txt', '\$', 5) - result = re.search('LAST_BUILD_INFO', str(self.ssh.before)) - if result is not None: - mismatch = False - self.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) - result = re.search(self.ranCommitID, str(self.ssh.before)) - if result is None: - mismatch = True - self.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): - result = re.search('YES', str(self.ssh.before)) - if result is None: - mismatch = True - self.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - result = re.search('develop', str(self.ssh.before)) - else: - result = re.search(self.ranTargetBranch, str(self.ssh.before)) - if result is None: - mismatch = True - else: - result = re.search('NO', str(self.ssh.before)) - if result is None: - mismatch = True - if not mismatch: - self.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - return - - self.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30) - # if the commit ID is provided use it to point to it - if self.ranCommitID != '': - self.command('git checkout -f ' + self.ranCommitID, '\$', 5) - # if the branch is not develop, then it is a merge request and we need to do - # the potential merge. Note that merge conflicts should already been checked earlier - if (self.ranAllowMerge): - if self.ranTargetBranch == '': - if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): - self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) - else: - logging.debug('Merging with the target branch: ' + self.ranTargetBranch) - self.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('mkdir -p log', '\$', 5) - self.command('chmod 777 log', '\$', 5) - # no need to remove in log (git clean did the trick) - self.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee compile_oai_ue.log', 'Bypassing the Tests|build have failed', 600) - self.command('ls lte_build_oai/build', '\$', 3) - self.command('ls lte_build_oai/build', '\$', 3) - buildStatus = True - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is None: - buildStatus = False - self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) - self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) - self.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5) - if buildStatus: - # Generating a BUILD INFO file - self.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) - self.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): - self.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - self.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - self.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - self.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) - self.close() - self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') - else: - self.close() - logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') - self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE') - self.CreateHtmlTabFooter(False) - sys.exit(1) - - def InitializeHSS(self): - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - logging.debug('Using the OAI EPC Release 14 Cassandra-based HSS') - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - logging.debug('\u001B[1m Launching tshark on all interfaces \u001B[0m') - EPC_PcapFileName = 'epc_' + self.testCase_id + '.pcap' - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f ' + EPC_PcapFileName, '\$', 5) - self.command('echo $USER; nohup sudo tshark -f "tcp port not 22 and port not 53" -i any -w ' + self.EPCSourceCodePath + '/scripts/' + EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S mkdir -p logs', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss_' + self.testCase_id + '.log logs/hss*.*', '\$', 5) - self.command('echo "oai_hss -j /usr/local/etc/oai/hss_rel14.json" > ./my-hss.sh', '\$', 5) - self.command('chmod 755 ./my-hss.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=hss_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/hss_' + self.testCase_id + '.log ./my-hss.sh', '\$', 5) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - logging.debug('Using the OAI EPC HSS') - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_hss 2>&1 | stdbuf -o0 awk \'{ print strftime("[%Y/%m/%d %H:%M:%S] ",systime()) $0 }\' | stdbuf -o0 tee -a hss_' + self.testCase_id + '.log &', 'Core state: 2 -> 3', 35) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - logging.debug('Using the ltebox simulated HSS') - self.command('if [ -d ' + self.EPCSourceCodePath + '/scripts ]; then echo ' + self.eNBPassword + ' | sudo -S rm -Rf ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) - self.command('mkdir -p ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('cd /opt/hss_sim0609', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss.log daemon.log', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S echo "Starting sudo session" && sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real ', '\$', 5) - else: - logging.error('This option should not occur!') - self.close() - self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) - - def InitializeMME(self): - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - logging.debug('Using the OAI EPC Release 14 MME') - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f mme_' + self.testCase_id + '.log', '\$', 5) - self.command('echo "./run_mme --config-file /usr/local/etc/oai/mme.conf --set-virt-if" > ./my-mme.sh', '\$', 5) - self.command('chmod 755 ./my-mme.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=mme_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/mme_' + self.testCase_id + '.log ./my-mme.sh', '\$', 5) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('stdbuf -o0 hostname', '\$', 5) - result = re.search('hostname\\\\r\\\\n(?P<host_name>[a-zA-Z0-9\-\_]+)\\\\r\\\\n', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m Hostname Not Found! \u001B[0m') - sys.exit(1) - host_name = result.group('host_name') - self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_mme 2>&1 | stdbuf -o0 tee -a mme_' + self.testCase_id + '.log &', 'MME app initialization complete', 100) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cd /opt/ltebox/tools', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_mme', '\$', 5) - else: - logging.error('This option should not occur!') - self.close() - self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) - - def InitializeSPGW(self): - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - logging.debug('Using the OAI EPC Release 14 SPGW-CUPS') - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f spgwc_' + self.testCase_id + '.log spgwu_' + self.testCase_id + '.log', '\$', 5) - self.command('echo "spgwc -c /usr/local/etc/oai/spgw_c.conf" > ./my-spgwc.sh', '\$', 5) - self.command('chmod 755 ./my-spgwc.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=spgwc_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwc_' + self.testCase_id + '.log ./my-spgwc.sh', '\$', 5) - time.sleep(5) - self.command('echo "spgwu -c /usr/local/etc/oai/spgw_u.conf" > ./my-spgwu.sh', '\$', 5) - self.command('chmod 755 ./my-spgwu.sh', '\$', 5) - self.command('sudo daemon --unsafe --name=spgwu_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwu_' + self.testCase_id + '.log ./my-spgwu.sh', '\$', 5) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_spgw 2>&1 | stdbuf -o0 tee -a spgw_' + self.testCase_id + '.log &', 'Initializing SPGW-APP task interface: DONE', 30) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cd /opt/ltebox/tools', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_xGw', '\$', 5) - else: - logging.error('This option should not occur!') - self.close() - self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK) - - def CheckFlexranCtrlInstallation(self): - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '': - return - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('ls -ls /opt/flexran_rtc/*/rt_controller', '\$', 5) - result = re.search('/opt/flexran_rtc/build/rt_controller', str(self.ssh.before)) - if result is not None: - self.flexranCtrlInstalled = True - logging.debug('Flexran Controller is installed') - self.close() - - def InitializeFlexranCtrl(self): - if self.flexranCtrlInstalled == False: - return - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd /opt/flexran_rtc', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f log/*.log', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5) - self.command('ps -aux | grep --color=never rt_controller', '\$', 5) - result = re.search('rt_controller -c ', str(self.ssh.before)) - if result is not None: - logging.debug('\u001B[1m Initialize FlexRan Controller Completed\u001B[0m') - self.flexranCtrlStarted = True - self.close() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def InitializeeNB(self): - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = False - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - # If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep -v "lo|tun"', '\$', 5) - result = re.search('interfaceToUse=(?P<eth_interface>[a-zA-Z0-9\-\_]+)done', str(self.ssh.before)) - if result is not None: - eth_interface = result.group('eth_interface') - logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m') - self.EPC_PcapFileName = 'enb_' + self.testCase_id + '_s1log.pcap' - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f /tmp/' + self.EPC_PcapFileName, '\$', 5) - self.command('echo $USER; nohup sudo tshark -f "host ' + lIpAddr +'" -i ' + eth_interface + ' -w /tmp/' + self.EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) - self.close() - self.open(lIpAddr, lUserName, lPassWord) - self.command('cd ' + lSourcePath, '\$', 5) - # Initialize_eNB_args usually start with -O and followed by the location in repository - full_config_file = self.Initialize_eNB_args.replace('-O ','') - extra_options = '' - extIdx = full_config_file.find('.conf') - if (extIdx > 0): - extra_options = full_config_file[extIdx + 5:] - # if tracer options is on, compiling and running T Tracer - result = re.search('T_stdout', str(extra_options)) - if result is not None: - logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m') - self.command('cd common/utils/T/tracer', '\$', 5) - self.command('make', '\$', 10) - self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', lUserName, 5) - self.command('cd ' + lSourcePath, '\$', 5) - full_config_file = full_config_file[:extIdx + 5] - config_path, config_file = os.path.split(full_config_file) - else: - sys.exit('Insufficient Parameter') - ci_full_config_file = config_path + '/ci-' + config_file - rruCheck = False - result = re.search('^rru|^rcc|^du.band', str(config_file)) - if result is not None: - rruCheck = True - # do not reset board twice in IF4.5 case - result = re.search('^rru|^enb|^du.band', str(config_file)) - if result is not None: - self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 10) - result = re.search('type: b200', str(self.ssh.before)) - if result is not None: - logging.debug('Found a B2xx device --> resetting it') - self.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) - # Reloading FGPA bin firmware - self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 15) - # Make a copy and adapt to EPC / eNB IP addresses - self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) - self.command('sed -i -e \'s/CI_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/CI_RRU1_IP_ADDR/' + self.eNB1IPAddress + '/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/CI_RRU2_IP_ADDR/' + self.eNB2IPAddress + '/\' ' + ci_full_config_file, '\$', 2); - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "yes";/\' ' + ci_full_config_file, '\$', 2); - else: - self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "no";/\' ' + ci_full_config_file, '\$', 2); - # Launch eNB with the modified config file - self.command('source oaienv', '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) - self.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log' - if extra_options != '': - self.eNBOptions[int(self.eNB_instance)] = extra_options - time.sleep(6) - doLoop = True - loopCounter = 10 - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - # In case of T tracer recording, we may need to kill it - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - self.command('killall --signal SIGKILL record', '\$', 5) - self.close() - doLoop = False - logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m') - self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', ALL_PROCESSES_OK) - # In case of T tracer recording, we need to kill tshark on EPC side - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) - if self.EPC_PcapFileName != '': - time.sleep(0.5) - self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5) - self.close() - time.sleep(1) - if self.EPC_PcapFileName != '': - copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.') - if (copyin_res == 0): - self.copyout(lIpAddr, lUserName, lPassWord, self.EPC_PcapFileName, lSourcePath + '/cmake_targets/.') - self.prematureExit = True - return - else: - self.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting"', '\$', 4) - if rruCheck: - result = re.search('wait RUs', str(self.ssh.before)) - else: - result = re.search('got sync|Starting F1AP at CU', str(self.ssh.before)) - if result is None: - time.sleep(6) - else: - doLoop = False - self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK) - logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') - time.sleep(10) - - self.close() - - def InitializeUE_common(self, device_id, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if not self.ADBCentralized: - # Reboot UE - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesRebootCmd[idx], '\$', 60) - # Wait - #time.sleep(60) - # Put in LTE-Mode only - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode 11"\'', '\$', 60) - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode1 11"\'', '\$', 60) - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode2 11"\'', '\$', 60) - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode3 11"\'', '\$', 60) - # enable data service - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - # we need to do radio on/off cycle to make sure of above changes - # airplane mode off // radio on - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - #time.sleep(10) - # airplane mode on // radio off - #self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - - # normal procedure without reboot - # enable data service - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - # airplane mode on // radio off - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - self.close() - return - # enable data service - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) - - # The following commands are deprecated since we no longer work on Android 7+ - # self.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10) - # self.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60) - # a dedicated script has to be installed inside the UE - # airplane mode on means call /data/local/tmp/off - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - #airplane mode off means call /data/local/tmp/on - logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m') - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def InitializeUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.InitializeUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def InitializeOAIUE(self): - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is None: - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - # b2xx_fx3_utils reset procedure - self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 10) - result = re.search('type: b200', str(self.ssh.before)) - if result is not None: - logging.debug('Found a B2xx device --> resetting it') - self.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) - # Reloading FGPA bin firmware - self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 15) - else: - logging.debug('Did not find any B2xx device') - self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('source oaienv', '\$', 5) - self.command('cd cmake_targets/lte_build_oai/build', '\$', 5) - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - # We may have to regenerate the .u* files - if result is None: - self.command('ls /tmp/*.sed', '\$', 5) - result = re.search('adapt_usim_parameters', str(self.ssh.before)) - if result is not None: - self.command('sed -f /tmp/adapt_usim_parameters.sed ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) - else: - self.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5) - # Launch UE with the modified config file - self.command('echo "ulimit -c unlimited && ./lte-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - self.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - self.UELogFile = 'ue_' + self.testCase_id + '.log' - - # We are now looping several times to hope we really sync w/ an eNB - doOutterLoop = True - outterLoopCounter = 5 - gotSyncStatus = True - fullSyncStatus = True - while (doOutterLoop): - self.command('cd ' + self.UESourceCodePath + '/cmake_targets/lte_build_oai/build', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/lte_build_oai/build -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - time.sleep(6) - self.command('cd ../..', '\$', 5) - doLoop = True - loopCounter = 10 - gotSyncStatus = True - # the 'got sync' message is for the UE threads synchronization - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - # Here should never occur - logging.error('"got sync" message never showed!') - gotSyncStatus = False - doLoop = False - continue - self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) - result = re.search('got sync', str(self.ssh.before)) - if result is None: - time.sleep(6) - else: - doLoop = False - logging.debug('Found "got sync" message!') - if gotSyncStatus == False: - # we certainly need to stop the lte-uesoftmodem process if it is still running! - self.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) - time.sleep(3) - # We are now checking if sync w/ eNB DOES NOT OCCUR - # Usually during the cell synchronization stage, the UE returns with No cell synchronization message - doLoop = True - loopCounter = 10 - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - # Here we do have a great chance that the UE did cell-sync w/ eNB - doLoop = False - doOutterLoop = False - fullSyncStatus = True - continue - self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) - result = re.search('No cell synchronization found', str(self.ssh.before)) - if result is None: - time.sleep(6) - else: - doLoop = False - fullSyncStatus = False - logging.debug('Found: "No cell synchronization" message! --> try again') - time.sleep(6) - self.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) - outterLoopCounter = outterLoopCounter - 1 - if (outterLoopCounter == 0): - doOutterLoop = False - - if fullSyncStatus and gotSyncStatus: - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is None: - self.command('ifconfig oaitun_ue1', '\$', 4) - # ifconfig output is different between ubuntu 16 and ubuntu 18 - result = re.search('inet addr:1|inet 1', str(self.ssh.before)) - if result is not None: - logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m') - tunnelInterfaceStatus = True - else: - logging.debug(str(self.ssh.before)) - logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') - tunnelInterfaceStatus = False - else: - tunnelInterfaceStatus = True - - self.close() - if fullSyncStatus and gotSyncStatus and tunnelInterfaceStatus: - self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') - logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m') - if (self.ADBIPAddress != 'none'): - self.UEDevices = [] - self.UEDevices.append('OAI-UE') - self.UEDevicesStatus = [] - self.UEDevicesStatus.append(UE_STATUS_DETACHED) - else: - self.htmlUEFailureMsg = 'oaitun_ue1 interface is either NOT mounted or NOT configured' - self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') - logging.error('\033[91mInitialize OAI UE Failed! \033[0m') - self.AutoTerminateUEandeNB() - - def checkDevTTYisUnlocked(self): - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - count = 0 - while count < 5: - self.command('echo ' + self.ADBPassword + ' | sudo -S lsof | grep ttyUSB0', '\$', 10) - result = re.search('picocom', str(self.ssh.before)) - if result is None: - count = 10 - else: - time.sleep(5) - count = count + 1 - self.close() - - def InitializeCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.picocom_closure = True - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - self.command('AT', 'OK|ERROR', 5) - self.command('AT', 'OK', 5) - # Disabling the Radio - self.command('AT+CFUN=0', 'OK', 5) - logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') - # Checking if auto-attach is enabled - self.command('AT^AUTOATT?', 'OK', 5) - result = re.search('AUTOATT: (?P<state>[0-9\-]+)', str(self.ssh.before)) - if result is not None: - if result.group('state') is not None: - autoAttachState = int(result.group('state')) - if autoAttachState is not None: - if autoAttachState == 0: - self.command('AT^AUTOATT=1', 'OK', 5) - logging.debug('\u001B[1m Auto-Attach enabled\u001B[0m') - else: - logging.debug('\u001B[1;37;41m Could not check Auto-Attach! \u001B[0m') - # Force closure of picocom but device might still be locked - self.close() - self.picocom_closure = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.checkDevTTYisUnlocked() - - def TerminateCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.picocom_closure = True - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - self.command('AT', 'OK|ERROR', 5) - self.command('AT', 'OK', 5) - # Disabling the Radio - self.command('AT+CFUN=0', 'OK', 5) - logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') - self.close() - self.picocom_closure = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.checkDevTTYisUnlocked() - - def AttachCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.picocom_closure = True - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - self.command('AT', 'OK|ERROR', 5) - self.command('AT', 'OK', 5) - # Enabling the Radio - self.command('AT+CFUN=1', 'SIMSTORE,READY', 5) - logging.debug('\u001B[1m Cellular Functionality enabled\u001B[0m') - time.sleep(4) - # We should check if we register - count = 0 - attach_cnt = 0 - attach_status = False - while count < 5: - self.command('AT+CEREG?', 'OK', 5) - result = re.search('CEREG: 2,(?P<state>[0-9\-]+),', str(self.ssh.before)) - if result is not None: - mDataConnectionState = int(result.group('state')) - if mDataConnectionState is not None: - if mDataConnectionState == 1: - count = 10 - attach_status = True - result = re.search('CEREG: 2,1,"(?P<networky>[0-9A-Z]+)","(?P<networkz>[0-9A-Z]+)"', str(self.ssh.before)) - if result is not None: - networky = result.group('networky') - networkz = result.group('networkz') - logging.debug('\u001B[1m CAT-M module attached to eNB (' + str(networky) + '/' + str(networkz) + ')\u001B[0m') - else: - logging.debug('\u001B[1m CAT-M module attached to eNB\u001B[0m') - else: - logging.debug('+CEREG: 2,' + str(mDataConnectionState)) - attach_cnt = attach_cnt + 1 - else: - logging.debug(str(self.ssh.before)) - attach_cnt = attach_cnt + 1 - count = count + 1 - time.sleep(1) - if attach_status: - self.command('AT+CESQ', 'OK', 5) - result = re.search('CESQ: 99,99,255,255,(?P<rsrq>[0-9]+),(?P<rsrp>[0-9]+)', str(self.ssh.before)) - if result is not None: - nRSRQ = int(result.group('rsrq')) - nRSRP = int(result.group('rsrp')) - if (nRSRQ is not None) and (nRSRP is not None): - logging.debug(' RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB') - logging.debug(' RSRP = ' + str(-140+nRSRP) + ' dBm') - self.close() - self.picocom_closure = False - html_queue = SimpleQueue() - self.checkDevTTYisUnlocked() - if attach_status: - html_cell = '<pre style="background-color:white">CAT-M module Attachment Completed in ' + str(attach_cnt+4) + ' seconds' - if (nRSRQ is not None) and (nRSRP is not None): - html_cell += '\n RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB' - html_cell += '\n RSRP = ' + str(-140+nRSRP) + ' dBm</pre>' - else: - html_cell += '</pre>' - html_queue.put(html_cell) - self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) - else: - logging.error('\u001B[1m CAT-M module Attachment Failed\u001B[0m') - html_cell = '<pre style="background-color:white">CAT-M module Attachment Failed</pre>' - html_queue.put(html_cell) - self.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) - self.AutoTerminateUEandeNB() - - def PingCatM(self): - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - try: - statusQueue = SimpleQueue() - lock = Lock() - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE): - logging.debug('Using the OAI EPC HSS: not implemented yet') - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - else: - self.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5) - result = re.search('Allocated ipv4 addr: (?P<ipaddr>[0-9\.]+) from Pool', str(self.ssh.before)) - if result is not None: - moduleIPAddr = result.group('ipaddr') - else: - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - device_id = 'catm' - ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + str(moduleIPAddr) + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with UE (' + str(moduleIPAddr) + ') crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before)) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before)) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - lock.acquire() - logging.debug('\u001B[1;37;44m ping result (' + moduleIPAddr + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - lock.release() - self.close() - html_cell = '<pre style="background-color:white">CAT-M module\nIP Address : ' + moduleIPAddr + '\n' + qMsg + '</pre>' - statusQueue.put(html_cell) - if (packetLossOK): - self.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue) - else: - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue) - self.AutoTerminateUEandeNB() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AttachUE_common(self, device_id, statusQueue, lock, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) - else: - # airplane mode off // radio on - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - time.sleep(2) - max_count = 45 - count = max_count - while count > 0: - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep -m 1 mDataConnectionState', '\$', 15) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep -m 1 mDataConnectionState', '\$', 60) - result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put('mDataConnectionState Not Found!') - lock.release() - break - mDataConnectionState = int(result.group('state')) - if mDataConnectionState == 2: - logging.debug('\u001B[1mUE (' + device_id + ') Attach Completed\u001B[0m') - lock.acquire() - statusQueue.put(max_count - count) - statusQueue.put(device_id) - statusQueue.put('Attach Completed') - lock.release() - break - count = count - 1 - if count == 15 or count == 30: - logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m') - if self.ADBCentralized: - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - time.sleep(0.5) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - time.sleep(0.5) - logging.debug('\u001B[1mWait UE (' + device_id + ') a second until mDataConnectionState=2 (' + str(max_count-count) + ' times)\u001B[0m') - time.sleep(1) - if count == 0: - logging.debug('\u001B[1;37;41m UE (' + device_id + ') Attach Failed \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put('Attach Failed') - lock.release() - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AttachUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - status_queue = SimpleQueue() - lock = Lock() - nb_ue_to_connect = 0 - for device_id in self.UEDevices: - if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach): - self.UEDevicesStatus[nb_ue_to_connect] = UE_STATUS_ATTACHING - p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,)) - p.daemon = True - p.start() - multi_jobs.append(p) - nb_ue_to_connect = nb_ue_to_connect + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - self.CreateHtmlTestRow('N/A', 'KO', ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - return - else: - attach_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - attach_status = False - device_id = status_queue.get() - message = status_queue.get() - if (count < 0): - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>' - else: - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds</pre>' - html_queue.put(html_cell) - if (attach_status): - # cnt from index to object of a class - cnt = 0 - while cnt < len(self.UEDevices): - if self.UEDevicesStatus[cnt] == UE_STATUS_ATTACHING: - self.UEDevicesStatus[cnt] = UE_STATUS_ATTACHED - cnt += 1 - self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - logging.debug('Waiting 5 seconds to fill up record file') - time.sleep(5) - else: - self.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def DetachUE_common(self, device_id, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DetachUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - cnt = 0 - for device_id in self.UEDevices: - self.UEDevicesStatus[cnt] = UE_STATUS_DETACHING - p = Process(target = self.DetachUE_common, args = (device_id,cnt,)) - p.daemon = True - p.start() - multi_jobs.append(p) - cnt += 1 - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - logging.debug('Waiting 5 seconds to fill up record file') - time.sleep(5) - cnt = 0 - while cnt < len(self.UEDevices): - self.UEDevicesStatus[cnt] = UE_STATUS_DETACHED - cnt += 1 - - def RebootUE_common(self, device_id): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - previousmDataConnectionStates = [] - # Save mDataConnectionState - self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') - sys.exit(1) - previousmDataConnectionStates.append(int(result.group('state'))) - # Reboot UE - self.command('stdbuf -o0 adb -s ' + device_id + ' shell reboot', '\$', 10) - time.sleep(60) - previousmDataConnectionState = previousmDataConnectionStates.pop(0) - count = 180 - while count > 0: - count = count - 1 - self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', str(self.ssh.before)) - if result is None: - mDataConnectionState = None - else: - mDataConnectionState = int(result.group('state')) - logging.debug('mDataConnectionState = ' + result.group('state')) - if mDataConnectionState is None or (previousmDataConnectionState == 2 and mDataConnectionState != 2): - logging.debug('\u001B[1mWait UE (' + device_id + ') a second until reboot completion (' + str(180-count) + ' times)\u001B[0m') - time.sleep(1) - else: - logging.debug('\u001B[1mUE (' + device_id + ') Reboot Completed\u001B[0m') - break - if count == 0: - logging.debug('\u001B[1;37;41m UE (' + device_id + ') Reboot Failed \u001B[0m') - sys.exit(1) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def RebootUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - multi_jobs = [] - for device_id in self.UEDevices: - p = Process(target = self.RebootUE_common, args = (device_id,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def DataDisableUE_common(self, device_id, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # disable data service - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data disable"', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data disable"\'', '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Disabled Data Service\u001B[0m') - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DataDisableUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.DataDisableUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def DataEnableUE_common(self, device_id, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # enable data service - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Enabled Data Service\u001B[0m') - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DataEnableUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.DataEnableUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def GetAllUEDevices(self, terminate_ue_flag): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - self.command('adb devices', '\$', 15) - self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",str(self.ssh.before)) - self.close() - else: - if (os.path.isfile('./phones_list.txt')): - os.remove('./phones_list.txt') - self.command('ls /etc/*/phones*.txt', '\$', 5) - result = re.search('/etc/ci/phones_list.txt', str(self.ssh.before)) - self.close() - if (result is not None) and (len(self.UEDevices) == 0): - self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, '/etc/ci/phones_list.txt', '.') - if (os.path.isfile('./phones_list.txt')): - phone_list_file = open('./phones_list.txt', 'r') - for line in phone_list_file.readlines(): - line = line.strip() - result = re.search('^#', line) - if result is not None: - continue - comma_split = line.split(",") - self.UEDevices.append(comma_split[0]) - self.UEDevicesRemoteServer.append(comma_split[1]) - self.UEDevicesRemoteUser.append(comma_split[2]) - self.UEDevicesOffCmd.append(comma_split[3]) - self.UEDevicesOnCmd.append(comma_split[4]) - self.UEDevicesRebootCmd.append(comma_split[5]) - phone_list_file.close() - - if terminate_ue_flag == False: - if len(self.UEDevices) == 0: - logging.debug('\u001B[1;37;41m UE Not Found! \u001B[0m') - sys.exit(1) - if len(self.UEDevicesStatus) == 0: - cnt = 0 - while cnt < len(self.UEDevices): - self.UEDevicesStatus.append(UE_STATUS_DETACHED) - cnt += 1 - - def GetAllCatMDevices(self, terminate_ue_flag): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - self.command('lsusb | egrep "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15) - self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",str(self.ssh.before)) - else: - if (os.path.isfile('./modules_list.txt')): - os.remove('./modules_list.txt') - self.command('ls /etc/*/modules*.txt', '\$', 5) - result = re.search('/etc/ci/modules_list.txt', str(self.ssh.before)) - self.close() - if result is not None: - logging.debug('Found a module list file on ADB server') - if terminate_ue_flag == False: - if len(self.CatMDevices) == 0: - logging.debug('\u001B[1;37;41m CAT-M UE Not Found! \u001B[0m') - sys.exit(1) - self.close() - - def CheckUEStatus_common(self, lock, device_id, statusQueue, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry"', '\$', 15) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\'', '\$', 60) - result = re.search('mServiceState=(?P<serviceState>[0-9]+)', str(self.ssh.before)) - serviceState = 'Service State: UNKNOWN' - if result is not None: - lServiceState = int(result.group('serviceState')) - if lServiceState == 3: - serviceState = 'Service State: RADIO_POWERED_OFF' - if lServiceState == 1: - serviceState = 'Service State: OUT_OF_SERVICE' - if lServiceState == 0: - serviceState = 'Service State: IN_SERVICE' - if lServiceState == 2: - serviceState = 'Service State: EMERGENCY_ONLY' - result = re.search('mDataConnectionState=(?P<dataConnectionState>[0-9]+)', str(self.ssh.before)) - dataConnectionState = 'Data State: UNKNOWN' - if result is not None: - lDataConnectionState = int(result.group('dataConnectionState')) - if lDataConnectionState == 0: - dataConnectionState = 'Data State: DISCONNECTED' - if lDataConnectionState == 1: - dataConnectionState = 'Data State: CONNECTING' - if lDataConnectionState == 2: - dataConnectionState = 'Data State: CONNECTED' - if lDataConnectionState == 3: - dataConnectionState = 'Data State: SUSPENDED' - result = re.search('mDataConnectionReason=(?P<dataConnectionReason>[0-9a-zA-Z_]+)', str(self.ssh.before)) - dataConnectionReason = 'Data Reason: UNKNOWN' - if result is not None: - dataConnectionReason = 'Data Reason: ' + result.group('dataConnectionReason') - lock.acquire() - logging.debug('\u001B[1;37;44m Status Check (' + str(device_id) + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + serviceState + '\u001B[0m') - logging.debug('\u001B[1;34m ' + dataConnectionState + '\u001B[0m') - logging.debug('\u001B[1;34m ' + dataConnectionReason + '\u001B[0m') - statusQueue.put(0) - statusQueue.put(device_id) - qMsg = serviceState + '\n' + dataConnectionState + '\n' + dataConnectionReason - statusQueue.put(qMsg) - lock.release() - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckStatusUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - multi_jobs = [] - lock = Lock() - status_queue = SimpleQueue() - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.CheckUEStatus_common, args = (lock,device_id,status_queue,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd /opt/flexran_rtc', '\$', 5) - self.command('curl http://localhost:9999/stats | jq \'.\' > log/check_status_' + self.testCase_id + '.log 2>&1', '\$', 5) - self.command('cat log/check_status_' + self.testCase_id + '.log | jq \'.eNB_config[0].UE\' | grep -c rnti | sed -e "s#^#Nb Connected UE = #"', '\$', 5) - result = re.search('Nb Connected UE = (?P<nb_ues>[0-9]+)', str(self.ssh.before)) - passStatus = True - if result is not None: - nb_ues = int(result.group('nb_ues')) - htmlOptions = 'Nb Connected UE(s) to eNB = ' + str(nb_ues) - logging.debug('\u001B[1;37;44m ' + htmlOptions + ' \u001B[0m') - if self.expectedNbOfConnectedUEs > -1: - if nb_ues != self.expectedNbOfConnectedUEs: - passStatus = False - else: - htmlOptions = 'N/A' - self.close() - else: - passStatus = True - htmlOptions = 'N/A' - - if (status_queue.empty()): - self.CreateHtmlTestRow(htmlOptions, 'KO', ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - check_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - check_status = False - device_id = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>' - html_queue.put(html_cell) - if check_status and passStatus: - self.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def GetAllUEIPAddresses(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - ue_ip_status = 0 - self.UEIPAddresses = [] - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('ifconfig oaitun_ue1', '\$', 4) - result = re.search('inet addr:(?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|inet (?P<ueipaddress2>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', str(self.ssh.before)) - if result is not None: - if result.group('ueipaddress') is not None: - UE_IPAddress = result.group('ueipaddress') - else: - UE_IPAddress = result.group('ueipaddress2') - logging.debug('\u001B[1mUE (' + self.UEDevices[0] + ') IP Address is ' + UE_IPAddress + '\u001B[0m') - self.UEIPAddresses.append(UE_IPAddress) - else: - logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') - ue_ip_status -= 1 - self.close() - return ue_ip_status - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - idx = 0 - for device_id in self.UEDevices: - if self.UEDevicesStatus[idx] != UE_STATUS_ATTACHED: - idx += 1 - continue - count = 0 - while count < 4: - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "ip addr show | grep rmnet"', '\$', 15) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ip addr show | grep rmnet"\'', '\$', 60) - result = re.search('inet (?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+[0-9a-zA-Z\.\s]+', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') - time.sleep(1) - count += 1 - else: - count = 10 - if count < 9: - ue_ip_status -= 1 - continue - UE_IPAddress = result.group('ueipaddress') - logging.debug('\u001B[1mUE (' + device_id + ') IP Address is ' + UE_IPAddress + '\u001B[0m') - for ueipaddress in self.UEIPAddresses: - if ueipaddress == UE_IPAddress: - logging.debug('\u001B[1mUE (' + device_id + ') IP Address ' + UE_IPAddress + ': has already been allocated to another device !' + '\u001B[0m') - ue_ip_status -= 1 - continue - self.UEIPAddresses.append(UE_IPAddress) - idx += 1 - self.close() - return ue_ip_status - - def ping_iperf_wrong_exit(self, lock, UE_IPAddress, device_id, statusQueue, message): - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(message) - lock.release() - - def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue): - try: - # 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 - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - launchFromEpc = False - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - - if launchFromEpc: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) - ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) - else: - cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' - message = cmd + '\n' - logging.debug(cmd) - ret = subprocess.run(cmd, shell=True) - ping_status = ret.returncode - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'ping_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cat ' + self.EPCSourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before)) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before)) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - lock.acquire() - logging.debug('\u001B[1;37;44m ping result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - if (packetLossOK): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(qMsg) - lock.release() - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def PingNoS1_wrong_exit(self, qMsg): - html_queue = SimpleQueue() - html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>' - html_queue.put(html_cell) - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - - def PingNoS1(self): - check_eNB = True - check_OAI_UE = True - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) - if ping_from_eNB is not None: - if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - else: - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': - Usage() - sys.exit('Insufficient Parameter') - try: - if ping_from_eNB is not None: - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets/', '\$', 5) - else: - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5) - self.command('cd cmake_targets', '\$', 5) - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '.log', '\$', int(ping_time[0])*1.5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with OAI UE crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before)) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before)) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - logging.debug('\u001B[1;37;44m OAI UE ping result \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - self.close() - html_queue = SimpleQueue() - ip_addr = 'TBD' - html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>' - html_queue.put(html_cell) - if packetLossOK: - self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - - # copying on the EPC server for logCollection - if ping_from_eNB is not None: - copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') - else: - copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') - if (copyin_res == 0): - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'ping_' + self.testCase_id + '.log', self.EPCSourceCodePath + '/scripts') - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def Ping(self): - result = re.search('noS1', str(self.Initialize_eNB_args)) - if result is not None: - self.PingNoS1() - return - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - check_OAI_UE = True - else: - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ueIpStatus = self.GetAllUEIPAddresses() - if (ueIpStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - i = 0 - lock = Lock() - status_queue = SimpleQueue() - for UE_IPAddress in self.UEIPAddresses: - device_id = self.UEDevices[i] - p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i = i + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - self.CreateHtmlTestRow(self.ping_args, 'KO', ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - ping_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - ping_status = False - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' - html_queue.put(html_cell) - if (ping_status): - self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def Iperf_ComputeTime(self): - result = re.search('-t (?P<iperf_time>\d+)', str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Iperf time Not Found! \u001B[0m') - sys.exit(1) - return result.group('iperf_time') - - def Iperf_ComputeModifiedBW(self, idx, ue_num): - result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Iperf bandwidth Not Found! \u001B[0m') - sys.exit(1) - iperf_bandwidth = result.group('iperf_bandwidth') - if self.iperf_profile == 'balanced': - iperf_bandwidth_new = float(iperf_bandwidth)/ue_num - if self.iperf_profile == 'single-ue': - iperf_bandwidth_new = float(iperf_bandwidth) - if self.iperf_profile == 'unbalanced': - # residual is 2% of max bw - residualBW = float(iperf_bandwidth) / 50 - if idx == 0: - iperf_bandwidth_new = float(iperf_bandwidth) - ((ue_num - 1) * residualBW) - else: - iperf_bandwidth_new = residualBW - iperf_bandwidth_str = '-b ' + iperf_bandwidth - iperf_bandwidth_str_new = '-b ' + ('%.2f' % iperf_bandwidth_new) - result = re.sub(iperf_bandwidth_str, iperf_bandwidth_str_new, str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Calculate Iperf bandwidth Failed! \u001B[0m') - sys.exit(1) - return result - - def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - self.command('awk -f /tmp/tcp_iperf_stats.awk /tmp/CI-eNB/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('Avg Bitrate : (?P<average>[0-9\.]+ Mbits\/sec) Max Bitrate : (?P<maximum>[0-9\.]+ Mbits\/sec) Min Bitrate : (?P<minimum>[0-9\.]+ Mbits\/sec)', str(self.ssh.before)) - if result is not None: - avgbitrate = result.group('average') - maxbitrate = result.group('maximum') - minbitrate = result.group('minimum') - lock.acquire() - logging.debug('\u001B[1;37;44m TCP iperf result (' + UE_IPAddress + ') \u001B[0m') - msg = 'TCP Stats :\n' - if avgbitrate is not None: - logging.debug('\u001B[1;34m Avg Bitrate : ' + avgbitrate + '\u001B[0m') - msg += 'Avg Bitrate : ' + avgbitrate + '\n' - if maxbitrate is not None: - logging.debug('\u001B[1;34m Max Bitrate : ' + maxbitrate + '\u001B[0m') - msg += 'Max Bitrate : ' + maxbitrate + '\n' - if minbitrate is not None: - logging.debug('\u001B[1;34m Min Bitrate : ' + minbitrate + '\u001B[0m') - msg += 'Min Bitrate : ' + minbitrate + '\n' - statusQueue.put(0) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - return 0 - - def Iperf_analyzeV2Output(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - result = re.search('-u', str(iperf_real_options)) - if result is None: - return self.Iperf_analyzeV2TCPOutput(lock, UE_IPAddress, device_id, statusQueue, iperf_real_options) - - result = re.search('Server Report:', str(self.ssh.before)) - if result is None: - result = re.search('read failed: Connection refused', str(self.ssh.before)) - if result is not None: - logging.debug('\u001B[1;37;41m Could not connect to iperf server! \u001B[0m') - else: - logging.debug('\u001B[1;37;41m Server Report and Connection refused Not Found! \u001B[0m') - return -1 - # Computing the requested bandwidth in float - result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(iperf_real_options)) - if result is not None: - req_bandwidth = result.group('iperf_bandwidth') - req_bw = float(req_bandwidth) - result = re.search('-b [0-9\.]+K', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Kbits/sec' % req_bw - req_bw = req_bw * 1000 - result = re.search('-b [0-9\.]+M', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Mbits/sec' % req_bw - req_bw = req_bw * 1000000 - result = re.search('-b [0-9\.]+G', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Gbits/sec' % req_bw - req_bw = req_bw * 1000000000 - - result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', str(self.ssh.before)) - if result is not None: - bitrate = result.group('bitrate') - packetloss = result.group('packetloss') - jitter = result.group('jitter') - lock.acquire() - logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') - iperfStatus = True - msg = 'Req Bitrate : ' + req_bandwidth + '\n' - logging.debug('\u001B[1;34m Req Bitrate : ' + req_bandwidth + '\u001B[0m') - if bitrate is not None: - msg += 'Bitrate : ' + bitrate + '\n' - logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') - result = re.search('(?P<real_bw>[0-9\.]+) [KMG]bits/sec', str(bitrate)) - if result is not None: - actual_bw = float(str(result.group('real_bw'))) - result = re.search('[0-9\.]+ K', bitrate) - if result is not None: - actual_bw = actual_bw * 1000 - result = re.search('[0-9\.]+ M', bitrate) - if result is not None: - actual_bw = actual_bw * 1000000 - result = re.search('[0-9\.]+ G', bitrate) - if result is not None: - actual_bw = actual_bw * 1000000000 - br_loss = 100 * actual_bw / req_bw - bitperf = '%.2f ' % br_loss - msg += 'Bitrate Perf: ' + bitperf + '%\n' - logging.debug('\u001B[1;34m Bitrate Perf: ' + bitperf + '%\u001B[0m') - if packetloss is not None: - msg += 'Packet Loss : ' + packetloss + '%\n' - logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') - if float(packetloss) > float(self.iperf_packetloss_threshold): - msg += 'Packet Loss too high!\n' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - iperfStatus = False - if jitter is not None: - msg += 'Jitter : ' + jitter + '\n' - logging.debug('\u001B[1;34m Jitter : ' + jitter + '\u001B[0m') - if (iperfStatus): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - return 0 - 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')): - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') - return - # Computing the requested bandwidth in float - result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(iperf_real_options)) - if result is None: - logging.debug('Iperf bandwidth Not Found!') - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not compute Iperf bandwidth!') - return - else: - req_bandwidth = result.group('iperf_bandwidth') - req_bw = float(req_bandwidth) - result = re.search('-b [0-9\.]+K', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Kbits/sec' % req_bw - req_bw = req_bw * 1000 - result = re.search('-b [0-9\.]+M', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Mbits/sec' % req_bw - req_bw = req_bw * 1000000 - result = re.search('-b [0-9\.]+G', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Gbits/sec' % req_bw - req_bw = req_bw * 1000000000 - - server_file = open('iperf_server_' + self.testCase_id + '_' + device_id + '.log', 'r') - br_sum = 0.0 - ji_sum = 0.0 - pl_sum = 0 - ps_sum = 0 - row_idx = 0 - for line in server_file.readlines(): - 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') - packetlost = result.group('lostPack') - packetsent = result.group('sentPack') - br = bitrate.split(' ') - ji = jitter.split(' ') - row_idx = row_idx + 1 - curr_br = float(br[0]) - pl_sum = pl_sum + int(packetlost) - ps_sum = ps_sum + int(packetsent) - if (br[1] == 'Kbits/sec'): - curr_br = curr_br * 1000 - if (br[1] == 'Mbits/sec'): - curr_br = curr_br * 1000 * 1000 - br_sum = curr_br + br_sum - ji_sum = float(ji[0]) + ji_sum - if (row_idx > 0): - br_sum = br_sum / row_idx - ji_sum = ji_sum / row_idx - br_loss = 100 * br_sum / req_bw - if (br_sum > 1000): - br_sum = br_sum / 1000 - if (br_sum > 1000): - br_sum = br_sum / 1000 - bitrate = '%.2f Mbits/sec' % br_sum - else: - bitrate = '%.2f Kbits/sec' % br_sum - else: - bitrate = '%.2f bits/sec' % br_sum - bitperf = '%.2f ' % br_loss - bitperf += '%' - jitter = '%.2f ms' % (ji_sum) - if (ps_sum > 0): - pl = float(100 * pl_sum / ps_sum) - packetloss = '%2.1f ' % (pl) - packetloss += '%' - else: - packetloss = 'unknown' - lock.acquire() - if (br_loss < 90): - statusQueue.put(1) - else: - statusQueue.put(0) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - req_msg = 'Req Bitrate : ' + req_bandwidth - bir_msg = 'Bitrate : ' + bitrate - brl_msg = 'Bitrate Perf: ' + bitperf - jit_msg = 'Jitter : ' + jitter - pal_msg = 'Packet Loss : ' + packetloss - statusQueue.put(req_msg + '\n' + bir_msg + '\n' + brl_msg + '\n' + jit_msg + '\n' + pal_msg + '\n') - logging.debug('\u001B[1;37;45m iperf result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;35m ' + req_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + bir_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + brl_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + jit_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + pal_msg + '\u001B[0m') - lock.release() - else: - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') - - server_file.close() - - - def Iperf_analyzeV3Output(self, lock, UE_IPAddress, device_id, statusQueue): - result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P<packetloss>[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', str(self.ssh.before)) - if result is None: - result = re.search('(?P<error>iperf: error - [a-zA-Z0-9 :]+)', str(self.ssh.before)) - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - if result is not None: - logging.debug('\u001B[1;37;41m ' + result.group('error') + ' \u001B[0m') - statusQueue.put(result.group('error')) - else: - logging.debug('\u001B[1;37;41m Bitrate and/or Packet Loss Not Found! \u001B[0m') - statusQueue.put('Bitrate and/or Packet Loss Not Found!') - lock.release() - - bitrate = result.group('bitrate') - packetloss = result.group('packetloss') - lock.acquire() - logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') - msg = 'Bitrate : ' + bitrate + '\n' - iperfStatus = True - if packetloss is not None: - logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') - msg += 'Packet Loss : ' + packetloss + '%\n' - if float(packetloss) > float(self.iperf_packetloss_threshold): - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - msg += 'Packet Loss too high!\n' - iperfStatus = False - if (iperfStatus): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - - def Iperf_UL_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): - udpIperf = True - result = re.search('-u', str(self.iperf_args)) - if result is None: - udpIperf = False - ipnumbers = UE_IPAddress.split('.') - if (len(ipnumbers) == 4): - ipnumbers[3] = '1' - EPC_Iperf_UE_IPAddress = ipnumbers[0] + '.' + ipnumbers[1] + '.' + ipnumbers[2] + '.' + ipnumbers[3] - - # Launch iperf server on EPC side (true for ltebox and old open-air-cn0 - # But for OAI-Rel14-CUPS, we launch from python executor and we are using its IP address as iperf client address - launchFromEpc = True - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - launchFromEpc = False - cmd = 'hostname -I' - ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') - if ret.stdout is not None: - EPC_Iperf_UE_IPAddress = ret.stdout.strip() - port = 5001 + idx - if launchFromEpc: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if udpIperf: - self.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) - else: - self.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) - self.close() - else: - if self.ueIperfVersion == self.dummyIperfVersion: - prefix = '' - else: - prefix = '' - if self.ueIperfVersion == '2.0.5': - prefix = '/opt/iperf-2.0.5/bin/' - if udpIperf: - cmd = 'nohup ' + prefix + 'iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' - else: - cmd = 'nohup ' + prefix + 'iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' - logging.debug(cmd) - subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') - time.sleep(0.5) - - # Launch iperf client on UE - if (device_id == 'OAI-UE'): - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - else: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - iperf_time = self.Iperf_ComputeTime() - time.sleep(0.5) - - if udpIperf: - modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) - else: - modified_options = str(self.iperf_args) - modified_options = modified_options.replace('-R','') - time.sleep(0.5) - - self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if (device_id == 'OAI-UE'): - iperf_status = self.command('iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + ' -B ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - if self.ADBCentralized: - iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - iperf_status = self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '"\' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - self.command('fromdos -o iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - self.command('cat iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - # TIMEOUT Case - if iperf_status < 0: - self.close() - message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) - self.close() - - # Kill iperf server on EPC side - if launchFromEpc: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('killall --signal SIGKILL iperf', self.EPCUserName, 5) - self.close() - else: - cmd = 'killall --signal SIGKILL iperf' - logging.debug(cmd) - subprocess.run(cmd, shell=True) - time.sleep(1) - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - # in case of failure, retrieve server log - if (clientStatus == -1) or (clientStatus == -2): - if launchFromEpc: - time.sleep(1) - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) - # in case of OAI-UE - if (device_id == 'OAI-UE'): - self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.') - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - - def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): - try: - # Single-UE profile -- iperf only on one UE - if self.iperf_profile == 'single-ue' and idx != 0: - return - useIperf3 = False - udpIperf = True - - self.ueIperfVersion = '2.0.5' - if (device_id != 'OAI-UE'): - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it - self.command('if [ ! -d ' + self.EPCSourceCodePath + '/scripts ]; then mkdir -p ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - # Checking if iperf / iperf3 are installed - if self.ADBCentralized: - self.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ls /data/local/tmp"\'', '\$', 60) - result = re.search('iperf3', str(self.ssh.before)) - if result is None: - result = re.search('iperf', str(self.ssh.before)) - if result is None: - message = 'Neither iperf nor iperf3 installed on UE!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - else: - if self.ADBCentralized: - self.command('adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"', '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"\'', '\$', 60) - result = re.search('iperf version 2.0.5', str(self.ssh.before)) - if result is not None: - self.ueIperfVersion = '2.0.5' - result = re.search('iperf version 2.0.10', str(self.ssh.before)) - if result is not None: - self.ueIperfVersion = '2.0.10' - else: - useIperf3 = True - self.close() - else: - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('iperf --version', '\$', 5) - result = re.search('iperf version 2.0.5', str(self.ssh.before)) - if result is not None: - self.ueIperfVersion = '2.0.5' - result = re.search('iperf version 2.0.10', str(self.ssh.before)) - if result is not None: - self.ueIperfVersion = '2.0.10' - self.close() - # in case of iperf, UL has its own function - if (not useIperf3): - result = re.search('-R', str(self.iperf_args)) - if result is not None: - self.Iperf_UL_common(lock, UE_IPAddress, device_id, idx, ue_num, statusQueue) - return - - # Launch the IPERF server on the UE side for DL - if (device_id == 'OAI-UE'): - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('-u', str(self.iperf_args)) - if result is None: - self.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) - udpIperf = False - else: - self.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) - else: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - if self.ADBCentralized: - if (useIperf3): - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) - else: - self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('-u', str(self.iperf_args)) - if result is None: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) - udpIperf = False - else: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) - else: - self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - self.command('echo $USER; nohup ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" \' 2>&1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 60) - - time.sleep(0.5) - self.close() - - # 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 - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - launchFromEpc = False - if launchFromEpc: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - iperf_time = self.Iperf_ComputeTime() - time.sleep(0.5) - - if udpIperf: - modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) - else: - modified_options = str(self.iperf_args) - time.sleep(0.5) - - if launchFromEpc: - self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - else: - if (os.path.isfile('iperf_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_' + self.testCase_id + '_' + device_id + '.log') - if (useIperf3): - self.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - - clientStatus = 0 - self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue) - else: - if launchFromEpc: - iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - if self.ueIperfVersion == self.dummyIperfVersion: - prefix = '' - else: - prefix = '' - if self.ueIperfVersion == '2.0.5': - prefix = '/opt/iperf-2.0.5/bin/' - cmd = prefix + 'iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log' - message = cmd + '\n' - logging.debug(cmd) - ret = subprocess.run(cmd, shell=True) - iperf_status = ret.returncode - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cat ' + self.EPCSourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if iperf_status < 0: - if launchFromEpc: - self.close() - message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) - self.close() - - # Kill the IPERF server that runs in background - if (device_id == 'OAI-UE'): - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('killall iperf', '\$', 5) - else: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps" | grep --color=never iperf | grep -v grep\'', '\$', 60) - result = re.search('shell +(?P<pid>\d+)', str(self.ssh.before)) - if result is not None: - pid_iperf = result.group('pid') - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) - self.close() - # if the client report is absent, try to analyze the server log file - if (clientStatus == -1): - time.sleep(1) - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - if (device_id == 'OAI-UE'): - self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - else: - self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - self.command('fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) - - # in case of OAI UE: - if (device_id == 'OAI-UE'): - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - if not launchFromEpc: - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - else: - self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def IperfNoS1(self): - if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = True - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - server_on_enb = re.search('-R', str(self.iperf_args)) - if server_on_enb is not None: - iServerIPAddr = self.eNBIPAddress - iServerUser = self.eNBUserName - iServerPasswd = self.eNBPassword - iClientIPAddr = self.UEIPAddress - iClientUser = self.UEUserName - iClientPasswd = self.UEPassword - else: - iServerIPAddr = self.UEIPAddress - iServerUser = self.UEUserName - iServerPasswd = self.UEPassword - iClientIPAddr = self.eNBIPAddress - iClientUser = self.eNBUserName - iClientPasswd = self.eNBPassword - # Starting the iperf server - self.open(iServerIPAddr, iServerUser, iServerPasswd) - # args SHALL be "-c client -u any" - # -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1 - # -B 10.0.1.1 -u -s -i 1 -fm - server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args)) - server_options = server_options.replace('-c','-B') - self.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5) - self.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5) - time.sleep(0.5) - self.close() - - # Starting the iperf client - modified_options = self.Iperf_ComputeModifiedBW(0, 1) - modified_options = modified_options.replace('-R','') - iperf_time = self.Iperf_ComputeTime() - self.open(iClientIPAddr, iClientUser, iClientPasswd) - self.command('rm -f /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', 5) - iperf_status = self.command('stdbuf -o0 iperf ' + modified_options + ' 2>&1 | stdbuf -o0 tee /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', int(iperf_time)*5.0) - status_queue = SimpleQueue() - lock = Lock() - if iperf_status < 0: - message = 'iperf on OAI UE crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - clientStatus = -2 - else: - clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) - self.close() - - # Stopping the iperf server - self.open(iServerIPAddr, iServerUser, iServerPasswd) - self.command('killall --signal SIGKILL iperf', '\$', 5) - time.sleep(0.5) - self.close() - if (clientStatus == -1): - if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '.log') - self.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) - - # copying on the EPC server for logCollection - copyin_res = self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') - if (copyin_res == 0): - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') - copyin_res = self.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log') - if (copyin_res == 0): - self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') - iperf_noperf = False - if status_queue.empty(): - iperf_status = False - else: - iperf_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - iperf_status = False - if (count > 0): - iperf_noperf = True - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' - html_queue.put(html_cell) - if (iperf_noperf and iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) - elif (iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def Iperf(self): - result = re.search('noS1', str(self.Initialize_eNB_args)) - if result is not None: - self.IperfNoS1() - return - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - check_eNB = True - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - check_OAI_UE = True - else: - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ueIpStatus = self.GetAllUEIPAddresses() - if (ueIpStatus < 0): - self.CreateHtmlTestRow(self.iperf_args, 'KO', UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB() - return - - self.dummyIperfVersion = '2.0.10' - #cmd = 'iperf --version' - #logging.debug(cmd + '\n') - #iperfStdout = subprocess.check_output(cmd, shell=True, universal_newlines=True) - #result = re.search('iperf version 2.0.5', str(iperfStdout.strip())) - #if result is not None: - # dummyIperfVersion = '2.0.5' - #result = re.search('iperf version 2.0.10', str(iperfStdout.strip())) - #if result is not None: - # dummyIperfVersion = '2.0.10' - - multi_jobs = [] - i = 0 - ue_num = len(self.UEIPAddresses) - lock = Lock() - status_queue = SimpleQueue() - for UE_IPAddress in self.UEIPAddresses: - device_id = self.UEDevices[i] - p = Process(target = SSH.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i = i + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - self.CreateHtmlTestRow(self.iperf_args, 'KO', ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - iperf_status = True - iperf_noperf = False - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - iperf_status = False - if (count > 0): - iperf_noperf = True - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' - html_queue.put(html_cell) - if (iperf_noperf and iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) - elif (iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def CheckProcessExist(self, check_eNB, check_OAI_UE): - multi_jobs = [] - status_queue = SimpleQueue() - # in noS1 config, no need to check status from EPC - result = re.search('noS1', str(self.Initialize_eNB_args)) - if result is None: - p = Process(target = SSH.CheckHSSProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = SSH.CheckMMEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = SSH.CheckSPGWProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - else: - if (check_eNB == False) and (check_OAI_UE == False): - return 0 - if check_eNB: - p = Process(target = SSH.CheckeNBProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - if check_OAI_UE: - p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - return -15 - else: - result = 0 - while (not status_queue.empty()): - status = status_queue.get() - if (status < 0): - result = status - if result == ENB_PROCESS_FAILED: - fileCheck = re.search('enb_', str(self.eNBLogFiles[0])) - if fileCheck is not None: - self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFiles[0], '.') - logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFiles[0]) - if logStatus < 0: - result = logStatus - self.eNBLogFiles[0] = '' - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.TerminateFlexranCtrl() - return result - - def CheckOAIUEProcessExist(self, initialize_OAI_UE_flag): - multi_jobs = [] - status_queue = SimpleQueue() - if initialize_OAI_UE_flag == False: - p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - return -15 - else: - result = 0 - while (not status_queue.empty()): - status = status_queue.get() - if (status < 0): - result = status - if result == OAI_UE_PROCESS_FAILED: - fileCheck = re.search('ue_', str(self.UELogFile)) - if fileCheck is not None: - self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') - logStatus = self.AnalyzeLogFile_UE(self.UELogFile) - if logStatus < 0: - result = logStatus - return result - - def CheckOAIUEProcess(self, status_queue): - try: - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m') - status_queue.put(OAI_UE_PROCESS_FAILED) - else: - status_queue.put(OAI_UE_PROCESS_OK) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckeNBProcess(self, status_queue): - try: - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-softmodem', str(self.ssh.before)) - if result is None: - logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m') - status_queue.put(ENB_PROCESS_FAILED) - else: - status_queue.put(ENB_PROCESS_OK) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckHSSProcess(self, status_queue): - try: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('stdbuf -o0 ps -aux | grep --color=never hss | grep -v grep', '\$', 5) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - result = re.search('oai_hss -j', str(self.ssh.before)) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - result = re.search('hss_sim s6as diam_hss', str(self.ssh.before)) - else: - logging.error('This should not happen!') - if result is None: - logging.debug('\u001B[1;37;41m HSS Process Not Found! \u001B[0m') - status_queue.put(HSS_PROCESS_FAILED) - else: - status_queue.put(HSS_PROCESS_OK) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckMMEProcess(self, status_queue): - try: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('stdbuf -o0 ps -aux | grep --color=never mme | grep -v grep', '\$', 5) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - result = re.search('mme -c', str(self.ssh.before)) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - result = re.search('mme', str(self.ssh.before)) - else: - logging.error('This should not happen!') - if result is None: - logging.debug('\u001B[1;37;41m MME Process Not Found! \u001B[0m') - status_queue.put(MME_PROCESS_FAILED) - else: - status_queue.put(MME_PROCESS_OK) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckSPGWProcess(self, status_queue): - try: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5) - result = re.search('spgwu -c ', str(self.ssh.before)) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5) - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('stdbuf -o0 ps -aux | grep --color=never xGw | grep -v grep', '\$', 5) - result = re.search('xGw', str(self.ssh.before)) - else: - logging.error('This should not happen!') - if result is None: - logging.debug('\u001B[1;37;41m SPGW Process Not Found! \u001B[0m') - status_queue.put(SPGW_PROCESS_FAILED) - else: - status_queue.put(SPGW_PROCESS_OK) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AnalyzeLogFile_eNB(self, eNBlogFile): - if (not os.path.isfile('./' + eNBlogFile)): - return -1 - enb_log_file = open('./' + eNBlogFile, 'r') - exitSignalReceived = False - foundAssertion = False - msgAssertion = '' - msgLine = 0 - foundSegFault = False - foundRealTimeIssue = False - rrcSetupComplete = 0 - rrcReleaseRequest = 0 - rrcReconfigRequest = 0 - rrcReconfigComplete = 0 - rrcReestablishRequest = 0 - rrcReestablishComplete = 0 - rrcReestablishReject = 0 - rlcDiscardBuffer = 0 - rachCanceledProcedure = 0 - uciStatMsgCount = 0 - pdcpFailure = 0 - ulschFailure = 0 - cdrxActivationMessageCount = 0 - dropNotEnoughRBs = 0 - self.htmleNBFailureMsg = '' - isRRU = False - isSlave = False - slaveReceivesFrameResyncCmd = False - X2HO_state = X2_HO_REQ_STATE__IDLE - X2HO_inNbProcedures = 0 - X2HO_outNbProcedures = 0 - for line in enb_log_file.readlines(): - if X2HO_state == X2_HO_REQ_STATE__IDLE: - result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__TARGET_RECEIVES_REQ - result = re.search('source eNB receives the X2 HO ACK X2AP_HANDOVER_REQ_ACK', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK - if X2HO_state == X2_HO_REQ_STATE__TARGET_RECEIVES_REQ: - result = re.search('Received LTE_RRCConnectionReconfigurationComplete from UE', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE - if X2HO_state == X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE: - result = re.search('issue rrc_eNB_send_PATH_SWITCH_REQ', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ - if X2HO_state == X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ: - result = re.search('received path switch ack S1AP_PATH_SWITCH_REQ_ACK', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__IDLE - X2HO_inNbProcedures += 1 - if X2HO_state == X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK: - result = re.search('source eNB receives the X2 UE CONTEXT RELEASE X2AP_UE_CONTEXT_RELEASE', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__IDLE - X2HO_outNbProcedures += 1 - - if self.eNBOptions[int(self.eNB_instance)] != '': - res1 = re.search('max_rxgain (?P<requested_option>[0-9]+)', self.eNBOptions[int(self.eNB_instance)]) - res2 = re.search('max_rxgain (?P<applied_option>[0-9]+)', str(line)) - if res1 is not None and res2 is not None: - requested_option = int(res1.group('requested_option')) - applied_option = int(res2.group('applied_option')) - if requested_option == applied_option: - self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ok-circle"></span> Command line option(s) correctly applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n' - else: - self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ban-circle"></span> Command line option(s) NOT applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n' - result = re.search('Exiting OAI softmodem', str(line)) - if result is not None: - exitSignalReceived = True - result = re.search('[Ss]egmentation [Ff]ault', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('./lte_build_oai/build/lte-softmodem', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Aa]ssertion', str(line)) - if result is not None and not exitSignalReceived: - foundAssertion = True - result = re.search('LLL', str(line)) - if result is not None and not exitSignalReceived: - foundRealTimeIssue = True - if foundAssertion and (msgLine < 3): - msgLine += 1 - msgAssertion += str(line) - result = re.search('Setting function for RU', str(line)) - if result is not None: - isRRU = True - if isRRU: - result = re.search('RU 0 is_slave=yes', str(line)) - if result is not None: - isSlave = True - if isSlave: - result = re.search('Received RRU_frame_resynch command', str(line)) - if result is not None: - slaveReceivesFrameResyncCmd = True - result = re.search('LTE_RRCConnectionSetupComplete from UE', str(line)) - if result is not None: - rrcSetupComplete += 1 - result = re.search('Generate LTE_RRCConnectionRelease|Generate RRCConnectionRelease', str(line)) - if result is not None: - rrcReleaseRequest += 1 - result = re.search('Generate LTE_RRCConnectionReconfiguration', str(line)) - if result is not None: - rrcReconfigRequest += 1 - result = re.search('LTE_RRCConnectionReconfigurationComplete from UE rnti', str(line)) - if result is not None: - rrcReconfigComplete += 1 - result = re.search('LTE_RRCConnectionReestablishmentRequest', str(line)) - if result is not None: - rrcReestablishRequest += 1 - result = re.search('LTE_RRCConnectionReestablishmentComplete', str(line)) - if result is not None: - rrcReestablishComplete += 1 - result = re.search('LTE_RRCConnectionReestablishmentReject', str(line)) - if result is not None: - rrcReestablishReject += 1 - result = re.search('CDRX configuration activated after RRC Connection', str(line)) - if result is not None: - cdrxActivationMessageCount += 1 - result = re.search('uci->stat', str(line)) - if result is not None: - uciStatMsgCount += 1 - result = re.search('PDCP.*Out of Resources.*reason', str(line)) - if result is not None: - pdcpFailure += 1 - result = re.search('ULSCH in error in round', str(line)) - if result is not None: - ulschFailure += 1 - result = re.search('BAD all_segments_received', str(line)) - if result is not None: - rlcDiscardBuffer += 1 - result = re.search('Canceled RA procedure for UE rnti', str(line)) - if result is not None: - rachCanceledProcedure += 1 - result = re.search('dropping, not enough RBs', str(line)) - if result is not None: - dropNotEnoughRBs += 1 - enb_log_file.close() - logging.debug(' File analysis completed') - if uciStatMsgCount > 0: - statMsg = 'eNB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if pdcpFailure > 0: - statMsg = 'eNB showed ' + str(pdcpFailure) + ' "PDCP Out of Resources" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if ulschFailure > 0: - statMsg = 'eNB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if dropNotEnoughRBs > 0: - statMsg = 'eNB showed ' + str(dropNotEnoughRBs) + ' "dropping, not enough RBs" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if rrcSetupComplete > 0: - rrcMsg = 'eNB completed ' + str(rrcSetupComplete) + ' RRC Connection Setup(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rrcReleaseRequest > 0: - rrcMsg = 'eNB requested ' + str(rrcReleaseRequest) + ' RRC Connection Release(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rrcReconfigRequest > 0 or rrcReconfigComplete > 0: - rrcMsg = 'eNB requested ' + str(rrcReconfigRequest) + ' RRC Connection Reconfiguration(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReconfigComplete) + ' were completed' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rrcReestablishRequest > 0 or rrcReestablishComplete > 0 or rrcReestablishReject > 0: - rrcMsg = 'eNB requested ' + str(rrcReestablishRequest) + ' RRC Connection Reestablishment(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReestablishComplete) + ' were completed' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if X2HO_inNbProcedures > 0: - rrcMsg = 'eNB completed ' + str(X2HO_inNbProcedures) + ' X2 Handover Connection procedure(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if X2HO_outNbProcedures > 0: - rrcMsg = 'eNB completed ' + str(X2HO_outNbProcedures) + ' X2 Handover Release procedure(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if self.eNBOptions[int(self.eNB_instance)] != '': - res1 = re.search('drx_Config_present prSetup', self.eNBOptions[int(self.eNB_instance)]) - if res1 is not None: - if cdrxActivationMessageCount > 0: - rrcMsg = 'eNB activated the CDRX Configuration for ' + str(cdrxActivationMessageCount) + ' time(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - else: - rrcMsg = 'eNB did NOT ACTIVATE the CDRX Configuration' - logging.debug('\u001B[1;37;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rachCanceledProcedure > 0: - rachMsg = 'eNB cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)' - logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rachMsg + '\n' - if isRRU: - if isSlave: - if slaveReceivesFrameResyncCmd: - rruMsg = 'Slave RRU received the RRU_frame_resynch command from RAU' - logging.debug('\u001B[1;30;43m ' + rruMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rruMsg + '\n' - else: - rruMsg = 'Slave RRU DID NOT receive the RRU_frame_resynch command from RAU' - logging.debug('\u001B[1;37;41m ' + rruMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rruMsg + '\n' - self.prematureExit = True - return ENB_PROCESS_SLAVE_RRU_NOT_SYNCED - if foundSegFault: - logging.debug('\u001B[1;37;41m eNB ended with a Segmentation Fault! \u001B[0m') - return ENB_PROCESS_SEG_FAULT - if foundAssertion: - logging.debug('\u001B[1;37;41m eNB ended with an assertion! \u001B[0m') - self.htmleNBFailureMsg += msgAssertion - return ENB_PROCESS_ASSERTION - if foundRealTimeIssue: - logging.debug('\u001B[1;37;41m eNB faced real time issues! \u001B[0m') - self.htmleNBFailureMsg += 'eNB faced real time issues!\n' - #return ENB_PROCESS_REALTIME_ISSUE - if rlcDiscardBuffer > 0: - rlcMsg = 'eNB RLC discarded ' + str(rlcDiscardBuffer) + ' buffer(s)' - logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rlcMsg + '\n' - return ENB_PROCESS_REALTIME_ISSUE - return 0 - - def AnalyzeLogFile_UE(self, UElogFile): - if (not os.path.isfile('./' + UElogFile)): - return -1 - ue_log_file = open('./' + UElogFile, 'r') - exitSignalReceived = False - foundAssertion = False - msgAssertion = '' - msgLine = 0 - foundSegFault = False - foundRealTimeIssue = False - uciStatMsgCount = 0 - pdcpDataReqFailedCount = 0 - badDciCount = 0 - rrcConnectionRecfgComplete = 0 - no_cell_sync_found = False - mib_found = False - frequency_found = False - plmn_found = False - self.htmlUEFailureMsg = '' - for line in ue_log_file.readlines(): - result = re.search('Exiting OAI softmodem', str(line)) - if result is not None: - exitSignalReceived = True - result = re.search('System error|[Ss]egmentation [Ff]ault|======= Backtrace: =========|======= Memory map: ========', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('./lte-uesoftmodem', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Aa]ssertion', str(line)) - if result is not None and not exitSignalReceived: - foundAssertion = True - result = re.search('LLL', str(line)) - if result is not None and not exitSignalReceived: - foundRealTimeIssue = True - if foundAssertion and (msgLine < 3): - msgLine += 1 - msgAssertion += str(line) - result = re.search('uci->stat', str(line)) - if result is not None and not exitSignalReceived: - uciStatMsgCount += 1 - result = re.search('PDCP data request failed', str(line)) - if result is not None and not exitSignalReceived: - pdcpDataReqFailedCount += 1 - result = re.search('bad DCI 1A', str(line)) - if result is not None and not exitSignalReceived: - badDciCount += 1 - result = re.search('Generating RRCConnectionReconfigurationComplete', str(line)) - if result is not None: - rrcConnectionRecfgComplete += 1 - # No cell synchronization found, abandoning - result = re.search('No cell synchronization found, abandoning', str(line)) - if result is not None: - no_cell_sync_found = True - result = re.search("MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P<nidcell>\d{1,3}), N_RB_DL (?P<n_rb_dl>\d{1,3}), PHICH DURATION (?P<phich_duration>\d), PHICH RESOURCE (?P<phich_resource>.{1,4}), TX_ANT (?P<tx_ant>\d)", str(line)) - if result is not None and (not mib_found): - try: - mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2) - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " nidcell = " + result.group('nidcell') - self.htmlUEFailureMsg += mibMsg - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " n_rb_dl = " + result.group('n_rb_dl') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " phich_duration = " + result.group('phich_duration') - self.htmlUEFailureMsg += mibMsg - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " phich_resource = " + result.group('phich_resource') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " tx_ant = " + result.group('tx_ant') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mib_found = True - except Exception as e: - logging.error('\033[91m' + "MIB marker was not found" + '\033[0m') - result = re.search("Measured Carrier Frequency (?P<measured_carrier_frequency>\d{1,15}) Hz", str(line)) - if result is not None and (not frequency_found): - try: - mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz' - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - frequency_found = True - except Exception as e: - logging.error('\033[91m' + "Measured Carrier Frequency not found" + '\033[0m') - result = re.search("PLMN MCC (?P<mcc>\d{1,3}), MNC (?P<mnc>\d{1,3}), TAC", str(line)) - if result is not None and (not plmn_found): - try: - mibMsg = 'PLMN MCC = ' + result.group('mcc') + ' MNC = ' + result.group('mnc') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - plmn_found = True - except Exception as e: - logging.error('\033[91m' + "PLMN not found" + '\033[0m') - result = re.search("Found (?P<operator>[\w,\s]{1,15}) \(name from internal table\)", str(line)) - if result is not None: - try: - mibMsg = "The operator is: " + result.group('operator') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - except Exception as e: - logging.error('\033[91m' + "Operator name not found" + '\033[0m') - result = re.search("SIB5 InterFreqCarrierFreq element (.{1,4})/(.{1,4})", str(line)) - if result is not None: - try: - mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2) - self.htmlUEFailureMsg += mibMsg + ' -> ' - logging.debug('\033[94m' + mibMsg + '\033[0m') - except Exception as e: - logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m') - result = re.search("DL Carrier Frequency/ARFCN : (?P<carrier_frequency>\d{1,15}/\d{1,4})", str(line)) - if result is not None: - try: - freq = result.group('carrier_frequency') - new_freq = re.sub('/[0-9]+','',freq) - float_freq = float(new_freq) / 1000000 - self.htmlUEFailureMsg += 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz' - logging.debug('\033[94m' + " DL Carrier Frequency is: " + freq + '\033[0m') - except Exception as e: - logging.error('\033[91m' + " DL Carrier Frequency not found" + '\033[0m') - result = re.search("AllowedMeasBandwidth : (?P<allowed_bandwidth>\d{1,7})", str(line)) - if result is not None: - try: - prb = result.group('allowed_bandwidth') - self.htmlUEFailureMsg += ' -- PRB: ' + prb + '\n' - logging.debug('\033[94m' + " AllowedMeasBandwidth: " + prb + '\033[0m') - except Exception as e: - logging.error('\033[91m' + " AllowedMeasBandwidth not found" + '\033[0m') - ue_log_file.close() - if rrcConnectionRecfgComplete > 0: - statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)' - logging.debug('\033[94m' + statMsg + '\033[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if uciStatMsgCount > 0: - statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if pdcpDataReqFailedCount > 0: - statMsg = 'UE showed ' + str(pdcpDataReqFailedCount) + ' "PDCP data request failed" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if badDciCount > 0: - statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1A" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if foundSegFault: - logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') - return ENB_PROCESS_SEG_FAULT - if foundAssertion: - logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m') - self.htmlUEFailureMsg += 'UE showed an assertion!\n' - if not mib_found or not frequency_found: - return OAI_UE_PROCESS_ASSERTION - if foundRealTimeIssue: - logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m') - self.htmlUEFailureMsg += 'UE faced real time issues!\n' - #return ENB_PROCESS_REALTIME_ISSUE - if no_cell_sync_found and not mib_found: - logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m') - self.htmlUEFailureMsg += 'UE could not synchronize!\n' - return OAI_UE_PROCESS_COULD_NOT_SYNC - return 0 - - def TerminateeNB(self): - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(lIpAddr, lUserName, lPassWord) - self.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) - self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-softmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) - self.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5) - time.sleep(10) - self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-softmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) - time.sleep(5) - self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.close() - # If tracer options is on, stopping tshark on EPC side - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) - time.sleep(1) - if self.EPC_PcapFileName != '': - self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5) - self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.') - self.copyout(lIpAddr, lUserName, lPassWord, self.EPC_PcapFileName, lSourcePath + '/cmake_targets/.') - self.close() - logging.debug('\u001B[1m Replaying RAW record file\u001B[0m') - self.open(lIpAddr, lUserName, lPassWord) - self.command('cd ' + lSourcePath + '/common/utils/T/tracer/', '\$', 5) - enbLogFile = self.eNBLogFiles[int(self.eNB_instance)] - raw_record_file = enbLogFile.replace('.log', '_record.raw') - replay_log_file = enbLogFile.replace('.log', '_replay.log') - extracted_txt_file = enbLogFile.replace('.log', '_extracted_messages.txt') - extracted_log_file = enbLogFile.replace('.log', '_extracted_messages.log') - self.command('./extract_config -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + extracted_txt_file, '\$', 5) - self.command('echo $USER; nohup ./replay -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', lUserName, 5) - self.command('./textlog -d ' + lSourcePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + lSourcePath + '/cmake_targets/' + extracted_log_file, '\$', 5) - self.close() - self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + extracted_log_file, '.') - logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m') - logStatus = self.AnalyzeLogFile_eNB(extracted_log_file) - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.eNBLogFiles[int(self.eNB_instance)] = '' - else: - analyzeFile = False - if self.eNBLogFiles[int(self.eNB_instance)] != '': - analyzeFile = True - fileToAnalyze = self.eNBLogFiles[int(self.eNB_instance)] - self.eNBLogFiles[int(self.eNB_instance)] = '' - if analyzeFile: - copyin_res = self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + fileToAnalyze, '.') - if (copyin_res == -1): - logging.debug('\u001B[1;37;41m Could not copy eNB logfile to analyze it! \u001B[0m') - self.htmleNBFailureMsg = 'Could not copy eNB logfile to analyze it!' - self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE) - return - if self.eNB_serverId != '0': - self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/') - logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m ' + fileToAnalyze) - logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze) - if (logStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', logStatus) - self.preamtureExit = True - return - else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateHSS(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT oai_hss || true', '\$', 5) - time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep hss | grep -v grep', '\$', 5) - result = re.search('oai_hss -j', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL oai_hss || true', '\$', 5) - self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-hss.sh', '\$', 5) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_hss oai_hss || true', '\$', 5) - time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep hss | grep -v grep', '\$', 5) - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_hss oai_hss || true', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=simulated_hss --stop', '\$', 5) - time.sleep(1) - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL hss_sim', '\$', 5) - else: - logging.error('This should not happen!') - self.close() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateMME(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_mme mme || true', '\$', 5) - time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep mme | grep -v grep', '\$', 5) - result = re.search('mme -c', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_mme mme || true', '\$', 5) - self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-mme.sh', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cd /opt/ltebox/tools', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./stop_mme', '\$', 5) - else: - logging.error('This should not happen!') - self.close() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateSPGW(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT spgwc spgwu || true', '\$', 5) - time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5) - result = re.search('spgwc -c |spgwu -c ', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL spgwc spgwu || true', '\$', 5) - self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-spgw*.sh', '\$', 5) - self.command('stdbuf -o0 ps -aux | grep tshark | grep -v grep', '\$', 5) - result = re.search('-w ', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT tshark || true', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 ' + self.EPCSourceCodePath + '/scripts/*.pcap', '\$', 5) - elif re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_spgw spgw || true', '\$', 5) - time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5) - result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_spgw spgw || true', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cd /opt/ltebox/tools', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./stop_xGw', '\$', 5) - else: - logging.error('This should not happen!') - self.close() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateFlexranCtrl(self): - if self.flexranCtrlInstalled == False or self.flexranCtrlStarted == False: - return - if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5) - time.sleep(1) - self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5) - time.sleep(1) - self.close() - self.flexranCtrlStarted = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateUE_common(self, device_id, idx): - try: - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # back in airplane mode on (ie radio off) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') - - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"', '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"\'', '\$', 60) - result = re.search('shell +(?P<pid>\d+)', str(self.ssh.before)) - if result is not None: - pid_iperf = result.group('pid') - if self.ADBCentralized: - self.command('stdbuf -o0 adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"', '\$', 5) - else: - self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) - self.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def TerminateUE(self): - terminate_ue_flag = True - self.GetAllUEDevices(terminate_ue_flag) - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target= SSH.TerminateUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def TerminateOAIUE(self): - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - self.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.UEPassword + ' | sudo -S daemon --name=ue' + str(self.UE_instance) + '_daemon --stop', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT lte-uesoftmodem || true', '\$', 5) - time.sleep(10) - self.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('lte-uesoftmodem', str(self.ssh.before)) - if result is not None: - self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL lte-uesoftmodem || true', '\$', 5) - time.sleep(5) - self.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - self.close() - result = re.search('ue_', str(self.UELogFile)) - if result is not None: - copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') - if (copyin_res == -1): - logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m') - self.htmlUEFailureMsg = 'Could not copy UE logfile to analyze it!' - self.CreateHtmlTestRow('N/A', 'KO', OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE') - self.UELogFile = '' - return - logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m') - logStatus = self.AnalyzeLogFile_UE(self.UELogFile) - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is not None: - ueAction = 'Sniffing' - else: - ueAction = 'Connection' - if (logStatus < 0): - logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') - self.htmlUEFailureMsg = '<b>' + ueAction + ' Failed</b>\n' + self.htmlUEFailureMsg - self.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') - # In case of sniffing on commercial eNBs we have random results - # Not an error then - if (logStatus != OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): - self.Initialize_OAI_UE_args = '' - self.AutoTerminateUEandeNB() - else: - logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') - self.htmlUEFailureMsg = '<b>' + ueAction + ' Completed</b>\n' + self.htmlUEFailureMsg - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.UELogFile = '' - else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def AutoTerminateUEandeNB(self): - if (self.ADBIPAddress != 'none'): - self.testCase_id = 'AUTO-KILL-UE' - self.desc = 'Automatic Termination of UE' - self.ShowTestID() - self.TerminateUE() - if (self.Initialize_OAI_UE_args != ''): - self.testCase_id = 'AUTO-KILL-UE' - self.desc = 'Automatic Termination of UE' - self.ShowTestID() - self.TerminateOAIUE() - if (self.Initialize_eNB_args != ''): - self.testCase_id = 'AUTO-KILL-eNB' - self.desc = 'Automatic Termination of eNB' - self.ShowTestID() - self.eNB_instance = '0' - self.TerminateeNB() - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.testCase_id = 'AUTO-KILL-flexran-ctl' - self.desc = 'Automatic Termination of FlexRan CTL' - self.ShowTestID() - self.TerminateFlexranCtrl() - self.prematureExit = True - - def IdleSleep(self): - time.sleep(self.idle_sleep_time) - self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK) - - def X2_Status(self, idx, fileName): - cmd = "curl --silent http://" + self.EPCIPAddress + ":9999/stats | jq '.' > " + fileName - message = cmd + '\n' - logging.debug(cmd) - subprocess.run(cmd, shell=True) - if idx == 0: - cmd = "jq '.mac_stats | length' " + fileName - strNbEnbs = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2NbENBs = int(strNbEnbs.strip()) - cnt = 0 - while cnt < self.x2NbENBs: - cmd = "jq '.mac_stats[" + str(cnt) + "].bs_id' " + fileName - bs_id = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2ENBBsIds[idx].append(bs_id.strip()) - cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats | length' " + fileName - stNbUEs = subprocess.check_output(cmd, shell=True, universal_newlines=True) - nbUEs = int(stNbUEs.strip()) - ueIdx = 0 - self.x2ENBConnectedUEs[idx].append([]) - while ueIdx < nbUEs: - cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats[" + str(ueIdx) + "].rnti' " + fileName - rnti = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2ENBConnectedUEs[idx][cnt].append(rnti.strip()) - ueIdx += 1 - cnt += 1 - - msg = "FlexRan Controller is connected to " + str(self.x2NbENBs) + " eNB(s)" - logging.debug(msg) - message += msg + '\n' - cnt = 0 - while cnt < self.x2NbENBs: - msg = " -- eNB: " + str(self.x2ENBBsIds[idx][cnt]) + " is connected to " + str(len(self.x2ENBConnectedUEs[idx][self.cnt])) + " UE(s)" - logging.debug(msg) - message += msg + '\n' - ueIdx = 0 - while ueIdx < len(self.x2ENBConnectedUEs[idx][cnt]): - msg = " -- UE rnti: " + str(self.x2ENBConnectedUEs[idx][cnt][ueIdx]) - logging.debug(msg) - message += msg + '\n' - ueIdx += 1 - cnt += 1 - return message - - def Perform_X2_Handover(self): - html_queue = SimpleQueue() - fullMessage = '<pre style="background-color:white">' - msg = 'Doing X2 Handover w/ option ' + self.x2_ho_options - logging.debug(msg) - fullMessage += msg + '\n' - if self.x2_ho_options == 'network': - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.x2ENBBsIds = [] - self.x2ENBConnectedUEs = [] - self.x2ENBBsIds.append([]) - self.x2ENBBsIds.append([]) - self.x2ENBConnectedUEs.append([]) - self.x2ENBConnectedUEs.append([]) - fullMessage += self.X2_Status(0, self.testCase_id + '_pre_ho.json') - - msg = "Activating the X2 Net control on each eNB" - logging.debug(msg) - fullMessage += msg + '\n' - eNB_cnt = self.x2NbENBs - cnt = 0 - while cnt < eNB_cnt: - cmd = "curl -XPOST http://" + self.EPCIPAddress + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1" - logging.debug(cmd) - fullMessage += cmd + '\n' - subprocess.run(cmd, shell=True) - cnt += 1 - # Waiting for the activation to be active - time.sleep(10) - msg = "Switching UE(s) from eNB to eNB" - logging.debug(msg) - fullMessage += msg + '\n' - cnt = 0 - while cnt < eNB_cnt: - ueIdx = 0 - while ueIdx < len(self.x2ENBConnectedUEs[0][cnt]): - cmd = "curl -XPOST http://" + self.EPCIPAddress + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1]) - logging.debug(cmd) - fullMessage += cmd + '\n' - subprocess.run(cmd, shell=True) - ueIdx += 1 - cnt += 1 - time.sleep(10) - # check - logging.debug("Checking the Status after X2 Handover") - fullMessage += self.X2_Status(1, self.testCase_id + '_post_ho.json') - cnt = 0 - x2Status = True - while cnt < eNB_cnt: - if len(self.x2ENBConnectedUEs[0][cnt]) == len(self.x2ENBConnectedUEs[1][cnt]): - x2Status = False - cnt += 1 - if x2Status: - msg = "X2 Handover was successful" - logging.debug(msg) - fullMessage += msg + '</pre>' - html_queue.put(fullMessage) - self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - else: - msg = "X2 Handover FAILED" - logging.error(msg) - fullMessage += msg + '</pre>' - html_queue.put(fullMessage) - self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - else: - self.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', ALL_PROCESSES_OK) - - def LogCollectBuild(self): - if (self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != ''): - IPAddress = self.eNBIPAddress - UserName = self.eNBUserName - Password = self.eNBPassword - SourceCodePath = self.eNBSourceCodePath - elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''): - IPAddress = self.UEIPAddress - UserName = self.UEUserName - Password = self.UEPassword - SourceCodePath = self.UESourceCodePath - else: - sys.exit('Insufficient Parameter') - self.open(IPAddress, UserName, Password) - self.command('cd ' + SourceCodePath, '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('rm -f build.log.zip', '\$', 5) - self.command('zip build.log.zip build_log_*/*', '\$', 60) - self.close() - - def LogCollecteNB(self): - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('cd ' + self.eNBSourceCodePath, '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 60) - self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 5) - self.close() - - def LogCollectPing(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('rm -f ping.log.zip', '\$', 5) - self.command('zip ping.log.zip ping*.log', '\$', 60) - self.command('rm ping*.log', '\$', 5) - self.close() - - def LogCollectIperf(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath, '\$', 5) - self.command('cd scripts', '\$', 5) - self.command('rm -f iperf.log.zip', '\$', 5) - self.command('zip iperf.log.zip iperf*.log', '\$', 60) - self.command('rm iperf*.log', '\$', 5) - self.close() - - def LogCollectHSS(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('rm -f hss.log.zip', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('zip hss.log.zip hss*.log', '\$', 60) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm hss*.log', '\$', 5) - if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('zip hss.log.zip logs/hss*.* *.pcap', '\$', 60) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f logs/hss*.* *.pcap', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cp /opt/hss_sim0609/hss.log .', '\$', 60) - self.command('zip hss.log.zip hss.log', '\$', 60) - else: - logging.error('This option should not occur!') - self.close() - - def LogCollectMME(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('rm -f mme.log.zip', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('zip mme.log.zip mme*.log', '\$', 60) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm mme*.log', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cp /opt/ltebox/var/log/*Log.0 .', '\$', 5) - self.command('zip mme.log.zip mmeLog.0 s1apcLog.0 s1apsLog.0 s11cLog.0 libLog.0 s1apCodecLog.0', '\$', 60) - else: - logging.error('This option should not occur!') - self.close() - - def LogCollectSPGW(self): - self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('rm -f spgw.log.zip', '\$', 5) - if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE): - self.command('zip spgw.log.zip spgw*.log', '\$', 60) - self.command('echo ' + self.EPCPassword + ' | sudo -S rm spgw*.log', '\$', 5) - elif re.match('ltebox', self.EPCType, re.IGNORECASE): - self.command('cp /opt/ltebox/var/log/xGwLog.0 .', '\$', 5) - self.command('zip spgw.log.zip xGwLog.0', '\$', 60) - else: - logging.error('This option should not occur!') - self.close() - - def LogCollectOAIUE(self): - self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('cd cmake_targets', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S rm -f ue.log.zip', '\$', 5) - self.command('echo ' + self.UEPassword + ' | sudo -S zip ue.log.zip ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 60) - self.command('echo ' + self.UEPassword + ' | sudo -S rm ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 5) - self.close() - - def RetrieveSystemVersion(self, machine): - if self.eNBIPAddress == 'none' or self.UEIPAddress == 'none': - self.OsVersion = 'Ubuntu 16.04.5 LTS' - self.KernelVersion = '4.15.0-45-generic' - self.UhdVersion = '3.13.0.1-0' - self.UsrpBoard = 'B210' - self.CpuNb = '4' - self.CpuModel = 'Intel(R) Core(TM) i5-6200U' - self.CpuMHz = '2399.996 MHz' - return 0 - if machine == 'eNB': - if self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != '': - IPAddress = self.eNBIPAddress - UserName = self.eNBUserName - Password = self.eNBPassword - else: - return -1 - if machine == 'UE': - if self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != '': - IPAddress = self.UEIPAddress - UserName = self.UEUserName - Password = self.UEPassword - else: - return -1 - - self.open(IPAddress, UserName, Password) - self.command('lsb_release -a', '\$', 5) - result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', str(self.ssh.before)) - if result is not None: - self.OsVersion = result.group('os_type') - logging.debug('OS is: ' + self.OsVersion) - self.command('uname -r', '\$', 5) - result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', str(self.ssh.before)) - if result is not None: - self.KernelVersion = result.group('kernel_version') - logging.debug('Kernel Version is: ' + self.KernelVersion) - self.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) - result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', str(self.ssh.before)) - if result is not None: - self.UhdVersion = result.group('uhd_version') - logging.debug('UHD Version is: ' + self.UhdVersion) - self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 15) - result = re.search('product: (?P<usrp_board>[0-9A-Za-z]+)\\\\r\\\\n', str(self.ssh.before)) - if result is not None: - self.UsrpBoard = result.group('usrp_board') - logging.debug('USRP Board is: ' + self.UsrpBoard) - self.command('lscpu', '\$', 5) - result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', str(self.ssh.before)) - if result is not None: - self.CpuNb = result.group('nb_cpus') - logging.debug('nb_cpus: ' + self.CpuNb) - self.CpuModel = result.group('model') - logging.debug('model: ' + self.CpuModel) - self.CpuMHz = result.group('cpu_mhz') + ' MHz' - logging.debug('cpu_mhz: ' + self.CpuMHz) - self.close() - -#----------------------------------------------------------- -# HTML Reporting.... -#----------------------------------------------------------- - def CreateHtmlHeader(self): - if (not self.htmlHeaderCreated): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1m Creating HTML header \u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - self.htmlFile = open('test_results.html', 'w') - self.htmlFile.write('<!DOCTYPE html>\n') - self.htmlFile.write('<html class="no-js" lang="en-US">\n') - self.htmlFile.write('<head>\n') - self.htmlFile.write(' <meta name="viewport" content="width=device-width, initial-scale=1">\n') - self.htmlFile.write(' <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">\n') - self.htmlFile.write(' <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>\n') - self.htmlFile.write(' <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>\n') - self.htmlFile.write(' <title>Test Results for TEMPLATE_JOB_NAME job build #TEMPLATE_BUILD_ID</title>\n') - self.htmlFile.write('</head>\n') - self.htmlFile.write('<body><div class="container">\n') - self.htmlFile.write(' <br>\n') - self.htmlFile.write(' <table style="border-collapse: collapse; border: none;">\n') - self.htmlFile.write(' <tr style="border-collapse: collapse; border: none;">\n') - self.htmlFile.write(' <td style="border-collapse: collapse; border: none;">\n') - self.htmlFile.write(' <a href="http://www.openairinterface.org/">\n') - self.htmlFile.write(' <img src="http://www.openairinterface.org/wp-content/uploads/2016/03/cropped-oai_final_logo2.png" alt="" border="none" height=50 width=150>\n') - self.htmlFile.write(' </img>\n') - self.htmlFile.write(' </a>\n') - self.htmlFile.write(' </td>\n') - self.htmlFile.write(' <td style="border-collapse: collapse; border: none; vertical-align: center;">\n') - self.htmlFile.write(' <b><font size = "6">Job Summary -- Job: TEMPLATE_JOB_NAME -- Build-ID: TEMPLATE_BUILD_ID</font></b>\n') - self.htmlFile.write(' </td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - self.htmlFile.write(' <br>\n') - self.htmlFile.write(' <div class="alert alert-info"><strong> <span class="glyphicon glyphicon-dashboard"></span> TEMPLATE_STAGE_NAME</strong></div>\n') - self.htmlFile.write(' <table border = "1">\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-time"></span> Build Start Time (UTC) </td>\n') - self.htmlFile.write(' <td>TEMPLATE_BUILD_TIME</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-cloud-upload"></span> GIT Repository </td>\n') - self.htmlFile.write(' <td><a href="' + self.ranRepository + '">' + self.ranRepository + '</a></td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-wrench"></span> Job Trigger </td>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td>Merge-Request</td>\n') - else: - self.htmlFile.write(' <td>Push to Branch</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-out"></span> Source Branch </td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tree-deciduous"></span> Branch</td>\n') - self.htmlFile.write(' <td>' + self.ranBranch + '</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Source Commit ID </td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Commit ID </td>\n') - self.htmlFile.write(' <td>' + self.ranCommitID + '</td>\n') - self.htmlFile.write(' </tr>\n') - if self.ranAllowMerge != '': - commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.ranCommitID, shell=True, universal_newlines=True) - commit_message = commit_message.strip() - self.htmlFile.write(' <tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Source Commit Message </td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Commit Message </td>\n') - self.htmlFile.write(' <td>' + commit_message + '</td>\n') - self.htmlFile.write(' </tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-in"></span> Target Branch </td>\n') - if (self.ranTargetBranch == ''): - self.htmlFile.write(' <td>develop</td>\n') - else: - self.htmlFile.write(' <td>' + self.ranTargetBranch + '</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - - if (self.ADBIPAddress != 'none'): - terminate_ue_flag = True - self.GetAllUEDevices(terminate_ue_flag) - self.GetAllCatMDevices(terminate_ue_flag) - self.htmlUEConnected = len(self.UEDevices) - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server</h2>\n') - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n') - else: - self.UEDevices.append('OAI-UE') - self.htmlUEConnected = len(self.UEDevices) - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' OAI UE(s) is(are) connected to CI bench</h2>\n') - self.htmlFile.write(' <br>\n') - self.htmlFile.write(' <ul class="nav nav-pills">\n') - count = 0 - while (count < self.nbTestXMLfiles): - pillMsg = ' <li><a data-toggle="pill" href="#' - pillMsg += self.htmlTabRefs[count] - pillMsg += '">' - pillMsg += '__STATE_' + self.htmlTabNames[count] + '__' - pillMsg += self.htmlTabNames[count] - pillMsg += ' <span class="glyphicon glyphicon-' - pillMsg += self.htmlTabIcons[count] - pillMsg += '"></span></a></li>\n' - self.htmlFile.write(pillMsg) - count += 1 - self.htmlFile.write(' </ul>\n') - self.htmlFile.write(' <div class="tab-content">\n') - self.htmlFile.close() - - def CreateHtmlTabHeader(self): - if (not self.htmlHeaderCreated): - if (not os.path.isfile('test_results.html')): - self.CreateHtmlHeader() - self.htmlFile = open('test_results.html', 'a') - if (self.nbTestXMLfiles == 1): - self.htmlFile.write(' <div id="' + self.htmlTabRefs[0] + '" class="tab-pane fade">\n') - self.htmlFile.write(' <h3>Test Summary for <span class="glyphicon glyphicon-file"></span> ' + self.testXMLfiles[0] + '</h3>\n') - else: - self.htmlFile.write(' <div id="build-tab" class="tab-pane fade">\n') - self.htmlFile.write(' <table class="table" border = "1">\n') - self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n') - self.htmlFile.write(' <th>Relative Time (ms)</th>\n') - self.htmlFile.write(' <th>Test Id</th>\n') - self.htmlFile.write(' <th>Test Desc</th>\n') - self.htmlFile.write(' <th>Test Options</th>\n') - self.htmlFile.write(' <th>Test Status</th>\n') - if (self.htmlUEConnected == -1): - terminate_ue_flag = True - if (self.ADBIPAddress != 'none'): - self.GetAllUEDevices(terminate_ue_flag) - self.GetAllCatMDevices(terminate_ue_flag) - else: - self.UEDevices.append('OAI-UE') - self.htmlUEConnected = len(self.UEDevices) - - i = 0 - while (i < self.htmlUEConnected): - self.htmlFile.write(' <th>UE' + str(i) + ' Status</th>\n') - i += 1 - self.htmlFile.write(' </tr>\n') - self.htmlHeaderCreated = True - - def CreateHtmlTabFooter(self, passStatus): - if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th bgcolor = "#33CCFF" colspan=3>Final Tab Status</th>\n') - if passStatus: - self.htmlFile.write(' <th bgcolor = "green" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">PASS <span class="glyphicon glyphicon-ok"></span> </font></th>\n') - else: - self.htmlFile.write(' <th bgcolor = "red" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - self.htmlFile.write(' </div>\n') - self.htmlFile.close() - time.sleep(1) - if passStatus: - cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__//' test_results.html" - subprocess.run(cmd, shell=True) - else: - cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<span class=\"glyphicon glyphicon-remove\"><\/span>/' test_results.html" - subprocess.run(cmd, shell=True) - self.htmlFooterCreated = False - - def CreateHtmlFooter(self, passStatus): - if (os.path.isfile('test_results.html')): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1m Creating HTML footer \u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - - self.htmlFile = open('test_results.html', 'a') - self.htmlFile.write('</div>\n') - self.htmlFile.write(' <p></p>\n') - self.htmlFile.write(' <table class="table table-condensed">\n') - - machines = [ 'eNB', 'UE' ] - for machine in machines: - res = self.RetrieveSystemVersion(machine) - if res == -1: - continue - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th colspan=8>' + str(machine) + ' Server Characteristics</th>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td>OS Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.OsVersion + '</span></td>\n') - self.htmlFile.write(' <td>Kernel Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.KernelVersion + '</span></td>\n') - self.htmlFile.write(' <td>UHD Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.UhdVersion + '</span></td>\n') - self.htmlFile.write(' <td>USRP Board</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.UsrpBoard + '</span></td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td>Nb CPUs</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.CpuNb + '</span></td>\n') - self.htmlFile.write(' <td>CPU Model Name</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.CpuModel + '</span></td>\n') - self.htmlFile.write(' <td>CPU Frequency</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.CpuMHz + '</span></td>\n') - self.htmlFile.write(' <td></td>\n') - self.htmlFile.write(' <td></td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th colspan=5 bgcolor = "#33CCFF">Final Status</th>\n') - if passStatus: - self.htmlFile.write(' <th colspan=3 bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n') - else: - self.htmlFile.write(' <th colspan=3 bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - self.htmlFile.write(' <p></p>\n') - self.htmlFile.write(' <div class="well well-lg">End of Test Report -- Copyright <span class="glyphicon glyphicon-copyright-mark"></span> 2018 <a href="http://www.openairinterface.org/">OpenAirInterface</a>. All Rights Reserved.</div>\n') - self.htmlFile.write('</div></body>\n') - self.htmlFile.write('</html>\n') - self.htmlFile.close() - - def CreateHtmlTestRow(self, options, status, processesStatus, machine='eNB'): - if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - currentTime = int(round(time.time() * 1000)) - self.startTime - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + format(currentTime / 1000, '.1f') + '</td>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n') - self.htmlFile.write(' <td>' + self.desc + '</td>\n') - self.htmlFile.write(' <td>' + str(options) + '</td>\n') - if (str(status) == 'OK'): - self.htmlFile.write(' <td bgcolor = "lightgreen" >' + str(status) + '</td>\n') - elif (str(status) == 'KO'): - if (processesStatus == 0): - self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') - elif (processesStatus == ENB_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process not found</td>\n') - elif (processesStatus == OAI_UE_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - OAI UE process not found</td>\n') - elif (processesStatus == ENB_PROCESS_SEG_FAULT): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Segmentation Fault</td>\n') - elif (processesStatus == ENB_PROCESS_ASSERTION) or (processesStatus == OAI_UE_PROCESS_ASSERTION): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Assertion</td>\n') - elif (processesStatus == ENB_PROCESS_REALTIME_ISSUE): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process faced Real Time issue(s)</td>\n') - elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE) or (processesStatus == OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE): - self.htmlFile.write(' <td bgcolor = "orange" >OK?</td>\n') - elif (processesStatus == ENB_PROCESS_SLAVE_RRU_NOT_SYNCED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' Slave RRU could not synch</td>\n') - elif (processesStatus == OAI_UE_PROCESS_COULD_NOT_SYNC): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - UE could not sync</td>\n') - elif (processesStatus == HSS_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - HSS process not found</td>\n') - elif (processesStatus == MME_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - MME process not found</td>\n') - elif (processesStatus == SPGW_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - SPGW process not found</td>\n') - elif (processesStatus == UE_IP_ADDRESS_ISSUE): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - Could not retrieve UE IP address</td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') - else: - self.htmlFile.write(' <td bgcolor = "orange" >' + str(status) + '</td>\n') - if (len(str(self.htmleNBFailureMsg)) > 2): - cellBgColor = 'white' - result = re.search('ended with|faced real time issues', self.htmleNBFailureMsg) - if result is not None: - cellBgColor = 'red' - else: - result = re.search('showed|Reestablishment|Could not copy eNB logfile', self.htmleNBFailureMsg) - if result is not None: - cellBgColor = 'orange' - self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmleNBFailureMsg + '</pre></td>\n') - self.htmleNBFailureMsg = '' - elif (len(str(self.htmlUEFailureMsg)) > 2): - cellBgColor = 'white' - result = re.search('ended with|faced real time issues', self.htmlUEFailureMsg) - if result is not None: - cellBgColor = 'red' - else: - result = re.search('showed|Could not copy UE logfile|oaitun_ue1 interface is either NOT mounted or NOT configured', self.htmlUEFailureMsg) - if result is not None: - cellBgColor = 'orange' - self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmlUEFailureMsg + '</pre></td>\n') - self.htmlUEFailureMsg = '' - else: - i = 0 - while (i < self.htmlUEConnected): - self.htmlFile.write(' <td>-</td>\n') - i += 1 - self.htmlFile.write(' </tr>\n') - - def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue): - if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - currentTime = int(round(time.time() * 1000)) - self.startTime - addOrangeBK = False - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + format(currentTime / 1000, '.1f') + '</td>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n') - self.htmlFile.write(' <td>' + self.desc + '</td>\n') - self.htmlFile.write(' <td>' + str(options) + '</td>\n') - if (str(status) == 'OK'): - self.htmlFile.write(' <td bgcolor = "lightgreen" >' + str(status) + '</td>\n') - elif (str(status) == 'KO'): - self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') - else: - addOrangeBK = True - self.htmlFile.write(' <td bgcolor = "orange" >' + str(status) + '</td>\n') - i = 0 - while (i < self.htmlUEConnected): - if (i < ue_status): - if (not ue_queue.empty()): - if (addOrangeBK): - self.htmlFile.write(' <td bgcolor = "orange" >' + str(ue_queue.get()).replace('white', 'orange') + '</td>\n') - else: - self.htmlFile.write(' <td>' + str(ue_queue.get()) + '</td>\n') - else: - self.htmlFile.write(' <td>-</td>\n') - else: - self.htmlFile.write(' <td>-</td>\n') - i += 1 - self.htmlFile.write(' </tr>\n') - -#----------------------------------------------------------- -# ShowTestID() -#----------------------------------------------------------- - def ShowTestID(self): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1mTest ID:' + self.testCase_id + '\u001B[0m') - logging.debug('\u001B[1m' + self.desc + '\u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - -#----------------------------------------------------------- -# Usage() -#----------------------------------------------------------- -def Usage(): - print('----------------------------------------------------------------------------------------------------------------------') - print('main.py Ver:' + Version) - print('----------------------------------------------------------------------------------------------------------------------') - print('Usage: python main.py [options]') - print(' --help Show this help.') - print(' --mode=[Mode]') - print(' TesteNB') - print(' InitiateHtml, FinalizeHtml') - print(' TerminateeNB, TerminateUE, TerminateHSS, TerminateMME, TerminateSPGW') - print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf') - print('---------------------------------------------------------------------------------------------------- Git Options --') - print(' --ranRepository=[OAI RAN Repository URL]') - print(' --ranBranch=[OAI RAN Repository Branch]') - print(' --ranCommitID=[OAI RAN Repository Commit SHA-1]') - print(' --ranAllowMerge=[Allow Merge Request (with target branch) (true or false)]') - print(' --ranTargetBranch=[Target Branch in case of a Merge Request]') - print('--------------------------------------------------------------------------------------------- eNB Server Options --') - print(' --eNBIPAddress=[eNB\'s IP Address]') - print(' --eNBUserName=[eNB\'s Login User Name]') - print(' --eNBPassword=[eNB\'s Login Password]') - print(' --eNBSourceCodePath=[eNB\'s Source Code Path]') - print('------------------------------------------------------------------------------------------ OAI UE Server Options --') - print(' --UEIPAddress=[UE\'s IP Address]') - print(' --UEUserName=[UE\'s Login User Name]') - print(' --UEPassword=[UE\'s Login Password]') - print(' --UESourceCodePath=[UE\'s Source Code Path]') - print('--------------------------------------------------------------------------------------------- EPC Server Options --') - print(' --EPCIPAddress=[EPC\'s IP Address]') - print(' --EPCUserName=[EPC\'s Login User Name]') - print(' --EPCPassword=[EPC\'s Login Password]') - print(' --EPCSourceCodePath=[EPC\'s Source Code Path]') - print(' --EPCType=[EPC\'s Type: OAI or ltebox or OAI-Rel14-CUPS]') - print('--------------------------------------------------------------------------------------------- ABD Server Options --') - print(' --ADBIPAddress=[ADB\'s IP Address]') - print(' --ADBUserName=[ADB\'s Login User Name]') - print(' --ADBPassword=[ADB\'s Login Password]') - print('----------------------------------------------------------------------------------------------------------------------') - print(' --XMLTestFile=[XML Test File to be run]') - print('----------------------------------------------------------------------------------------------------------------------') - -def CheckClassValidity(action,id): - if action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover': - logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) - return False - return True - -def GetParametersFromXML(action): - if action == 'Build_eNB': - SSH.Build_eNB_args = test.findtext('Build_eNB_args') - SSH.eNB_instance = test.findtext('eNB_instance') - if (SSH.eNB_instance is None): - SSH.eNB_instance = '0' - SSH.eNB_serverId = test.findtext('eNB_serverId') - if (SSH.eNB_serverId is None): - SSH.eNB_serverId = '0' - xmlBgBuildField = test.findtext('backgroundBuild') - if (xmlBgBuildField is None): - SSH.backgroundBuild = False - else: - if re.match('true', xmlBgBuildField, re.IGNORECASE): - SSH.backgroundBuild = True - else: - SSH.backgroundBuild = False - - if action == 'WaitEndBuild_eNB': - SSH.Build_eNB_args = test.findtext('Build_eNB_args') - SSH.eNB_instance = test.findtext('eNB_instance') - if (SSH.eNB_instance is None): - SSH.eNB_instance = '0' - SSH.eNB_serverId = test.findtext('eNB_serverId') - if (SSH.eNB_serverId is None): - SSH.eNB_serverId = '0' - - if action == 'Initialize_eNB': - SSH.Initialize_eNB_args = test.findtext('Initialize_eNB_args') - SSH.eNB_instance = test.findtext('eNB_instance') - if (SSH.eNB_instance is None): - SSH.eNB_instance = '0' - SSH.eNB_serverId = test.findtext('eNB_serverId') - if (SSH.eNB_serverId is None): - SSH.eNB_serverId = '0' - - if action == 'Terminate_eNB': - SSH.eNB_instance = test.findtext('eNB_instance') - if (SSH.eNB_instance is None): - SSH.eNB_instance = '0' - SSH.eNB_serverId = test.findtext('eNB_serverId') - if (SSH.eNB_serverId is None): - SSH.eNB_serverId = '0' - - if action == 'Attach_UE': - nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach') - if (nbMaxUEtoAttach is None): - SSH.nbMaxUEtoAttach = -1 - else: - SSH.nbMaxUEtoAttach = int(nbMaxUEtoAttach) - - if action == 'CheckStatusUE': - expectedNBUE = test.findtext('expectedNbOfConnectedUEs') - if (expectedNBUE is None): - SSH.expectedNbOfConnectedUEs = -1 - else: - SSH.expectedNbOfConnectedUEs = int(expectedNBUE) - - if action == 'Build_OAI_UE': - SSH.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args') - - if action == 'Initialize_OAI_UE': - SSH.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args') - SSH.UE_instance = test.findtext('UE_instance') - if (SSH.UE_instance is None): - SSH.UE_instance = '0' - - if action == 'Terminate_OAI_UE': - SSH.eNB_instance = test.findtext('UE_instance') - if (SSH.UE_instance is None): - SSH.UE_instance = '0' - - if action == 'Ping' or action == 'Ping_CatM_module': - SSH.ping_args = test.findtext('ping_args') - SSH.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold') - - if action == 'Iperf': - SSH.iperf_args = test.findtext('iperf_args') - SSH.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold') - SSH.iperf_profile = test.findtext('iperf_profile') - if (SSH.iperf_profile is None): - SSH.iperf_profile = 'balanced' - else: - if SSH.iperf_profile != 'balanced' and SSH.iperf_profile != 'unbalanced' and SSH.iperf_profile != 'single-ue': - logging.debug('ERROR: test-case has wrong profile ' + SSH.iperf_profile) - SSH.iperf_profile = 'balanced' - - if action == 'IdleSleep': - string_field = test.findtext('idle_sleep_time_in_sec') - if (string_field is None): - SSH.idle_sleep_time = 5 - else: - SSH.idle_sleep_time = int(string_field) - - if action == 'Perform_X2_Handover': - string_field = test.findtext('x2_ho_options') - if (string_field is None): - SSH.x2_ho_options = 'network' - else: - if string_field != 'network': - logging.error('ERROR: test-case has wrong option ' + string_field) - SSH.x2_ho_options = 'network' - else: - SSH.x2_ho_options = string_field - - -#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 - -def receive_signal(signum, frame): - sys.exit(1) - -#----------------------------------------------------------- -# Parameter Check -#----------------------------------------------------------- -mode = '' -SSH = SSHConnection() - -argvs = sys.argv -argc = len(argvs) -cwd = os.getcwd() - -while len(argvs) > 1: - myArgv = argvs.pop(1) # 0th is this file's name - if re.match('^\-\-help$', myArgv, re.IGNORECASE): - Usage() - sys.exit(0) - elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE) - mode = matchReg.group(1) - elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE) - SSH.ranRepository = matchReg.group(1) - elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE) - doMerge = matchReg.group(1) - if ((doMerge == 'true') or (doMerge == 'True')): - SSH.ranAllowMerge = True - elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE) - SSH.ranBranch = matchReg.group(1) - elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE) - SSH.ranCommitID = matchReg.group(1) - elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE) - SSH.ranTargetBranch = matchReg.group(1) - elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.eNBIPAddress = matchReg.group(1) - elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB1IPAddress = matchReg.group(1) - elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB2IPAddress = matchReg.group(1) - elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) - SSH.eNBUserName = matchReg.group(1) - elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB1UserName = matchReg.group(1) - elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB2UserName = matchReg.group(1) - elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE) - SSH.eNBPassword = matchReg.group(1) - elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB1Password = matchReg.group(1) - elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB2Password = matchReg.group(1) - elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - SSH.eNBSourceCodePath = matchReg.group(1) - elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB1SourceCodePath = matchReg.group(1) - elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - SSH.eNB2SourceCodePath = matchReg.group(1) - elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.EPCIPAddress = matchReg.group(1) - elif re.match('^\-\-EPCBranch=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCBranch=(.+)$', myArgv, re.IGNORECASE) - SSH.EPCBranch = matchReg.group(1) - elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE) - SSH.EPCUserName = matchReg.group(1) - elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE) - SSH.EPCPassword = matchReg.group(1) - elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - SSH.EPCSourceCodePath = matchReg.group(1) - elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE) - if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE): - SSH.EPCType = matchReg.group(1) - else: - sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS)') - elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.ADBIPAddress = matchReg.group(1) - elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE) - SSH.ADBUserName = matchReg.group(1) - elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE) - if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE): - if re.match('distributed', matchReg.group(1), re.IGNORECASE): - SSH.ADBCentralized = False - else: - SSH.ADBCentralized = True - else: - sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)') - elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE) - SSH.ADBPassword = matchReg.group(1) - elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) - SSH.testXMLfiles.append(matchReg.group(1)) - SSH.nbTestXMLfiles += 1 - elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) - SSH.UEIPAddress = matchReg.group(1) - elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE) - SSH.UEUserName = matchReg.group(1) - elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE) - SSH.UEPassword = matchReg.group(1) - elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE) - SSH.UESourceCodePath = matchReg.group(1) - elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE) - finalStatus = matchReg.group(1) - if ((finalStatus == 'true') or (finalStatus == 'True')): - SSH.finalStatus = True - else: - Usage() - sys.exit('Invalid Parameter: ' + myArgv) - -if re.match('^TerminateeNB$', mode, re.IGNORECASE): - if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.eNB_serverId = '0' - SSH.eNB_instance = '0' - SSH.eNBSourceCodePath = '/tmp/' - SSH.TerminateeNB() -elif re.match('^TerminateUE$', mode, re.IGNORECASE): - if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''): - Usage() - sys.exit('Insufficient Parameter') - signal.signal(signal.SIGUSR1, receive_signal) - SSH.TerminateUE() -elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE): - if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '': - Usage() - sys.exit('Insufficient Parameter') - signal.signal(signal.SIGUSR1, receive_signal) - SSH.TerminateOAIUE() -elif re.match('^TerminateHSS$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.TerminateHSS() -elif re.match('^TerminateMME$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.TerminateMME() -elif re.match('^TerminateSPGW$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.TerminateSPGW() -elif re.match('^LogCollectBuild$', mode, re.IGNORECASE): - if (SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '') and (SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == ''): - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectBuild() -elif re.match('^LogCollecteNB$', mode, re.IGNORECASE): - if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollecteNB() -elif re.match('^LogCollectHSS$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectHSS() -elif re.match('^LogCollectMME$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectMME() -elif re.match('^LogCollectSPGW$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectSPGW() -elif re.match('^LogCollectPing$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectPing() -elif re.match('^LogCollectIperf$', mode, re.IGNORECASE): - if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCSourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectIperf() -elif re.match('^LogCollectOAIUE$', mode, re.IGNORECASE): - if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '': - Usage() - sys.exit('Insufficient Parameter') - SSH.LogCollectOAIUE() -elif re.match('^InitiateHtml$', mode, re.IGNORECASE): - if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''): - Usage() - sys.exit('Insufficient Parameter') - count = 0 - foundCount = 0 - while (count < SSH.nbTestXMLfiles): - xml_test_file = cwd + "/" + SSH.testXMLfiles[count] - xml_test_file = sys.path[0] + "/" + SSH.testXMLfiles[count] - if (os.path.isfile(xml_test_file)): - xmlTree = ET.parse(xml_test_file) - xmlRoot = xmlTree.getroot() - SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) - SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count))) - SSH.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign')) - foundCount += 1 - count += 1 - if foundCount != SSH.nbTestXMLfiles: - SSH.nbTestXMLfiles = foundCount - SSH.CreateHtmlHeader() -elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): - SSH.CreateHtmlFooter(SSH.finalStatus) -elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE): - if re.match('^TesteNB$', mode, re.IGNORECASE): - if SSH.eNBIPAddress == '' or SSH.ranRepository == '' or SSH.ranBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - - if (SSH.EPCIPAddress != '') and (SSH.EPCIPAddress != 'none'): - SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/tcp_iperf_stats.awk", "/tmp") - SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/active_net_interfaces.awk", "/tmp") - else: - if SSH.UEIPAddress == '' or SSH.ranRepository == '' or SSH.ranBranch == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '': - Usage() - sys.exit('UE: Insufficient Parameter') - - #read test_case_list.xml file - # if no parameters for XML file, use default value - if (SSH.nbTestXMLfiles != 1): - xml_test_file = cwd + "/test_case_list.xml" - else: - xml_test_file = cwd + "/" + SSH.testXMLfiles[0] - - xmlTree = ET.parse(xml_test_file) - xmlRoot = xmlTree.getroot() - - exclusion_tests=xmlRoot.findtext('TestCaseExclusionList',default='') - requested_tests=xmlRoot.findtext('TestCaseRequestedList',default='') - if (SSH.nbTestXMLfiles == 1): - SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) - SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0')) - repeatCount = xmlRoot.findtext('repeatCount',default='1') - SSH.repeatCounts.append(int(repeatCount)) - all_tests=xmlRoot.findall('testCase') - - exclusion_tests=exclusion_tests.split() - requested_tests=requested_tests.split() - - #check that exclusion tests are well formatted - #(6 digits or less than 6 digits followed by +) - for test in exclusion_tests: - if (not re.match('^[0-9]{6}$', test) and - not re.match('^[0-9]{1,5}\+$', test)): - logging.debug('ERROR: exclusion test is invalidly formatted: ' + test) - sys.exit(1) - else: - logging.debug(test) - - #check that requested tests are well formatted - #(6 digits or less than 6 digits followed by +) - #be verbose - for test in requested_tests: - if (re.match('^[0-9]{6}$', test) or - re.match('^[0-9]{1,5}\+$', test)): - logging.debug('INFO: test group/case requested: ' + test) - else: - logging.debug('ERROR: requested test is invalidly formatted: ' + test) - sys.exit(1) - if (SSH.EPCIPAddress != '') and (SSH.EPCIPAddress != 'none'): - SSH.CheckFlexranCtrlInstallation() - - #get the list of tests to be done - todo_tests=[] - for test in requested_tests: - if (test_in_list(test, exclusion_tests)): - logging.debug('INFO: test will be skipped: ' + test) - else: - #logging.debug('INFO: test will be run: ' + test) - todo_tests.append(test) - - signal.signal(signal.SIGUSR1, receive_signal) - - SSH.CreateHtmlTabHeader() - - SSH.FailReportCnt = 0 - SSH.prematureExit = True - SSH.startTime = int(round(time.time() * 1000)) - while SSH.FailReportCnt < SSH.repeatCounts[0] and SSH.prematureExit: - SSH.prematureExit = False - for test_case_id in todo_tests: - if SSH.prematureExit: - break - for test in all_tests: - if SSH.prematureExit: - break - id = test.get('id') - if test_case_id != id: - continue - SSH.testCase_id = id - SSH.desc = test.findtext('desc') - action = test.findtext('class') - if (CheckClassValidity(action, id) == False): - continue - SSH.ShowTestID() - GetParametersFromXML(action) - if action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Ping' or action == 'Iperf' or action == 'Reboot_UE' or action == 'DataDisable_UE' or action == 'DataEnable_UE' or action == 'CheckStatusUE': - if (SSH.ADBIPAddress != 'none'): - terminate_ue_flag = False - SSH.GetAllUEDevices(terminate_ue_flag) - if action == 'Build_eNB': - SSH.BuildeNB() - elif action == 'WaitEndBuild_eNB': - SSH.WaitBuildeNBisFinished() - elif action == 'Initialize_eNB': - SSH.InitializeeNB() - elif action == 'Terminate_eNB': - SSH.TerminateeNB() - elif action == 'Initialize_UE': - SSH.InitializeUE() - elif action == 'Terminate_UE': - SSH.TerminateUE() - elif action == 'Attach_UE': - SSH.AttachUE() - elif action == 'Detach_UE': - SSH.DetachUE() - elif action == 'DataDisable_UE': - SSH.DataDisableUE() - elif action == 'DataEnable_UE': - SSH.DataEnableUE() - elif action == 'CheckStatusUE': - SSH.CheckStatusUE() - elif action == 'Build_OAI_UE': - SSH.BuildOAIUE() - elif action == 'Initialize_OAI_UE': - SSH.InitializeOAIUE() - elif action == 'Terminate_OAI_UE': - SSH.TerminateOAIUE() - elif action == 'Initialize_CatM_module': - SSH.InitializeCatM() - elif action == 'Terminate_CatM_module': - SSH.TerminateCatM() - elif action == 'Attach_CatM_module': - SSH.AttachCatM() - elif action == 'Detach_CatM_module': - SSH.TerminateCatM() - elif action == 'Ping_CatM_module': - SSH.PingCatM() - elif action == 'Ping': - SSH.Ping() - elif action == 'Iperf': - SSH.Iperf() - elif action == 'Reboot_UE': - SSH.RebootUE() - elif action == 'Initialize_HSS': - SSH.InitializeHSS() - elif action == 'Terminate_HSS': - SSH.TerminateHSS() - elif action == 'Initialize_MME': - SSH.InitializeMME() - elif action == 'Terminate_MME': - SSH.TerminateMME() - elif action == 'Initialize_SPGW': - SSH.InitializeSPGW() - elif action == 'Terminate_SPGW': - SSH.TerminateSPGW() - elif action == 'Initialize_FlexranCtrl': - SSH.InitializeFlexranCtrl() - elif action == 'Terminate_FlexranCtrl': - SSH.TerminateFlexranCtrl() - elif action == 'IdleSleep': - SSH.IdleSleep() - elif action == 'Perform_X2_Handover': - SSH.Perform_X2_Handover() - else: - sys.exit('Invalid action') - SSH.FailReportCnt += 1 - if SSH.FailReportCnt == SSH.repeatCounts[0] and SSH.prematureExit: - logging.debug('Testsuite failed ' + str(SSH.FailReportCnt) + ' time(s)') - SSH.CreateHtmlTabFooter(False) - sys.exit('Failed Scenario') - else: - logging.info('Testsuite passed after ' + str(SSH.FailReportCnt) + ' time(s)') - SSH.CreateHtmlTabFooter(True) -else: - Usage() - sys.exit('Invalid mode') -sys.exit(0) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index c9da55041c92daf71c37c6c43c66a64b20f3eabd..1dd840225040194f24e12cdfaf9134e9f309311c 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -28,48 +28,13 @@ # pexpect #--------------------------------------------------------------------- +import constants as CONST + #----------------------------------------------------------- # Version #----------------------------------------------------------- Version = '0.1' -#----------------------------------------------------------- -# Constants -#----------------------------------------------------------- -ALL_PROCESSES_OK = 0 -ENB_PROCESS_FAILED = -1 -ENB_PROCESS_OK = +1 -ENB_PROCESS_SEG_FAULT = -11 -ENB_PROCESS_ASSERTION = -12 -ENB_PROCESS_REALTIME_ISSUE = -13 -ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14 -ENB_PROCESS_SLAVE_RRU_NOT_SYNCED = -15 -HSS_PROCESS_FAILED = -2 -HSS_PROCESS_OK = +2 -MME_PROCESS_FAILED = -3 -MME_PROCESS_OK = +3 -SPGW_PROCESS_FAILED = -4 -SPGW_PROCESS_OK = +4 -UE_IP_ADDRESS_ISSUE = -5 -OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE = -20 -OAI_UE_PROCESS_COULD_NOT_SYNC = -21 -OAI_UE_PROCESS_ASSERTION = -22 -OAI_UE_PROCESS_FAILED = -23 -OAI_UE_PROCESS_NO_TUNNEL_INTERFACE = -24 -OAI_UE_PROCESS_SEG_FAULT = -25 -OAI_UE_PROCESS_OK = +6 - -UE_STATUS_DETACHED = 0 -UE_STATUS_DETACHING = 1 -UE_STATUS_ATTACHING = 2 -UE_STATUS_ATTACHED = 3 - -X2_HO_REQ_STATE__IDLE = 0 -X2_HO_REQ_STATE__TARGET_RECEIVES_REQ = 1 -X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE = 2 -X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ = 3 -X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK = 10 - #----------------------------------------------------------- # Import #----------------------------------------------------------- @@ -89,56 +54,22 @@ logging.basicConfig( format="[%(asctime)s] %(name)s:%(levelname)s: %(message)s" ) + #----------------------------------------------------------- # Class Declaration #----------------------------------------------------------- class OaiCiTest(): + def __init__(self): self.FailReportCnt = 0 - self.prematureExit = False - self.ranRepository = '' - self.ranBranch = '' - self.ranAllowMerge = False - self.ranCommitID = '' - self.ranTargetBranch = '' - self.eNBIPAddress = '' - self.eNBUserName = '' - self.eNBPassword = '' - self.eNBSourceCodePath = '' - #self.EPCIPAddress = '' - #self.EPCUserName = '' - #self.EPCPassword = '' - self.eNB1IPAddress = '' - self.eNB1UserName = '' - self.eNB1Password = '' - self.eNB1SourceCodePath = '' - self.eNB2IPAddress = '' - self.eNB2UserName = '' - self.eNB2Password = '' - self.eNB2SourceCodePath = '' - #self.EPCSourceCodePath = '' - #self.EPCType = '' - #self.EPC_PcapFileName = '' self.ADBIPAddress = '' self.ADBUserName = '' self.ADBPassword = '' self.ADBCentralized = True self.testCase_id = '' self.testXMLfiles = [] - self.nbTestXMLfiles = 0 + #self.nbTestXMLfiles = 0 self.desc = '' - self.Build_eNB_args = '' - self.backgroundBuild = False - self.backgroundBuildTestId = ['', '', ''] - self.Build_eNB_forced_workspace_cleanup = False - self.Initialize_eNB_args = '' - self.air_interface = 'lte' - self.eNB_instance = '' - self.eNB_serverId = '' - self.eNBLogFiles = ['', '', ''] - self.eNBOptions = ['', '', ''] - self.eNBmbmsEnables = [False, False, False] - self.eNBstatuses = [-1, -1, -1] self.ping_args = '' self.ping_packetloss_threshold = '' self.iperf_args = '' @@ -156,8 +87,8 @@ class OaiCiTest(): self.CatMDevices = [] self.UEIPAddresses = [] self.htmlFile = '' - self.htmlHeaderCreated = False - self.htmlFooterCreated = False + # self.htmlHeaderCreated = False + # self.htmlFooterCreated = False self.htmlUEConnected = -1 self.htmleNBFailureMsg = '' self.htmlUEFailureMsg = '' @@ -167,9 +98,6 @@ class OaiCiTest(): self.x2NbENBs = 0 self.x2ENBBsIds = [] self.x2ENBConnectedUEs = [] - self.htmlTabRefs = [] - self.htmlTabNames = [] - self.htmlTabIcons = [] self.repeatCounts = [] self.finalStatus = False self.OsVersion = '' @@ -193,214 +121,24 @@ class OaiCiTest(): self.expectedNbOfConnectedUEs = 0 self.startTime = 0 - def BuildeNB(self): - if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - SSH.open(lIpAddr, lUserName, lPassWord) - # Check if we build an 5G-NR gNB or an LTE eNB - result = re.search('--gNB', self.Build_eNB_args) - if result is not None: - self.air_interface = 'nr' - else: - self.air_interface = 'lte' - # Worakround for some servers, we need to erase completely the workspace - if self.Build_eNB_forced_workspace_cleanup: - SSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) - # on RedHat/CentOS .git extension is mandatory - result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) - if result is not None: - full_ran_repo_name = self.ranRepository - else: - full_ran_repo_name = self.ranRepository + '.git' - SSH.command('mkdir -p ' + lSourcePath, '\$', 5) - SSH.command('cd ' + lSourcePath, '\$', 5) - SSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) - # Raphael: here add a check if git clone or git fetch went smoothly - SSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) - SSH.command('git config user.name "OAI Jenkins"', '\$', 5) - # Checking the BUILD INFO file - if not self.backgroundBuild: - SSH.command('ls *.txt', '\$', 5) - result = re.search('LAST_BUILD_INFO', SSH.getBefore()) - if result is not None: - mismatch = False - SSH.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) - result = re.search(self.ranCommitID, SSH.getBefore()) - if result is None: - mismatch = True - SSH.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): - result = re.search('YES', SSH.getBefore()) - if result is None: - mismatch = True - SSH.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - result = re.search('develop', SSH.getBefore()) - else: - result = re.search(self.ranTargetBranch, SSH.getBefore()) - if result is None: - mismatch = True - else: - result = re.search('NO', SSH.getBefore()) - if result is None: - mismatch = True - if not mismatch: - SSH.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - return - - SSH.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30) - # if the commit ID is provided use it to point to it - if self.ranCommitID != '': - SSH.command('git checkout -f ' + self.ranCommitID, '\$', 5) - # if the branch is not develop, then it is a merge request and we need to do - # the potential merge. Note that merge conflicts should already been checked earlier - if (self.ranAllowMerge): - if self.ranTargetBranch == '': - if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): - SSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) - else: - logging.debug('Merging with the target branch: ' + self.ranTargetBranch) - SSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) - SSH.command('source oaienv', '\$', 5) - SSH.command('cd cmake_targets', '\$', 5) - SSH.command('mkdir -p log', '\$', 5) - SSH.command('chmod 777 log', '\$', 5) - # no need to remove in log (git clean did the trick) - if self.backgroundBuild: - SSH.command('echo "./build_oai ' + self.Build_eNB_args + '" > ./my-lte-softmodem-build.sh', '\$', 5) - SSH.command('chmod 775 ./my-lte-softmodem-build.sh', '\$', 5) - SSH.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=build_enb_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ./my-lte-softmodem-build.sh', '\$', 5) - SSH.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - self.backgroundBuildTestId[int(self.eNB_instance)] = self.testCase_id - return - SSH.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee compile_oai_enb.log', 'Bypassing the Tests|build have failed', 1500) - self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.testCase_id) - - def WaitBuildeNBisFinished(self): - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - SSH.open(lIpAddr, lUserName, lPassWord) - count = 40 - buildOAIprocess = True - while (count > 0) and buildOAIprocess: - SSH.command('ps aux | grep --color=never build_ | grep -v grep', '\$', 3) - result = re.search('build_oai', SSH.getBefore()) - if result is None: - buildOAIprocess = False - else: - count -= 1 - time.sleep(30) - self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.backgroundBuildTestId[int(self.eNB_instance)]) - - def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId): - SSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 3) - SSH.command('ls ran_build/build', '\$', 3) - SSH.command('ls ran_build/build', '\$', 3) - if self.air_interface == 'nr': - nodeB_prefix = 'g' - else: - nodeB_prefix = 'e' - buildStatus = True - result = re.search(self.air_interface + '-softmodem', SSH.getBefore()) - if result is None: - buildStatus = False - else: - # Generating a BUILD INFO file - SSH.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) - SSH.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): - SSH.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - SSH.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - SSH.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - SSH.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) - SSH.command('mkdir -p build_log_' + testcaseId, '\$', 5) - SSH.command('mv log/* ' + 'build_log_' + testcaseId, '\$', 5) - SSH.command('mv compile_oai_enb.log ' + 'build_log_' + testcaseId, '\$', 5) - if self.eNB_serverId != '0': - SSH.command('cd cmake_targets', '\$', 5) - SSH.command('if [ -e tmp_build' + testcaseId + '.zip ]; then rm -f tmp_build' + testcaseId + '.zip; fi', '\$', 5) - SSH.command('zip -r -qq tmp_build' + testcaseId + '.zip build_log_' + testcaseId, '\$', 5) - SSH.close() - if (os.path.isfile('./tmp_build' + testcaseId + '.zip')): - os.remove('./tmp_build' + testcaseId + '.zip') - SSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/tmp_build' + testcaseId + '.zip', '.') - if (os.path.isfile('./tmp_build' + testcaseId + '.zip')): - SSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './tmp_build' + testcaseId + '.zip', self.eNBSourceCodePath + '/cmake_targets/.') - os.remove('./tmp_build' + testcaseId + '.zip') - SSH.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - SSH.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5) - SSH.command('unzip -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5) - SSH.command('rm -f tmp_build' + testcaseId + '.zip', '\$', 5) - SSH.close() - else: - SSH.close() - - if buildStatus: - logging.info('\u001B[1m Building OAI ' + nodeB_prefix + 'NB Pass\u001B[0m') - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) - else: - logging.error('\u001B[1m Building OAI ' + nodeB_prefix + 'NB Failed\u001B[0m') - self.CreateHtmlTestRow(self.Build_eNB_args, 'KO', ALL_PROCESSES_OK) - self.CreateHtmlTabFooter(False) - sys.exit(1) def BuildOAIUE(self): - if self.UEIPAddress == '' or self.ranRepository == '' or self.ranBranch == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': + if self.UEIPAddress == '' or RAN.GetranRepository() == '' or RAN.GetranBranch() == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': GenericHelp(Version) sys.exit('Insufficient Parameter') SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) result = re.search('--nrUE', self.Build_OAI_UE_args) if result is not None: - self.air_interface = 'nr' + RAN.Setair_interface('nr') ue_prefix = 'NR ' else: - self.air_interface = 'lte' + RAN.Setair_interface('lte') ue_prefix = '' - result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) + result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', RAN.GetranRepository()) if result is not None: - full_ran_repo_name = self.ranRepository + full_ran_repo_name = RAN.GetranRepository() else: - full_ran_repo_name = self.ranRepository + '.git' + full_ran_repo_name = RAN.GetranRepository() + '.git' SSH.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) SSH.command('cd ' + self.UESourceCodePath, '\$', 5) SSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) @@ -413,19 +151,19 @@ class OaiCiTest(): if result is not None: mismatch = False SSH.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) - result = re.search(self.ranCommitID, SSH.getBefore()) + result = re.search(RAN.GetranCommitID(), SSH.getBefore()) if result is None: mismatch = True SSH.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): + if (RAN.GetranAllowMerge()): result = re.search('YES', SSH.getBefore()) if result is None: mismatch = True SSH.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': + if RAN.GetranTargetBranch() == '': result = re.search('develop', SSH.getBefore()) else: - result = re.search(self.ranTargetBranch, SSH.getBefore()) + result = re.search(RAN.GetranTargetBranch(), SSH.getBefore()) if result is None: mismatch = True else: @@ -434,23 +172,23 @@ class OaiCiTest(): mismatch = True if not mismatch: SSH.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(RAN.GetBuild_eNB_args(), 'OK', CONST.ALL_PROCESSES_OK) return SSH.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30) # if the commit ID is provided use it to point to it - if self.ranCommitID != '': - SSH.command('git checkout -f ' + self.ranCommitID, '\$', 5) + if RAN.GetranCommitID() != '': + SSH.command('git checkout -f ' + RAN.GetranCommitID(), '\$', 5) # if the branch is not develop, then it is a merge request and we need to do # the potential merge. Note that merge conflicts should already been checked earlier - if (self.ranAllowMerge): - if self.ranTargetBranch == '': - if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): + if (RAN.GetranAllowMerge()): + if RAN.GetranTargetBranch() == '': + if (RAN.GetranBranch() != 'develop') and (RAN.GetranBranch() != 'origin/develop'): SSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) else: - logging.debug('Merging with the target branch: ' + self.ranTargetBranch) - SSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) + logging.debug('Merging with the target branch: ' + RAN.GetranTargetBranch()) + SSH.command('git merge --ff origin/' + RAN.GetranTargetBranch() + ' -m "Temporary merge for CI"', '\$', 5) SSH.command('source oaienv', '\$', 5) SSH.command('cd cmake_targets', '\$', 5) SSH.command('mkdir -p log', '\$', 5) @@ -460,7 +198,7 @@ class OaiCiTest(): SSH.command('ls ran_build/build', '\$', 3) SSH.command('ls ran_build/build', '\$', 3) buildStatus = True - result = re.search(self.air_interface + '-uesoftmodem', SSH.getBefore()) + result = re.search(RAN.Getair_interface() + '-uesoftmodem', SSH.getBefore()) if result is None: buildStatus = False SSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) @@ -468,23 +206,23 @@ class OaiCiTest(): SSH.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5) if buildStatus: # Generating a BUILD INFO file - SSH.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) - SSH.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if (self.ranAllowMerge): + SSH.command('echo "SRC_BRANCH: ' + RAN.GetranBranch() + '" > ../LAST_BUILD_INFO.txt', '\$', 2) + SSH.command('echo "SRC_COMMIT: ' + RAN.GetranCommitID() + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) + if (RAN.GetranAllowMerge()): SSH.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': + if RAN.GetranTargetBranch() == '': SSH.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) else: - SSH.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) + SSH.command('echo "TGT_BRANCH: ' + RAN.GetranTargetBranch() + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) else: SSH.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) SSH.close() - self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') + HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE') else: SSH.close() logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') - self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE') - self.CreateHtmlTabFooter(False) + HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', CONST.ALL_PROCESSES_OK, 'OAI UE') + HTML.CreateHtmlTabFooter(False) sys.exit(1) def CheckFlexranCtrlInstallation(self): @@ -495,6 +233,7 @@ class OaiCiTest(): result = re.search('/opt/flexran_rtc/build/rt_controller', SSH.getBefore()) if result is not None: self.flexranCtrlInstalled = True + RAN.SetflexranCtrlInstalled(True) logging.debug('Flexran Controller is installed') SSH.close() @@ -515,187 +254,10 @@ class OaiCiTest(): if result is not None: logging.debug('\u001B[1m Initialize FlexRan Controller Completed\u001B[0m') self.flexranCtrlStarted = True + RAN.SetflexranCtrlStarted(True) SSH.close() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - - def InitializeeNB(self): - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - check_eNB = False - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - self.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', pStatus) - self.CreateHtmlTabFooter(False) - sys.exit(1) - # If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep -v "lo|tun"', '\$', 5) - result = re.search('interfaceToUse=(?P<eth_interface>[a-zA-Z0-9\-\_]+)done', SSH.getBefore()) - if result is not None: - eth_interface = result.group('eth_interface') - logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m') - EPC.EPC_PcapFileName = 'enb_' + self.testCase_id + '_s1log.pcap' - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S rm -f /tmp/' + EPC.EPC_PcapFileName , '\$', 5) - SSH.command('echo $USER; nohup sudo tshark -f "host ' + lIpAddr +'" -i ' + eth_interface + ' -w /tmp/' + EPC.EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', EPC.GetUserName(), 5) - SSH.close() - SSH.open(lIpAddr, lUserName, lPassWord) - SSH.command('cd ' + lSourcePath, '\$', 5) - # Initialize_eNB_args usually start with -O and followed by the location in repository - full_config_file = self.Initialize_eNB_args.replace('-O ','') - extra_options = '' - extIdx = full_config_file.find('.conf') - if (extIdx > 0): - extra_options = full_config_file[extIdx + 5:] - # if tracer options is on, compiling and running T Tracer - result = re.search('T_stdout', str(extra_options)) - if result is not None: - logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m') - SSH.command('cd common/utils/T/tracer', '\$', 5) - SSH.command('make', '\$', 10) - SSH.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', lUserName, 5) - SSH.command('cd ' + lSourcePath, '\$', 5) - full_config_file = full_config_file[:extIdx + 5] - config_path, config_file = os.path.split(full_config_file) - else: - sys.exit('Insufficient Parameter') - ci_full_config_file = config_path + '/ci-' + config_file - rruCheck = False - result = re.search('^rru|^rcc|^du.band', str(config_file)) - if result is not None: - rruCheck = True - # do not reset board twice in IF4.5 case - result = re.search('^rru|^enb|^du.band', str(config_file)) - if result is not None: - SSH.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 60) - result = re.search('type: b200', SSH.getBefore()) - if result is not None: - logging.debug('Found a B2xx device --> resetting it') - SSH.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) - # Reloading FGPA bin firmware - SSH.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 60) - # Make a copy and adapt to EPC / eNB IP addresses - SSH.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) - SSH.command('sed -i -e \'s/CI_MME_IP_ADDR/' + EPC.GetIPAddress() + '/\' ' + ci_full_config_file, '\$', 2); - SSH.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2); - SSH.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2); - SSH.command('sed -i -e \'s/CI_RRU1_IP_ADDR/' + self.eNB1IPAddress + '/\' ' + ci_full_config_file, '\$', 2); - SSH.command('sed -i -e \'s/CI_RRU2_IP_ADDR/' + self.eNB2IPAddress + '/\' ' + ci_full_config_file, '\$', 2); - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - SSH.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "yes";/\' ' + ci_full_config_file, '\$', 2); - else: - SSH.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "no";/\' ' + ci_full_config_file, '\$', 2); - self.eNBmbmsEnables[int(self.eNB_instance)] = False - SSH.command('grep enable_enb_m2 ' + ci_full_config_file, '\$', 2); - result = re.search('yes', SSH.getBefore()) - if result is not None: - self.eNBmbmsEnables[int(self.eNB_instance)] = True - logging.debug('\u001B[1m MBMS is enabled on this eNB\u001B[0m') - result = re.search('noS1', str(self.Initialize_eNB_args)) - eNBinNoS1 = False - if result is not None: - eNBinNoS1 = True - logging.debug('\u001B[1m eNB is in noS1 configuration \u001B[0m') - # Launch eNB with the modified config file - SSH.command('source oaienv', '\$', 5) - SSH.command('cd cmake_targets', '\$', 5) - SSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface + '-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - SSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - SSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) - SSH.command('hostnamectl','\$', 5) - result = re.search('CentOS Linux 7', SSH.getBefore()) - if result is not None: - SSH.command('echo $USER; nohup sudo ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10) - else: - SSH.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log' - if extra_options != '': - self.eNBOptions[int(self.eNB_instance)] = extra_options - time.sleep(6) - doLoop = True - loopCounter = 20 - enbDidSync = False - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - # In case of T tracer recording, we may need to kill it - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - SSH.command('killall --signal SIGKILL record', '\$', 5) - SSH.close() - doLoop = False - logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m') - self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', ALL_PROCESSES_OK) - # In case of T tracer recording, we need to kill tshark on EPC side - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) - if EPC.EPC_PcapFileName != '': - time.sleep(0.5) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S chmod 666 /tmp/' + EPC.EPC_PcapFileName , '\$', 5) - SSH.close() - time.sleep(1) - if EPC.EPC_PcapFileName != '': - copyin_res = SSH.copyin(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), '/tmp/' + EPC.EPC_PcapFileName , '.') - if (copyin_res == 0): - SSH.copyout(lIpAddr, lUserName, lPassWord, EPC.EPC_PcapFileName , lSourcePath + '/cmake_targets/.') - self.prematureExit = True - return - else: - SSH.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting"', '\$', 4) - if rruCheck: - result = re.search('wait RUs', SSH.getBefore()) - else: - result = re.search('got sync|Starting F1AP at CU', SSH.getBefore()) - if result is None: - time.sleep(6) - else: - doLoop = False - enbDidSync = True - time.sleep(10) - - if enbDidSync and eNBinNoS1: - SSH.command('ifconfig oaitun_enb1', '\$', 4) - SSH.command('ifconfig oaitun_enb1', '\$', 4) - result = re.search('inet addr:1|inet 1', SSH.getBefore()) - if result is not None: - logging.debug('\u001B[1m oaitun_enb1 interface is mounted and configured\u001B[0m') - else: - logging.error('\u001B[1m oaitun_enb1 interface is either NOT mounted or NOT configured\u001B[0m') - if self.eNBmbmsEnables[int(self.eNB_instance)]: - SSH.command('ifconfig oaitun_enm1', '\$', 4) - result = re.search('inet addr', SSH.getBefore()) - if result is not None: - logging.debug('\u001B[1m oaitun_enm1 interface is mounted and configured\u001B[0m') - else: - logging.error('\u001B[1m oaitun_enm1 interface is either NOT mounted or NOT configured\u001B[0m') - if enbDidSync: - self.eNBstatuses[int(self.eNB_instance)] = int(self.eNB_serverId) - - SSH.close() - self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK) - logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') - + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + def InitializeUE_common(self, device_id, idx): try: SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) @@ -757,21 +319,21 @@ class OaiCiTest(): i += 1 for job in multi_jobs: job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) def InitializeOAIUE(self): if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': GenericHelp(Version) sys.exit('Insufficient Parameter') - if self.air_interface == 'lte': + if RAN.Getair_interface() == 'lte': result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) if result is None: check_eNB = True check_OAI_UE = False pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus) - self.CreateHtmlTabFooter(False) + HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus) + HTML.CreateHtmlTabFooter(False) sys.exit(1) UE_prefix = '' else: @@ -792,7 +354,7 @@ class OaiCiTest(): # Initialize_OAI_UE_args usually start with -C and followed by the location in repository SSH.command('source oaienv', '\$', 5) SSH.command('cd cmake_targets/ran_build/build', '\$', 5) - if self.air_interface == 'lte': + if RAN.Getair_interface() == 'lte': result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) # We may have to regenerate the .u* files if result is None: @@ -804,7 +366,7 @@ class OaiCiTest(): SSH.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5) SSH.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5) - SSH.command('echo "ulimit -c unlimited && ./'+ self.air_interface +'-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + SSH.command('echo "ulimit -c unlimited && ./'+ RAN.Getair_interface() +'-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) self.UELogFile = 'ue_' + self.testCase_id + '.log' @@ -835,7 +397,7 @@ class OaiCiTest(): doLoop = False continue SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) - if self.air_interface == 'nr': + if RAN.Getair_interface() == 'nr': result = re.search('Starting sync detection', SSH.getBefore()) else: result = re.search('got sync', SSH.getBefore()) @@ -852,7 +414,7 @@ class OaiCiTest(): SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT -r *-uesoftmodem', '\$', 4) time.sleep(3) continue - if self.air_interface == 'nr': + if RAN.Getair_interface() == 'nr': fullSyncStatus = True doOutterLoop = False else: @@ -885,7 +447,7 @@ class OaiCiTest(): if (outterLoopCounter == 0): doOutterLoop = False - if fullSyncStatus and gotSyncStatus and self.air_interface == 'lte': + if fullSyncStatus and gotSyncStatus and RAN.Getair_interface() == 'lte': result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) if result is None: SSH.command('ifconfig oaitun_ue1', '\$', 4) @@ -899,7 +461,7 @@ class OaiCiTest(): logging.debug(SSH.getBefore()) logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') tunnelInterfaceStatus = False - if self.eNBmbmsEnables[0]: + if RAN.GeteNBmbmsEnables[0]: self.command('ifconfig oaitun_uem1', '\$', 4) result = re.search('inet addr', SSH.getBefore()) if result is not None: @@ -915,23 +477,23 @@ class OaiCiTest(): SSH.close() if fullSyncStatus and gotSyncStatus and tunnelInterfaceStatus: - self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') + HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE') logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m') if (self.ADBIPAddress != 'none'): self.UEDevices = [] self.UEDevices.append('OAI-UE') self.UEDevicesStatus = [] - self.UEDevicesStatus.append(UE_STATUS_DETACHED) + self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) else: - if self.air_interface == 'lte': - if self.eNBmbmsEnables[0]: + if RAN.Getair_interface() == 'lte': + if RAN.GeteNBmbmsEnables[0]: self.htmlUEFailureMsg = 'oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured' else: self.htmlUEFailureMsg = 'oaitun_ue1 interface is either NOT mounted or NOT configured' - self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') + HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') else: self.htmlUEFailureMsg = 'nr-uesoftmodem did NOT synced' - self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE') + HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE') logging.error('\033[91mInitialize OAI UE Failed! \033[0m') self.AutoTerminateUEandeNB() @@ -961,6 +523,11 @@ class OaiCiTest(): # Calling twice AT to clear all buffers SSH.command('AT', 'OK|ERROR', 5) SSH.command('AT', 'OK', 5) + # Doing a power cycle + self.command('AT^RESET', 'SIMSTORE,READY', 15) + self.command('AT', 'OK|ERROR', 5) + self.command('AT', 'OK', 5) + self.command('ATE1', 'OK', 5) # Disabling the Radio SSH.command('AT+CFUN=0', 'OK', 5) logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') @@ -979,7 +546,7 @@ class OaiCiTest(): # Force closure of picocom but device might still be locked SSH.close() self.picocom_closure = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) self.checkDevTTYisUnlocked() def TerminateCatM(self): @@ -1000,7 +567,7 @@ class OaiCiTest(): logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') SSH.close() self.picocom_closure = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) self.checkDevTTYisUnlocked() def AttachCatM(self): @@ -1069,12 +636,12 @@ class OaiCiTest(): else: html_cell += '</pre>' html_queue.put(html_cell) - self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) + HTML.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) else: logging.error('\u001B[1m CAT-M module Attachment Failed\u001B[0m') html_cell = '<pre style="background-color:white">CAT-M module Attachment Failed</pre>' html_queue.put(html_cell) - self.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) + HTML.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) self.AutoTerminateUEandeNB() def PingCatM(self): @@ -1085,7 +652,7 @@ class OaiCiTest(): check_OAI_UE = False pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) self.AutoTerminateUEandeNB() return try: @@ -1096,8 +663,8 @@ class OaiCiTest(): SSH.command('cd scripts', '\$', 5) if re.match('OAI', EPC.GetType(), re.IGNORECASE): logging.debug('Using the OAI EPC HSS: not implemented yet') - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.CreateHtmlTabFooter(False) + HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + HTML.CreateHtmlTabFooter(False) sys.exit(1) else: SSH.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5) @@ -1105,7 +672,7 @@ class OaiCiTest(): if result is not None: moduleIPAddr = result.group('ipaddr') else: - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) self.AutoTerminateUEandeNB() return ping_time = re.findall("-c (\d+)",str(self.ping_args)) @@ -1167,9 +734,9 @@ class OaiCiTest(): html_cell = '<pre style="background-color:white">CAT-M module\nIP Address : ' + moduleIPAddr + '\n' + qMsg + '</pre>' statusQueue.put(html_cell) if (packetLossOK): - self.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue) + HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue) else: - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue) + HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue) self.AutoTerminateUEandeNB() except: os.kill(os.getppid(),signal.SIGUSR1) @@ -1193,6 +760,7 @@ class OaiCiTest(): SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep -m 1 mDataConnectionState', '\$', 15) else: SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep -m 1 mDataConnectionState', '\$', 60) + print('#GP: in SSH.getBefore() K=0 (it was K=2 in main.py)') result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', SSH.getBefore()) if result is None: logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') @@ -1251,7 +819,7 @@ class OaiCiTest(): check_OAI_UE = False pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) + HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) self.AutoTerminateUEandeNB() return multi_jobs = [] @@ -1260,7 +828,7 @@ class OaiCiTest(): nb_ue_to_connect = 0 for device_id in self.UEDevices: if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach): - self.UEDevicesStatus[nb_ue_to_connect] = UE_STATUS_ATTACHING + self.UEDevicesStatus[nb_ue_to_connect] = CONST.UE_STATUS_ATTACHING p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,)) p.daemon = True p.start() @@ -1270,7 +838,7 @@ class OaiCiTest(): job.join() if (status_queue.empty()): - self.CreateHtmlTestRow('N/A', 'KO', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) self.AutoTerminateUEandeNB() return else: @@ -1290,16 +858,16 @@ class OaiCiTest(): if (attach_status): cnt = 0 while cnt < len(self.UEDevices): - if self.UEDevicesStatus[cnt] == UE_STATUS_ATTACHING: - self.UEDevicesStatus[cnt] = UE_STATUS_ATTACHED + if self.UEDevicesStatus[cnt] == CONST.UE_STATUS_ATTACHING: + self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED cnt += 1 - self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - result = re.search('T_stdout', str(self.Initialize_eNB_args)) + HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) + result = re.search('T_stdout', str(RAN.GetInitialize_eNB_args())) if result is not None: logging.debug('Waiting 5 seconds to fill up record file') time.sleep(5) else: - self.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) self.AutoTerminateUEandeNB() def DetachUE_common(self, device_id, idx): @@ -1325,13 +893,13 @@ class OaiCiTest(): check_OAI_UE = False pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) + HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) self.AutoTerminateUEandeNB() return multi_jobs = [] cnt = 0 for device_id in self.UEDevices: - self.UEDevicesStatus[cnt] = UE_STATUS_DETACHING + self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHING p = Process(target = self.DetachUE_common, args = (device_id,cnt,)) p.daemon = True p.start() @@ -1339,14 +907,14 @@ class OaiCiTest(): cnt += 1 for job in multi_jobs: job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - result = re.search('T_stdout', str(self.Initialize_eNB_args)) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + result = re.search('T_stdout', str(RAN.GetInitialize_eNB_args())) if result is not None: logging.debug('Waiting 5 seconds to fill up record file') time.sleep(5) cnt = 0 while cnt < len(self.UEDevices): - self.UEDevicesStatus[cnt] = UE_STATUS_DETACHED + self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHED cnt += 1 def RebootUE_common(self, device_id): @@ -1396,8 +964,8 @@ class OaiCiTest(): check_OAI_UE = False pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.CreateHtmlTabFooter(False) + HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) + HTML.CreateHtmlTabFooter(False) sys.exit(1) multi_jobs = [] for device_id in self.UEDevices: @@ -1407,7 +975,7 @@ class OaiCiTest(): multi_jobs.append(p) for job in multi_jobs: job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) def DataDisableUE_common(self, device_id, idx): try: @@ -1436,7 +1004,7 @@ class OaiCiTest(): i += 1 for job in multi_jobs: job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) def DataEnableUE_common(self, device_id, idx): try: @@ -1465,7 +1033,7 @@ class OaiCiTest(): i += 1 for job in multi_jobs: job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) def GetAllUEDevices(self, terminate_ue_flag): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': @@ -1501,14 +1069,16 @@ class OaiCiTest(): self.UEDevicesRebootCmd.append(comma_split[5]) phone_list_file.close() - if terminate_ue_flag == False: + if terminate_ue_flag == True: + print('terminate_ue_flag == True') if len(self.UEDevices) == 0: logging.debug('\u001B[1;37;41m UE Not Found! \u001B[0m') sys.exit(1) if len(self.UEDevicesStatus) == 0: + print('len(self.UEDevicesStatus) == 0') cnt = 0 while cnt < len(self.UEDevices): - self.UEDevicesStatus.append(UE_STATUS_DETACHED) + self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) cnt += 1 def GetAllCatMDevices(self, terminate_ue_flag): @@ -1528,7 +1098,7 @@ class OaiCiTest(): SSH.close() if result is not None: logging.debug('Found a module list file on ADB server') - if terminate_ue_flag == False: + if terminate_ue_flag == True: if len(self.CatMDevices) == 0: logging.debug('\u001B[1;37;41m CAT-M UE Not Found! \u001B[0m') sys.exit(1) @@ -1591,8 +1161,8 @@ class OaiCiTest(): check_OAI_UE = False pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.CreateHtmlTabFooter(False) + HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) + HTML.CreateHtmlTabFooter(False) sys.exit(1) multi_jobs = [] lock = Lock() @@ -1628,7 +1198,7 @@ class OaiCiTest(): htmlOptions = 'N/A' if (status_queue.empty()): - self.CreateHtmlTestRow(htmlOptions, 'KO', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(htmlOptions, 'KO', CONST.ALL_PROCESSES_OK) self.AutoTerminateUEandeNB() else: check_status = True @@ -1642,9 +1212,9 @@ class OaiCiTest(): html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>' html_queue.put(html_cell) if check_status and passStatus: - self.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue) else: - self.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue) self.AutoTerminateUEandeNB() def GetAllUEIPAddresses(self): @@ -1675,7 +1245,8 @@ class OaiCiTest(): SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) idx = 0 for device_id in self.UEDevices: - if self.UEDevicesStatus[idx] != UE_STATUS_ATTACHED: + print('UE status attched'+CONST.UE_STATUS_ATTACHED) + if self.UEDevicesStatus[idx] != CONST.UE_STATUS_ATTACHED: idx += 1 continue count = 0 @@ -1804,19 +1375,19 @@ class OaiCiTest(): html_queue = SimpleQueue() html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>' html_queue.put(html_cell) - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) def PingNoS1(self): check_eNB = True check_OAI_UE = True pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) self.AutoTerminateUEandeNB() return ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) if ping_from_eNB is not None: - if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '': + if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '': GenericHelp(Version) sys.exit('Insufficient Parameter') else: @@ -1825,8 +1396,8 @@ class OaiCiTest(): sys.exit('Insufficient Parameter') try: if ping_from_eNB is not None: - SSH.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - SSH.command('cd ' + self.eNBSourceCodePath + '/cmake_targets/', '\$', 5) + SSH.open(RAN.GeteNBIPAddress, RAN.GeteNBUserName, RAN.GeteNBPassword) + SSH.command('cd ' + RAN.GeteNBSourceCodePath() + '/cmake_targets/', '\$', 5) else: SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5) @@ -1884,13 +1455,13 @@ class OaiCiTest(): html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>' html_queue.put(html_cell) if packetLossOK: - self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) else: - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) # copying on the EPC server for logCollection if ping_from_eNB is not None: - copyin_res = SSH.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') + copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') else: copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') if (copyin_res == 0): @@ -1899,7 +1470,7 @@ class OaiCiTest(): os.kill(os.getppid(),signal.SIGUSR1) def Ping(self): - result = re.search('noS1', str(self.Initialize_eNB_args)) + result = re.search('noS1', str(RAN.GetInitialize_eNB_args())) if result is not None: self.PingNoS1() return @@ -1913,12 +1484,12 @@ class OaiCiTest(): check_OAI_UE = False pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) self.AutoTerminateUEandeNB() return ueIpStatus = self.GetAllUEIPAddresses() if (ueIpStatus < 0): - self.CreateHtmlTestRow(self.ping_args, 'KO', UE_IP_ADDRESS_ISSUE) + HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE) self.AutoTerminateUEandeNB() return multi_jobs = [] @@ -1936,7 +1507,7 @@ class OaiCiTest(): job.join() if (status_queue.empty()): - self.CreateHtmlTestRow(self.ping_args, 'KO', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.ALL_PROCESSES_OK) self.AutoTerminateUEandeNB() else: ping_status = True @@ -1951,9 +1522,9 @@ class OaiCiTest(): html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' html_queue.put(html_cell) if (ping_status): - self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) else: - self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) self.AutoTerminateUEandeNB() def Iperf_ComputeTime(self): @@ -2342,6 +1913,7 @@ class OaiCiTest(): def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): try: + logging.debug('entring Iperf_common') # Single-UE profile -- iperf only on one UE if self.iperf_profile == 'single-ue' and idx != 0: return @@ -2352,7 +1924,7 @@ class OaiCiTest(): if (device_id != 'OAI-UE'): SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it - SSH.command('if [ ! -d ' + EPC.GetSourceCodePath() + '/scripts ]; then mkdir -p ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) + SSH.command('if [ ! -d ' + EPC.GetSourceCodePath() + '/scripts ]; then mkdir -p ' + EPC.GetSourceCodePath() + '/scripts ; fi', '\$', 5) SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) # Checking if iperf / iperf3 are installed if self.ADBCentralized: @@ -2514,6 +2086,9 @@ class OaiCiTest(): else: SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.GetSourceCodePath() + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') SSH.command('fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + # fromdos has to be called on the python executor not on ADB server + cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log' + subprocess.run(cmd, shell=True) self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) # in case of OAI UE: @@ -2528,21 +2103,21 @@ class OaiCiTest(): os.kill(os.getppid(),signal.SIGUSR1) def IperfNoS1(self): - if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': + if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': GenericHelp(Version) sys.exit('Insufficient Parameter') check_eNB = True check_OAI_UE = True pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) + HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) self.AutoTerminateUEandeNB() return server_on_enb = re.search('-R', str(self.iperf_args)) if server_on_enb is not None: - iServerIPAddr = self.eNBIPAddress - iServerUser = self.eNBUserName - iServerPasswd = self.eNBPassword + iServerIPAddr = RAN.GeteNBIPAddress() + iServerUser = RAN.GeteNBUserName() + iServerPasswd = RAN.GeteNBPassword() iClientIPAddr = self.UEIPAddress iClientUser = self.UEUserName iClientPasswd = self.UEPassword @@ -2550,9 +2125,9 @@ class OaiCiTest(): iServerIPAddr = self.UEIPAddress iServerUser = self.UEUserName iServerPasswd = self.UEPassword - iClientIPAddr = self.eNBIPAddress - iClientUser = self.eNBUserName - iClientPasswd = self.eNBPassword + iClientIPAddr = RAN.GeteNBIPAddress() + iClientUser = RAN.GeteNBUserName() + iClientPasswd = RAN.GeteNBPassword() if self.iperf_options != 'sink': # Starting the iperf server SSH.open(iServerIPAddr, iServerUser, iServerPasswd) @@ -2629,15 +2204,15 @@ class OaiCiTest(): html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' html_queue.put(html_cell) if (iperf_noperf and iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) elif (iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) else: - self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) self.AutoTerminateUEandeNB() def Iperf(self): - result = re.search('noS1', str(self.Initialize_eNB_args)) + result = re.search('noS1', str(RAN.GetInitialize_eNB_args())) if result is not None: self.IperfNoS1() return @@ -2651,12 +2226,13 @@ class OaiCiTest(): check_OAI_UE = False pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) + HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) self.AutoTerminateUEandeNB() return ueIpStatus = self.GetAllUEIPAddresses() if (ueIpStatus < 0): - self.CreateHtmlTestRow(self.iperf_args, 'KO', UE_IP_ADDRESS_ISSUE) + logging.debug('going here') + HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE) self.AutoTerminateUEandeNB() return @@ -2676,9 +2252,10 @@ class OaiCiTest(): ue_num = len(self.UEIPAddresses) lock = Lock() status_queue = SimpleQueue() + logging.debug('ue_num = ' + str(ue_num)) for UE_IPAddress in self.UEIPAddresses: device_id = self.UEDevices[i] - p = Process(target = CiTestObj.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,)) + p = Process(target = self.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,)) p.daemon = True p.start() multi_jobs.append(p) @@ -2687,7 +2264,7 @@ class OaiCiTest(): job.join() if (status_queue.empty()): - self.CreateHtmlTestRow(self.iperf_args, 'KO', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK) self.AutoTerminateUEandeNB() else: iperf_status = True @@ -2705,11 +2282,11 @@ class OaiCiTest(): html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' html_queue.put(html_cell) if (iperf_noperf and iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) elif (iperf_status): - self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) else: - self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) self.AutoTerminateUEandeNB() def CheckProcessExist(self, check_eNB, check_OAI_UE): @@ -2717,7 +2294,7 @@ class OaiCiTest(): status_queue = SimpleQueue() # in noS1 config, no need to check status from EPC # in gNB also currently no need to check - result = re.search('noS1|band78', str(self.Initialize_eNB_args)) + result = re.search('noS1|band78', str(RAN.GetInitialize_eNB_args())) if result is None: p = Process(target = EPC.CheckHSSProcess, args = (status_queue,)) p.daemon = True @@ -2735,12 +2312,12 @@ class OaiCiTest(): if (check_eNB == False) and (check_OAI_UE == False): return 0 if check_eNB: - p = Process(target = CiTestObj.CheckeNBProcess, args = (status_queue,)) + p = Process(target = RAN.CheckeNBProcess, args = (status_queue,)) p.daemon = True p.start() multi_jobs.append(p) if check_OAI_UE: - p = Process(target = CiTestObj.CheckOAIUEProcess, args = (status_queue,)) + p = Process(target = self.CheckOAIUEProcess, args = (status_queue,)) p.daemon = True p.start() multi_jobs.append(p) @@ -2755,14 +2332,14 @@ class OaiCiTest(): status = status_queue.get() if (status < 0): result = status - if result == ENB_PROCESS_FAILED: - fileCheck = re.search('enb_', str(self.eNBLogFiles[0])) + if result == CONST.ENB_PROCESS_FAILED: + fileCheck = re.search('enb_', str(RAN.GeteNBLogFiles[0])) if fileCheck is not None: - SSH.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFiles[0], '.') - logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFiles[0]) + SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/' + RAN.GeteNBLogFiles[0], '.') + logStatus = self.AnalyzeLogFile_eNB(RAN.GeteNBLogFiles[0]) if logStatus < 0: result = logStatus - self.eNBLogFiles[0] = '' + RAN.SeteNBLogFiles[0] = '' if self.flexranCtrlInstalled and self.flexranCtrlStarted: self.TerminateFlexranCtrl() return result @@ -2771,7 +2348,7 @@ class OaiCiTest(): multi_jobs = [] status_queue = SimpleQueue() if initialize_OAI_UE_flag == False: - p = Process(target = CiTestObj.CheckOAIUEProcess, args = (status_queue,)) + p = Process(target = self.CheckOAIUEProcess, args = (status_queue,)) p.daemon = True p.start() multi_jobs.append(p) @@ -2786,7 +2363,7 @@ class OaiCiTest(): status = status_queue.get() if (status < 0): result = status - if result == OAI_UE_PROCESS_FAILED: + if result == CONST.OAI_UE_PROCESS_FAILED: fileCheck = re.search('ue_', str(self.UELogFile)) if fileCheck is not None: SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') @@ -2798,303 +2375,20 @@ class OaiCiTest(): def CheckOAIUEProcess(self, status_queue): try: SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + '-uesoftmodem | grep -v grep', '\$', 5) - result = re.search(self.air_interface + '-uesoftmodem', SSH.getBefore()) + SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + RAN.Getair_interface() + '-uesoftmodem | grep -v grep', '\$', 5) + result = re.search(RAN.Getair_interface() + '-uesoftmodem', SSH.getBefore()) if result is None: logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m') - status_queue.put(OAI_UE_PROCESS_FAILED) + status_queue.put(CONST.OAI_UE_PROCESS_FAILED) else: - status_queue.put(OAI_UE_PROCESS_OK) + status_queue.put(CONST.OAI_UE_PROCESS_OK) SSH.close() except: os.kill(os.getppid(),signal.SIGUSR1) - def CheckeNBProcess(self, status_queue): - try: - # At least the instance 0 SHALL be on! - if self.eNBstatuses[0] == 0: - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - elif self.eNBstatuses[0] == 1: - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - elif self.eNBstatuses[0] == 2: - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - else: - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - SSH.open(lIpAddr, lUserName, lPassWord) - SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + '-softmodem | grep -v grep', '\$', 5) - result = re.search(self.air_interface + '-softmodem', SSH.getBefore()) - if result is None: - logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m') - status_queue.put(ENB_PROCESS_FAILED) - else: - status_queue.put(ENB_PROCESS_OK) - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AnalyzeLogFile_eNB(self, eNBlogFile): - if (not os.path.isfile('./' + eNBlogFile)): - return -1 - enb_log_file = open('./' + eNBlogFile, 'r') - exitSignalReceived = False - foundAssertion = False - msgAssertion = '' - msgLine = 0 - foundSegFault = False - foundRealTimeIssue = False - rrcSetupComplete = 0 - rrcReleaseRequest = 0 - rrcReconfigRequest = 0 - rrcReconfigComplete = 0 - rrcReestablishRequest = 0 - rrcReestablishComplete = 0 - rrcReestablishReject = 0 - rlcDiscardBuffer = 0 - rachCanceledProcedure = 0 - uciStatMsgCount = 0 - pdcpFailure = 0 - ulschFailure = 0 - cdrxActivationMessageCount = 0 - dropNotEnoughRBs = 0 - mbmsRequestMsg = 0 - self.htmleNBFailureMsg = '' - isRRU = False - isSlave = False - slaveReceivesFrameResyncCmd = False - X2HO_state = X2_HO_REQ_STATE__IDLE - X2HO_inNbProcedures = 0 - X2HO_outNbProcedures = 0 - for line in enb_log_file.readlines(): - if X2HO_state == X2_HO_REQ_STATE__IDLE: - result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__TARGET_RECEIVES_REQ - result = re.search('source eNB receives the X2 HO ACK X2AP_HANDOVER_REQ_ACK', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK - if X2HO_state == X2_HO_REQ_STATE__TARGET_RECEIVES_REQ: - result = re.search('Received LTE_RRCConnectionReconfigurationComplete from UE', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE - if X2HO_state == X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE: - result = re.search('issue rrc_eNB_send_PATH_SWITCH_REQ', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ - if X2HO_state == X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ: - result = re.search('received path switch ack S1AP_PATH_SWITCH_REQ_ACK', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__IDLE - X2HO_inNbProcedures += 1 - if X2HO_state == X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK: - result = re.search('source eNB receives the X2 UE CONTEXT RELEASE X2AP_UE_CONTEXT_RELEASE', str(line)) - if result is not None: - X2HO_state = X2_HO_REQ_STATE__IDLE - X2HO_outNbProcedures += 1 - - if self.eNBOptions[int(self.eNB_instance)] != '': - res1 = re.search('max_rxgain (?P<requested_option>[0-9]+)', self.eNBOptions[int(self.eNB_instance)]) - res2 = re.search('max_rxgain (?P<applied_option>[0-9]+)', str(line)) - if res1 is not None and res2 is not None: - requested_option = int(res1.group('requested_option')) - applied_option = int(res2.group('applied_option')) - if requested_option == applied_option: - self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ok-circle"></span> Command line option(s) correctly applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n' - else: - self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ban-circle"></span> Command line option(s) NOT applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n' - result = re.search('Exiting OAI softmodem', str(line)) - if result is not None: - exitSignalReceived = True - result = re.search('[Ss]egmentation [Ff]ault', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('./ran_build/build/lte-softmodem', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Aa]ssertion', str(line)) - if result is not None and not exitSignalReceived: - foundAssertion = True - result = re.search('LLL', str(line)) - if result is not None and not exitSignalReceived: - foundRealTimeIssue = True - if foundAssertion and (msgLine < 3): - msgLine += 1 - msgAssertion += str(line) - result = re.search('Setting function for RU', str(line)) - if result is not None: - isRRU = True - if isRRU: - result = re.search('RU 0 is_slave=yes', str(line)) - if result is not None: - isSlave = True - if isSlave: - result = re.search('Received RRU_frame_resynch command', str(line)) - if result is not None: - slaveReceivesFrameResyncCmd = True - result = re.search('LTE_RRCConnectionSetupComplete from UE', str(line)) - if result is not None: - rrcSetupComplete += 1 - result = re.search('Generate LTE_RRCConnectionRelease|Generate RRCConnectionRelease', str(line)) - if result is not None: - rrcReleaseRequest += 1 - result = re.search('Generate LTE_RRCConnectionReconfiguration', str(line)) - if result is not None: - rrcReconfigRequest += 1 - result = re.search('LTE_RRCConnectionReconfigurationComplete from UE rnti', str(line)) - if result is not None: - rrcReconfigComplete += 1 - result = re.search('LTE_RRCConnectionReestablishmentRequest', str(line)) - if result is not None: - rrcReestablishRequest += 1 - result = re.search('LTE_RRCConnectionReestablishmentComplete', str(line)) - if result is not None: - rrcReestablishComplete += 1 - result = re.search('LTE_RRCConnectionReestablishmentReject', str(line)) - if result is not None: - rrcReestablishReject += 1 - result = re.search('CDRX configuration activated after RRC Connection', str(line)) - if result is not None: - cdrxActivationMessageCount += 1 - result = re.search('uci->stat', str(line)) - if result is not None: - uciStatMsgCount += 1 - result = re.search('PDCP.*Out of Resources.*reason', str(line)) - if result is not None: - pdcpFailure += 1 - result = re.search('ULSCH in error in round', str(line)) - if result is not None: - ulschFailure += 1 - result = re.search('BAD all_segments_received', str(line)) - if result is not None: - rlcDiscardBuffer += 1 - result = re.search('Canceled RA procedure for UE rnti', str(line)) - if result is not None: - rachCanceledProcedure += 1 - result = re.search('dropping, not enough RBs', str(line)) - if result is not None: - dropNotEnoughRBs += 1 - if self.eNBmbmsEnables[int(self.eNB_instance)]: - result = re.search('MBMS USER-PLANE.*Requesting.*bytes from RLC', str(line)) - if result is not None: - mbmsRequestMsg += 1 - enb_log_file.close() - logging.debug(' File analysis completed') - self.htmleNBFailureMsg = '' - if self.air_interface == 'lte': - nodeB_prefix = 'e' - else: - nodeB_prefix = 'g' - if uciStatMsgCount > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if pdcpFailure > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(pdcpFailure) + ' "PDCP Out of Resources" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if ulschFailure > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if dropNotEnoughRBs > 0: - statMsg = 'eNB showed ' + str(dropNotEnoughRBs) + ' "dropping, not enough RBs" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmleNBFailureMsg += statMsg + '\n' - if rrcSetupComplete > 0: - rrcMsg = nodeB_prefix + 'NB completed ' + str(rrcSetupComplete) + ' RRC Connection Setup(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcSetupComplete) + ' were completed' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rrcReleaseRequest > 0: - rrcMsg = nodeB_prefix + 'NB requested ' + str(rrcReleaseRequest) + ' RRC Connection Release(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rrcReconfigRequest > 0 or rrcReconfigComplete > 0: - rrcMsg = nodeB_prefix + 'NB requested ' + str(rrcReconfigRequest) + ' RRC Connection Reconfiguration(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReconfigComplete) + ' were completed' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rrcReestablishRequest > 0 or rrcReestablishComplete > 0 or rrcReestablishReject > 0: - rrcMsg = nodeB_prefix + 'NB requested ' + str(rrcReestablishRequest) + ' RRC Connection Reestablishment(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReestablishComplete) + ' were completed' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if self.eNBmbmsEnables[int(self.eNB_instance)]: - if mbmsRequestMsg > 0: - rrcMsg = 'eNB requested ' + str(mbmsRequestMsg) + ' times the RLC for MBMS USER-PLANE' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if X2HO_inNbProcedures > 0: - rrcMsg = 'eNB completed ' + str(X2HO_inNbProcedures) + ' X2 Handover Connection procedure(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if X2HO_outNbProcedures > 0: - rrcMsg = 'eNB completed ' + str(X2HO_outNbProcedures) + ' X2 Handover Release procedure(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if self.eNBOptions[int(self.eNB_instance)] != '': - res1 = re.search('drx_Config_present prSetup', self.eNBOptions[int(self.eNB_instance)]) - if res1 is not None: - if cdrxActivationMessageCount > 0: - rrcMsg = 'eNB activated the CDRX Configuration for ' + str(cdrxActivationMessageCount) + ' time(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - else: - rrcMsg = 'eNB did NOT ACTIVATE the CDRX Configuration' - logging.debug('\u001B[1;37;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - if rachCanceledProcedure > 0: - rachMsg = nodeB_prefix + 'NB cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)' - logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rachMsg + '\n' - if isRRU: - if isSlave: - if slaveReceivesFrameResyncCmd: - rruMsg = 'Slave RRU received the RRU_frame_resynch command from RAU' - logging.debug('\u001B[1;30;43m ' + rruMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rruMsg + '\n' - else: - rruMsg = 'Slave RRU DID NOT receive the RRU_frame_resynch command from RAU' - logging.debug('\u001B[1;37;41m ' + rruMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rruMsg + '\n' - self.prematureExit = True - return ENB_PROCESS_SLAVE_RRU_NOT_SYNCED - if foundSegFault: - logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with a Segmentation Fault! \u001B[0m') - return ENB_PROCESS_SEG_FAULT - if foundAssertion: - logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with an assertion! \u001B[0m') - self.htmleNBFailureMsg += msgAssertion - return ENB_PROCESS_ASSERTION - if foundRealTimeIssue: - logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB faced real time issues! \u001B[0m') - self.htmleNBFailureMsg += nodeB_prefix + 'NB faced real time issues!\n' - #return ENB_PROCESS_REALTIME_ISSUE - if rlcDiscardBuffer > 0: - rlcMsg = nodeB_prefix + 'NB RLC discarded ' + str(rlcDiscardBuffer) + ' buffer(s)' - logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rlcMsg + '\n' - return ENB_PROCESS_REALTIME_ISSUE - return 0 + +# def AnalyzeLogFile_eNB(self, eNBlogFile): +# ... def AnalyzeLogFile_UE(self, UElogFile): if (not os.path.isfile('./' + UElogFile)): @@ -3183,7 +2477,7 @@ class OaiCiTest(): result = re.search('No cell synchronization found, abandoning', str(line)) if result is not None: no_cell_sync_found = True - if self.eNBmbmsEnables[0]: + if RAN.GeteNBmbmsEnables[0]: result = re.search('TRIED TO PUSH MBMS DATA', str(line)) if result is not None: mbms_messages += 1 @@ -3309,7 +2603,7 @@ class OaiCiTest(): statMsg = 'UE showed ' + str(fatalErrorCount) + ' "MAC BSR Triggered ReTxBSR Timer expiry" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') self.htmlUEFailureMsg += statMsg + '\n' - if self.eNBmbmsEnables[0]: + if RAN.GeteNBmbmsEnables[0]: if mbms_messages > 0: statMsg = 'UE showed ' + str(mbms_messages) + ' "TRIED TO PUSH MBMS DATA" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') @@ -3320,130 +2614,34 @@ class OaiCiTest(): if foundSegFault: logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') if not nrUEFlag: - return OAI_UE_PROCESS_SEG_FAULT + return CONST.OAI_UE_PROCESS_SEG_FAULT else: if not frequency_found: - return OAI_UE_PROCESS_SEG_FAULT + return CONST.OAI_UE_PROCESS_SEG_FAULT if foundAssertion: logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m') self.htmlUEFailureMsg += 'UE showed an assertion!\n' if not nrUEFlag: if not mib_found or not frequency_found: - return OAI_UE_PROCESS_ASSERTION + return CONST.OAI_UE_PROCESS_ASSERTION else: if not frequency_found: - return OAI_UE_PROCESS_ASSERTION + return CONST.OAI_UE_PROCESS_ASSERTION if foundRealTimeIssue: logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m') self.htmlUEFailureMsg += 'UE faced real time issues!\n' - #return ENB_PROCESS_REALTIME_ISSUE + #return CONST.ENB_PROCESS_REALTIME_ISSUE if nrUEFlag: if not frequency_found: - return OAI_UE_PROCESS_COULD_NOT_SYNC + return CONST.OAI_UE_PROCESS_COULD_NOT_SYNC else: if no_cell_sync_found and not mib_found: logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m') self.htmlUEFailureMsg += 'UE could not synchronize!\n' - return OAI_UE_PROCESS_COULD_NOT_SYNC + return CONST.OAI_UE_PROCESS_COULD_NOT_SYNC return 0 - def TerminateeNB(self): - if self.eNB_serverId == '0': - lIpAddr = self.eNBIPAddress - lUserName = self.eNBUserName - lPassWord = self.eNBPassword - lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': - lIpAddr = self.eNB1IPAddress - lUserName = self.eNB1UserName - lPassWord = self.eNB1Password - lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': - lIpAddr = self.eNB2IPAddress - lUserName = self.eNB2UserName - lPassWord = self.eNB2Password - lSourcePath = self.eNB2SourceCodePath - if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - SSH.open(lIpAddr, lUserName, lPassWord) - SSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) - if self.air_interface == 'lte': - nodeB_prefix = 'e' - else: - nodeB_prefix = 'g' - SSH.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('-softmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) - SSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem || true', '\$', 5) - time.sleep(10) - SSH.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('-softmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem || true', '\$', 5) - time.sleep(5) - SSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - SSH.close() - # If tracer options is on, stopping tshark on EPC side - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if result is not None: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) - time.sleep(1) - if EPC.EPC_PcapFileName != '': - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S chmod 666 /tmp/' + EPC.EPC_PcapFileName , '\$', 5) - SSH.copyin(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), '/tmp/' + EPC.EPC_PcapFileName , '.') - SSH.copyout(lIpAddr, lUserName, lPassWord, EPC.EPC_PcapFileName , lSourcePath + '/cmake_targets/.') - SSH.close() - logging.debug('\u001B[1m Replaying RAW record file\u001B[0m') - SSH.open(lIpAddr, lUserName, lPassWord) - SSH.command('cd ' + lSourcePath + '/common/utils/T/tracer/', '\$', 5) - enbLogFile = self.eNBLogFiles[int(self.eNB_instance)] - raw_record_file = enbLogFile.replace('.log', '_record.raw') - replay_log_file = enbLogFile.replace('.log', '_replay.log') - extracted_txt_file = enbLogFile.replace('.log', '_extracted_messages.txt') - extracted_log_file = enbLogFile.replace('.log', '_extracted_messages.log') - SSH.command('./extract_config -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + extracted_txt_file, '\$', 5) - SSH.command('echo $USER; nohup ./replay -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', lUserName, 5) - SSH.command('./textlog -d ' + lSourcePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + lSourcePath + '/cmake_targets/' + extracted_log_file, '\$', 5) - SSH.close() - SSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + extracted_log_file, '.') - logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m') - logStatus = self.AnalyzeLogFile_eNB(extracted_log_file) - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.eNBLogFiles[int(self.eNB_instance)] = '' - else: - analyzeFile = False - if self.eNBLogFiles[int(self.eNB_instance)] != '': - analyzeFile = True - fileToAnalyze = self.eNBLogFiles[int(self.eNB_instance)] - self.eNBLogFiles[int(self.eNB_instance)] = '' - if analyzeFile: - copyin_res = SSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + fileToAnalyze, '.') - if (copyin_res == -1): - logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m') - self.htmleNBFailureMsg = 'Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!' - self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE) - self.eNBmbmsEnables[int(self.eNB_instance)] = False - return - if self.eNB_serverId != '0': - SSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/') - logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + fileToAnalyze) - logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze) - if (logStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', logStatus) - self.preamtureExit = True - self.eNBmbmsEnables[int(self.eNB_instance)] = False - return - else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.eNBmbmsEnables[int(self.eNB_instance)] = False - self.eNBstatuses[int(self.eNB_instance)] = -1 - + def TerminateFlexranCtrl(self): if self.flexranCtrlInstalled == False or self.flexranCtrlStarted == False: return @@ -3457,7 +2655,7 @@ class OaiCiTest(): time.sleep(1) SSH.close() self.flexranCtrlStarted = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) def TerminateUE_common(self, device_id, idx): try: @@ -3488,19 +2686,19 @@ class OaiCiTest(): os.kill(os.getppid(),signal.SIGUSR1) def TerminateUE(self): - terminate_ue_flag = True + terminate_ue_flag = False self.GetAllUEDevices(terminate_ue_flag) multi_jobs = [] i = 0 for device_id in self.UEDevices: - p = Process(target= CiTestObj.TerminateUE_common, args = (device_id,i,)) + p = Process(target= self.TerminateUE_common, args = (device_id,i,)) p.daemon = True p.start() multi_jobs.append(p) i += 1 for job in multi_jobs: job.join() - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) def TerminateOAIUE(self): SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) @@ -3523,7 +2721,7 @@ class OaiCiTest(): if (copyin_res == -1): logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m') self.htmlUEFailureMsg = 'Could not copy UE logfile to analyze it!' - self.CreateHtmlTestRow('N/A', 'KO', OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE') + HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE') self.UELogFile = '' return logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m') @@ -3536,52 +2734,56 @@ class OaiCiTest(): if (logStatus < 0): logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') self.htmlUEFailureMsg = '<b>' + ueAction + ' Failed</b>\n' + self.htmlUEFailureMsg - self.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') - if self.air_interface == 'lte': + HTML.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') + if RAN.Getair_interface() == 'lte': # In case of sniffing on commercial eNBs we have random results # Not an error then - if (logStatus != OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): + if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): self.Initialize_OAI_UE_args = '' self.AutoTerminateUEandeNB() else: - if (logStatus == OAI_UE_PROCESS_COULD_NOT_SYNC): + if (logStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC): self.Initialize_OAI_UE_args = '' self.AutoTerminateUEandeNB() else: logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') self.htmlUEFailureMsg = '<b>' + ueAction + ' Completed</b>\n' + self.htmlUEFailureMsg - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) self.UELogFile = '' else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) def AutoTerminateUEandeNB(self): if (self.ADBIPAddress != 'none'): self.testCase_id = 'AUTO-KILL-UE' + RAN.SettestCase_id(self.testCase_id) self.desc = 'Automatic Termination of UE' self.ShowTestID() self.TerminateUE() if (self.Initialize_OAI_UE_args != ''): self.testCase_id = 'AUTO-KILL-UE' + RAN.SettestCase_id(self.testCase_id) self.desc = 'Automatic Termination of UE' self.ShowTestID() self.TerminateOAIUE() - if (self.Initialize_eNB_args != ''): + if (RAN.GetInitialize_eNB_args() != ''): self.testCase_id = 'AUTO-KILL-eNB' + RAN.SettestCase_id(self.testCase_id) self.desc = 'Automatic Termination of eNB' self.ShowTestID() - self.eNB_instance = '0' - self.TerminateeNB() + RAN.SeteNB_instance('0') + RAN.TerminateeNB() if self.flexranCtrlInstalled and self.flexranCtrlStarted: self.testCase_id = 'AUTO-KILL-flexran-ctl' + RAN.SettestCase_id(self.testCase_id) self.desc = 'Automatic Termination of FlexRan CTL' self.ShowTestID() self.TerminateFlexranCtrl() - self.prematureExit = True + RAN.SetprematureExit(True) def IdleSleep(self): time.sleep(self.idle_sleep_time) - self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', CONST.ALL_PROCESSES_OK) def X2_Status(self, idx, fileName): cmd = "curl --silent http://" + EPC.GetIPAddress() + ":9999/stats | jq '.' > " + fileName @@ -3683,22 +2885,22 @@ class OaiCiTest(): logging.debug(msg) fullMessage += msg + '</pre>' html_queue.put(fullMessage) - self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) else: msg = "X2 Handover FAILED" logging.error(msg) fullMessage += msg + '</pre>' html_queue.put(fullMessage) - self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) + HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) else: - self.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', CONST.ALL_PROCESSES_OK) def LogCollectBuild(self): - if (self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != ''): - IPAddress = self.eNBIPAddress - UserName = self.eNBUserName - Password = self.eNBPassword - SourceCodePath = self.eNBSourceCodePath + if (RAN.GeteNBIPAddress() != '' and RAN.GeteNBUserName() != '' and RAN.GeteNBPassword() != ''): + IPAddress = RAN.GeteNBIPAddress() + UserName = RAN.GeteNBUserName() + Password = RAN.GeteNBPassword() + SourceCodePath = RAN.GeteNBSourceCodePath() elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''): IPAddress = self.UEIPAddress UserName = self.UEUserName @@ -3712,16 +2914,6 @@ class OaiCiTest(): SSH.command('rm -f build.log.zip', '\$', 5) SSH.command('zip build.log.zip build_log_*/*', '\$', 60) SSH.close() - - def LogCollecteNB(self): - SSH.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - SSH.command('cd ' + self.eNBSourceCodePath, '\$', 5) - SSH.command('cd cmake_targets', '\$', 5) - SSH.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5) - SSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 60) - SSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 5) - SSH.close() - def LogCollectPing(self): SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5) @@ -3750,7 +2942,7 @@ class OaiCiTest(): SSH.close() def RetrieveSystemVersion(self, machine): - if self.eNBIPAddress == 'none' or self.UEIPAddress == 'none': + if RAN.GeteNBIPAddress() == 'none' or self.UEIPAddress == 'none': self.OsVersion = 'Ubuntu 16.04.5 LTS' self.KernelVersion = '4.15.0-45-generic' self.UhdVersion = '3.13.0.1-0' @@ -3760,10 +2952,10 @@ class OaiCiTest(): self.CpuMHz = '2399.996 MHz' return 0 if machine == 'eNB': - if self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != '': - IPAddress = self.eNBIPAddress - UserName = self.eNBUserName - Password = self.eNBPassword + if RAN.GeteNBIPAddress() != '' and RAN.GeteNBUserName() != '' and RAN.GeteNBPassword() != '': + IPAddress = RAN.GeteNBIPAddress() + UserName = RAN.GeteNBUserName() + Password = RAN.GeteNBPassword() else: return -1 if machine == 'UE': @@ -3829,335 +3021,6 @@ class OaiCiTest(): logging.debug('cpu_mhz: ' + self.CpuMHz) SSH.close() -#----------------------------------------------------------- -# HTML Reporting.... -#----------------------------------------------------------- - def CreateHtmlHeader(self): - if (not self.htmlHeaderCreated): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1m Creating HTML header \u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - self.htmlFile = open('test_results.html', 'w') - self.htmlFile.write('<!DOCTYPE html>\n') - self.htmlFile.write('<html class="no-js" lang="en-US">\n') - self.htmlFile.write('<head>\n') - self.htmlFile.write(' <meta name="viewport" content="width=device-width, initial-scale=1">\n') - self.htmlFile.write(' <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">\n') - self.htmlFile.write(' <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>\n') - self.htmlFile.write(' <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>\n') - self.htmlFile.write(' <title>Test Results for TEMPLATE_JOB_NAME job build #TEMPLATE_BUILD_ID</title>\n') - self.htmlFile.write('</head>\n') - self.htmlFile.write('<body><div class="container">\n') - self.htmlFile.write(' <br>\n') - self.htmlFile.write(' <table style="border-collapse: collapse; border: none;">\n') - self.htmlFile.write(' <tr style="border-collapse: collapse; border: none;">\n') - self.htmlFile.write(' <td style="border-collapse: collapse; border: none;">\n') - self.htmlFile.write(' <a href="http://www.openairinterface.org/">\n') - self.htmlFile.write(' <img src="http://www.openairinterface.org/wp-content/uploads/2016/03/cropped-oai_final_logo2.png" alt="" border="none" height=50 width=150>\n') - self.htmlFile.write(' </img>\n') - self.htmlFile.write(' </a>\n') - self.htmlFile.write(' </td>\n') - self.htmlFile.write(' <td style="border-collapse: collapse; border: none; vertical-align: center;">\n') - self.htmlFile.write(' <b><font size = "6">Job Summary -- Job: TEMPLATE_JOB_NAME -- Build-ID: TEMPLATE_BUILD_ID</font></b>\n') - self.htmlFile.write(' </td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - self.htmlFile.write(' <br>\n') - self.htmlFile.write(' <div class="alert alert-info"><strong> <span class="glyphicon glyphicon-dashboard"></span> TEMPLATE_STAGE_NAME</strong></div>\n') - self.htmlFile.write(' <table border = "1">\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-time"></span> Build Start Time (UTC) </td>\n') - self.htmlFile.write(' <td>TEMPLATE_BUILD_TIME</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-cloud-upload"></span> GIT Repository </td>\n') - self.htmlFile.write(' <td><a href="' + self.ranRepository + '">' + self.ranRepository + '</a></td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-wrench"></span> Job Trigger </td>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td>Merge-Request</td>\n') - else: - self.htmlFile.write(' <td>Push to Branch</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-out"></span> Source Branch </td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tree-deciduous"></span> Branch</td>\n') - self.htmlFile.write(' <td>' + self.ranBranch + '</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Source Commit ID </td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Commit ID </td>\n') - self.htmlFile.write(' <td>' + self.ranCommitID + '</td>\n') - self.htmlFile.write(' </tr>\n') - if self.ranAllowMerge != '': - commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.ranCommitID, shell=True, universal_newlines=True) - commit_message = commit_message.strip() - self.htmlFile.write(' <tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Source Commit Message </td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Commit Message </td>\n') - self.htmlFile.write(' <td>' + commit_message + '</td>\n') - self.htmlFile.write(' </tr>\n') - if (self.ranAllowMerge): - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-in"></span> Target Branch </td>\n') - if (self.ranTargetBranch == ''): - self.htmlFile.write(' <td>develop</td>\n') - else: - self.htmlFile.write(' <td>' + self.ranTargetBranch + '</td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - - if (self.ADBIPAddress != 'none'): - terminate_ue_flag = True - self.GetAllUEDevices(terminate_ue_flag) - self.GetAllCatMDevices(terminate_ue_flag) - self.htmlUEConnected = len(self.UEDevices) - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server</h2>\n') - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n') - else: - self.UEDevices.append('OAI-UE') - self.htmlUEConnected = len(self.UEDevices) - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' OAI UE(s) is(are) connected to CI bench</h2>\n') - self.htmlFile.write(' <br>\n') - self.htmlFile.write(' <ul class="nav nav-pills">\n') - count = 0 - while (count < self.nbTestXMLfiles): - pillMsg = ' <li><a data-toggle="pill" href="#' - pillMsg += self.htmlTabRefs[count] - pillMsg += '">' - pillMsg += '__STATE_' + self.htmlTabNames[count] + '__' - pillMsg += self.htmlTabNames[count] - pillMsg += ' <span class="glyphicon glyphicon-' - pillMsg += self.htmlTabIcons[count] - pillMsg += '"></span></a></li>\n' - self.htmlFile.write(pillMsg) - count += 1 - self.htmlFile.write(' </ul>\n') - self.htmlFile.write(' <div class="tab-content">\n') - self.htmlFile.close() - - def CreateHtmlTabHeader(self): - if (not self.htmlHeaderCreated): - if (not os.path.isfile('test_results.html')): - self.CreateHtmlHeader() - self.htmlFile = open('test_results.html', 'a') - if (self.nbTestXMLfiles == 1): - self.htmlFile.write(' <div id="' + self.htmlTabRefs[0] + '" class="tab-pane fade">\n') - self.htmlFile.write(' <h3>Test Summary for <span class="glyphicon glyphicon-file"></span> ' + self.testXMLfiles[0] + '</h3>\n') - else: - self.htmlFile.write(' <div id="build-tab" class="tab-pane fade">\n') - self.htmlFile.write(' <table class="table" border = "1">\n') - self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n') - self.htmlFile.write(' <th>Relative Time (ms)</th>\n') - self.htmlFile.write(' <th>Test Id</th>\n') - self.htmlFile.write(' <th>Test Desc</th>\n') - self.htmlFile.write(' <th>Test Options</th>\n') - self.htmlFile.write(' <th>Test Status</th>\n') - if (self.htmlUEConnected == -1): - terminate_ue_flag = True - if (self.ADBIPAddress != 'none'): - self.GetAllUEDevices(terminate_ue_flag) - self.GetAllCatMDevices(terminate_ue_flag) - else: - self.UEDevices.append('OAI-UE') - self.htmlUEConnected = len(self.UEDevices) - - i = 0 - while (i < self.htmlUEConnected): - self.htmlFile.write(' <th>UE' + str(i) + ' Status</th>\n') - i += 1 - self.htmlFile.write(' </tr>\n') - self.htmlHeaderCreated = True - - def CreateHtmlTabFooter(self, passStatus): - if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th bgcolor = "#33CCFF" colspan=3>Final Tab Status</th>\n') - if passStatus: - self.htmlFile.write(' <th bgcolor = "green" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">PASS <span class="glyphicon glyphicon-ok"></span> </font></th>\n') - else: - self.htmlFile.write(' <th bgcolor = "red" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - self.htmlFile.write(' </div>\n') - self.htmlFile.close() - time.sleep(1) - if passStatus: - cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__//' test_results.html" - subprocess.run(cmd, shell=True) - else: - cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<span class=\"glyphicon glyphicon-remove\"><\/span>/' test_results.html" - subprocess.run(cmd, shell=True) - self.htmlFooterCreated = False - - def CreateHtmlFooter(self, passStatus): - if (os.path.isfile('test_results.html')): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1m Creating HTML footer \u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - - self.htmlFile = open('test_results.html', 'a') - self.htmlFile.write('</div>\n') - self.htmlFile.write(' <p></p>\n') - self.htmlFile.write(' <table class="table table-condensed">\n') - - machines = [ 'eNB', 'UE' ] - for machine in machines: - res = self.RetrieveSystemVersion(machine) - if res == -1: - continue - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th colspan=8>' + str(machine) + ' Server Characteristics</th>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td>OS Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.OsVersion + '</span></td>\n') - self.htmlFile.write(' <td>Kernel Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.KernelVersion + '</span></td>\n') - self.htmlFile.write(' <td>UHD Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.UhdVersion + '</span></td>\n') - self.htmlFile.write(' <td>USRP Board</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.UsrpBoard + '</span></td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td>Nb CPUs</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.CpuNb + '</span></td>\n') - self.htmlFile.write(' <td>CPU Model Name</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.CpuModel + '</span></td>\n') - self.htmlFile.write(' <td>CPU Frequency</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.CpuMHz + '</span></td>\n') - self.htmlFile.write(' <td></td>\n') - self.htmlFile.write(' <td></td>\n') - self.htmlFile.write(' </tr>\n') - - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th colspan=5 bgcolor = "#33CCFF">Final Status</th>\n') - if passStatus: - self.htmlFile.write(' <th colspan=3 bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n') - else: - self.htmlFile.write(' <th colspan=3 bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' </table>\n') - self.htmlFile.write(' <p></p>\n') - self.htmlFile.write(' <div class="well well-lg">End of Test Report -- Copyright <span class="glyphicon glyphicon-copyright-mark"></span> 2018 <a href="http://www.openairinterface.org/">OpenAirInterface</a>. All Rights Reserved.</div>\n') - self.htmlFile.write('</div></body>\n') - self.htmlFile.write('</html>\n') - self.htmlFile.close() - - def CreateHtmlRetrySeparator(self): - if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n') - self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '>Try Run #' + str(self.FailReportCnt) + '</td>\n') - self.htmlFile.write(' </tr>\n') - - def CreateHtmlTestRow(self, options, status, processesStatus, machine='eNB'): - if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - currentTime = int(round(time.time() * 1000)) - self.startTime - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + format(currentTime / 1000, '.1f') + '</td>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n') - self.htmlFile.write(' <td>' + self.desc + '</td>\n') - self.htmlFile.write(' <td>' + str(options) + '</td>\n') - if (str(status) == 'OK'): - self.htmlFile.write(' <td bgcolor = "lightgreen" >' + str(status) + '</td>\n') - elif (str(status) == 'KO'): - if (processesStatus == 0): - self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') - elif (processesStatus == ENB_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process not found</td>\n') - elif (processesStatus == OAI_UE_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - OAI UE process not found</td>\n') - elif (processesStatus == ENB_PROCESS_SEG_FAULT) or (processesStatus == OAI_UE_PROCESS_SEG_FAULT): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Segmentation Fault</td>\n') - elif (processesStatus == ENB_PROCESS_ASSERTION) or (processesStatus == OAI_UE_PROCESS_ASSERTION): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Assertion</td>\n') - elif (processesStatus == ENB_PROCESS_REALTIME_ISSUE): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process faced Real Time issue(s)</td>\n') - elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE) or (processesStatus == OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE): - self.htmlFile.write(' <td bgcolor = "orange" >OK?</td>\n') - elif (processesStatus == ENB_PROCESS_SLAVE_RRU_NOT_SYNCED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' Slave RRU could not synch</td>\n') - elif (processesStatus == OAI_UE_PROCESS_COULD_NOT_SYNC): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - UE could not sync</td>\n') - elif (processesStatus == HSS_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - HSS process not found</td>\n') - elif (processesStatus == MME_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - MME process not found</td>\n') - elif (processesStatus == SPGW_PROCESS_FAILED): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - SPGW process not found</td>\n') - elif (processesStatus == UE_IP_ADDRESS_ISSUE): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - Could not retrieve UE IP address</td>\n') - else: - self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') - else: - self.htmlFile.write(' <td bgcolor = "orange" >' + str(status) + '</td>\n') - if (len(str(self.htmleNBFailureMsg)) > 2): - cellBgColor = 'white' - result = re.search('ended with|faced real time issues', self.htmleNBFailureMsg) - if result is not None: - cellBgColor = 'red' - else: - result = re.search('showed|Reestablishment|Could not copy eNB logfile', self.htmleNBFailureMsg) - if result is not None: - cellBgColor = 'orange' - self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmleNBFailureMsg + '</pre></td>\n') - self.htmleNBFailureMsg = '' - elif (len(str(self.htmlUEFailureMsg)) > 2): - cellBgColor = 'white' - result = re.search('ended with|faced real time issues', self.htmlUEFailureMsg) - if result is not None: - cellBgColor = 'red' - else: - result = re.search('showed|Could not copy UE logfile|oaitun_ue1 interface is either NOT mounted or NOT configured', self.htmlUEFailureMsg) - if result is not None: - cellBgColor = 'orange' - self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmlUEFailureMsg + '</pre></td>\n') - self.htmlUEFailureMsg = '' - else: - i = 0 - while (i < self.htmlUEConnected): - self.htmlFile.write(' <td>-</td>\n') - i += 1 - self.htmlFile.write(' </tr>\n') - - def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue): - if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - currentTime = int(round(time.time() * 1000)) - self.startTime - addOrangeBK = False - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + format(currentTime / 1000, '.1f') + '</td>\n') - self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n') - self.htmlFile.write(' <td>' + self.desc + '</td>\n') - self.htmlFile.write(' <td>' + str(options) + '</td>\n') - if (str(status) == 'OK'): - self.htmlFile.write(' <td bgcolor = "lightgreen" >' + str(status) + '</td>\n') - elif (str(status) == 'KO'): - self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') - else: - addOrangeBK = True - self.htmlFile.write(' <td bgcolor = "orange" >' + str(status) + '</td>\n') - i = 0 - while (i < self.htmlUEConnected): - if (i < ue_status): - if (not ue_queue.empty()): - if (addOrangeBK): - self.htmlFile.write(' <td bgcolor = "orange" >' + str(ue_queue.get()).replace('white', 'orange') + '</td>\n') - else: - self.htmlFile.write(' <td>' + str(ue_queue.get()) + '</td>\n') - else: - self.htmlFile.write(' <td>-</td>\n') - else: - self.htmlFile.write(' <td>-</td>\n') - i += 1 - self.htmlFile.write(' </tr>\n') - #----------------------------------------------------------- # ShowTestID() #----------------------------------------------------------- @@ -4175,47 +3038,47 @@ def CheckClassValidity(action,id): def GetParametersFromXML(action): if action == 'Build_eNB': - CiTestObj.Build_eNB_args = test.findtext('Build_eNB_args') + RAN.SetBuild_eNB_args(test.findtext('Build_eNB_args')) forced_workspace_cleanup = test.findtext('forced_workspace_cleanup') if (forced_workspace_cleanup is None): - CiTestObj.Build_eNB_forced_workspace_cleanup = False + RAN.SetBuild_eNB_forced_workspace_cleanup(False) else: if re.match('true', forced_workspace_cleanup, re.IGNORECASE): - CiTestObj.Build_eNB_forced_workspace_cleanup = True - else: - CiTestObj.Build_eNB_forced_workspace_cleanup = False - CiTestObj.eNB_instance = test.findtext('eNB_instance') - if (CiTestObj.eNB_instance is None): - CiTestObj.eNB_instance = '0' - CiTestObj.eNB_serverId = test.findtext('eNB_serverId') - if (CiTestObj.eNB_serverId is None): - CiTestObj.eNB_serverId = '0' + RAN.SetBuild_eNB_forced_workspace_cleanup(True) + else: + RAN.SetBuild_eNB_forced_workspace_cleanup(False) + RAN.SeteNB_instance(test.findtext('eNB_instance')) + if (RAN.GeteNB_instance() is None): + RAN.SeteNB_instance('0') + RAN.SeteNB_serverId(test.findtext('eNB_serverId')) + if (RAN.GeteNB_serverId() is None): + RAN.SeteNB_serverId('0') xmlBgBuildField = test.findtext('backgroundBuild') if (xmlBgBuildField is None): - CiTestObj.backgroundBuild = False + RAN.SetbackgroundBuild(False) else: if re.match('true', xmlBgBuildField, re.IGNORECASE): - CiTestObj.backgroundBuild = True + RAN.SetbackgroundBuild(True) else: - CiTestObj.backgroundBuild = False + RAN.SetbackgroundBuild(False) if action == 'WaitEndBuild_eNB': - CiTestObj.Build_eNB_args = test.findtext('Build_eNB_args') - CiTestObj.eNB_instance = test.findtext('eNB_instance') - if (CiTestObj.eNB_instance is None): - CiTestObj.eNB_instance = '0' - CiTestObj.eNB_serverId = test.findtext('eNB_serverId') - if (CiTestObj.eNB_serverId is None): - CiTestObj.eNB_serverId = '0' + RAN.SetBuild_eNB_args(test.findtext('Build_eNB_args')) + RAN.SeteNB_instance(test.findtext('eNB_instance')) + if (RAN.GeteNB_instance() is None): + RAN.SeteNB_instance('0') + RAN.SeteNB_serverId(test.findtext('eNB_serverId')) + if (RAN.GeteNB_serverId() is None): + RAN.SeteNB_serverId('0') if action == 'Initialize_eNB': - CiTestObj.Initialize_eNB_args = test.findtext('Initialize_eNB_args') - CiTestObj.eNB_instance = test.findtext('eNB_instance') - if (CiTestObj.eNB_instance is None): - CiTestObj.eNB_instance = '0' - CiTestObj.eNB_serverId = test.findtext('eNB_serverId') - if (CiTestObj.eNB_serverId is None): - CiTestObj.eNB_serverId = '0' + RAN.SetInitialize_eNB_args(test.findtext('Initialize_eNB_args')) + RAN.SeteNB_instance(test.findtext('eNB_instance')) + if (RAN.GeteNB_instance() is None): + RAN.SeteNB_instance('0') + RAN.SeteNB_serverId(test.findtext('eNB_serverId')) + if (RAN.GeteNB_serverId() is None): + RAN.SeteNB_serverId('0') CiTestObj.air_interface = test.findtext('air_interface') if (CiTestObj.air_interface is None): CiTestObj.air_interface = 'lte' @@ -4223,12 +3086,12 @@ def GetParametersFromXML(action): CiTestObj.air_interface = CiTestObj.air_interface.lower() if action == 'Terminate_eNB': - CiTestObj.eNB_instance = test.findtext('eNB_instance') - if (CiTestObj.eNB_instance is None): - CiTestObj.eNB_instance = '0' - CiTestObj.eNB_serverId = test.findtext('eNB_serverId') - if (CiTestObj.eNB_serverId is None): - CiTestObj.eNB_serverId = '0' + RAN.SeteNB_instance(test.findtext('eNB_instance')) + if (RAN.GeteNB_instance() is None): + RAN.SeteNB_instance('0') + RAN.SeteNB_serverId(test.findtext('eNB_serverId')) + if (RAN.GeteNB_serverId() is None): + RAN.SeteNB_serverId('0') CiTestObj.air_interface = test.findtext('air_interface') if (CiTestObj.air_interface is None): CiTestObj.air_interface = 'lte' @@ -4269,7 +3132,7 @@ def GetParametersFromXML(action): CiTestObj.air_interface = SSH.air_interface.lower() if action == 'Terminate_OAI_UE': - CiTestObj.eNB_instance = test.findtext('UE_instance') + RAN.SeteNB_instance(test.findtext('UE_instance')) if (CiTestObj.UE_instance is None): CiTestObj.UE_instance = '0' @@ -4332,13 +3195,18 @@ def receive_signal(signum, frame): mode = '' CiTestObj = OaiCiTest() -from sshconnection import * -from epc import * -from helpreadme import * -SSH = SSHConnection() -EPC = EPCManagement() -#HELP = HelpReadme() -#HELP.GenericHelp() +import sshconnection +import epc +import helpreadme +import ran +import html +import constants + +SSH = sshconnection.SSHConnection() +EPC = epc.EPCManagement() +RAN = ran.RANManagement() +HTML = html.HTMLManagement() + argvs = sys.argv argc = len(argvs) @@ -4346,6 +3214,7 @@ cwd = os.getcwd() while len(argvs) > 1: myArgv = argvs.pop(1) # 0th is this file's name + if re.match('^\-\-help$', myArgv, re.IGNORECASE): GenericHelp(Version) sys.exit(0) @@ -4357,7 +3226,8 @@ while len(argvs) > 1: matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE) else: matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.ranRepository = matchReg.group(1) + RAN.SetranRepository(matchReg.group(1)) + HTML.SetranRepository(matchReg.group(1)) elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE) @@ -4365,68 +3235,72 @@ while len(argvs) > 1: matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE) doMerge = matchReg.group(1) if ((doMerge == 'true') or (doMerge == 'True')): - CiTestObj.ranAllowMerge = True + RAN.SetranAllowMerge(True) + HTML.SetranAllowMerge(True) elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) else: matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.ranBranch = matchReg.group(1) + RAN.SetranBranch(matchReg.group(1)) + HTML.SetranBranch(matchReg.group(1)) elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) else: matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE) - CiTestObj.ranCommitID = matchReg.group(1) + RAN.SetranCommitID(matchReg.group(1)) + HTML.SetranCommitID(matchReg.group(1)) elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) else: matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE) - CiTestObj.ranTargetBranch = matchReg.group(1) + RAN.SetranTargetBranch(matchReg.group(1)) elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNBIPAddress = matchReg.group(1) + RAN.SeteNBIPAddress(matchReg.group(1)) elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNB1IPAddress = matchReg.group(1) + RAN.SeteNB1IPAddress(matchReg.group(1)) elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNB2IPAddress = matchReg.group(1) + RAN.SeteNB2IPAddress(matchReg.group(1)) elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNBUserName = matchReg.group(1) + RAN.SeteNBUserName(matchReg.group(1)) elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNB1UserName = matchReg.group(1) + RAN.SeteNB1UserName(matchReg.group(1)) elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNB2UserName = matchReg.group(1) + RAN.SeteNB2UserName(matchReg.group(1)) elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNBPassword = matchReg.group(1) + RAN.SeteNBPassword(matchReg.group(1)) elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNB1Password = matchReg.group(1) + RAN.SeteNB1Password(matchReg.group(1)) elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNB2Password = matchReg.group(1) + RAN.SeteNB2Password(matchReg.group(1)) elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNBSourceCodePath = matchReg.group(1) + RAN.SeteNBSourceCodePath(matchReg.group(1)) elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNB1SourceCodePath = matchReg.group(1) + RAN.SeteNB1SourceCodePath(matchReg.group(1)) elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.eNB2SourceCodePath = matchReg.group(1) + RAN.SeteNB2SourceCodePath(matchReg.group(1)) elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) EPC.SetIPAddress(matchReg.group(1)) +#GP250220: do we still need EPCBranch? it's not used anywhere elif re.match('^\-\-EPCBranch=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCBranch=(.+)$', myArgv, re.IGNORECASE) CiTestObj.EPCBranch = matchReg.group(1) @@ -4466,7 +3340,8 @@ while len(argvs) > 1: elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) CiTestObj.testXMLfiles.append(matchReg.group(1)) - CiTestObj.nbTestXMLfiles += 1 + HTML.SettestXMLfiles(matchReg.group(1)) + HTML.SetnbTestXMLfiles(HTML.GetnbTestXMLfiles()+1) elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) CiTestObj.UEIPAddress = matchReg.group(1) @@ -4489,12 +3364,12 @@ while len(argvs) > 1: sys.exit('Invalid Parameter: ' + myArgv) if re.match('^TerminateeNB$', mode, re.IGNORECASE): - if CiTestObj.eNBIPAddress == '' or CiTestObj.eNBUserName == '' or CiTestObj.eNBPassword == '': + if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '': GenericHelp(Version) sys.exit('Insufficient Parameter') - CiTestObj.eNB_serverId = '0' - CiTestObj.eNB_instance = '0' - CiTestObj.eNBSourceCodePath = '/tmp/' + RAN.SeteNB_serverId('0') + RAN.SeteNB_instance('0') + RAN.SeteNBSourceCodePath('/tmp/') CiTestObj.TerminateeNB() elif re.match('^TerminateUE$', mode, re.IGNORECASE): if (CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == ''): @@ -4524,12 +3399,12 @@ elif re.match('^TerminateSPGW$', mode, re.IGNORECASE): sys.exit('Insufficient Parameter') CiTestObj.TerminateSPGW() elif re.match('^LogCollectBuild$', mode, re.IGNORECASE): - if (CiTestObj.eNBIPAddress == '' or CiTestObj.eNBUserName == '' or CiTestObj.eNBPassword == '' or CiTestObj.eNBSourceCodePath == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''): + if (RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''): GenericHelp(Version) sys.exit('Insufficient Parameter') CiTestObj.LogCollectBuild() elif re.match('^LogCollecteNB$', mode, re.IGNORECASE): - if CiTestObj.eNBIPAddress == '' or CiTestObj.eNBUserName == '' or CiTestObj.eNBPassword == '' or CiTestObj.eNBSourceCodePath == '': + if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '': GenericHelp(Version) sys.exit('Insufficient Parameter') CiTestObj.LogCollecteNB() @@ -4569,7 +3444,7 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE): sys.exit('Insufficient Parameter') count = 0 foundCount = 0 - while (count < CiTestObj.nbTestXMLfiles): + while (count < HTML.GetnbTestXMLfiles()): #xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[count] xml_test_file = sys.path[0] + "/" + CiTestObj.testXMLfiles[count] if (os.path.isfile(xml_test_file)): @@ -4578,36 +3453,52 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE): except: print("Error while parsing file: " + xml_test_file) xmlRoot = xmlTree.getroot() - CiTestObj.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) - CiTestObj.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count))) - CiTestObj.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign')) + HTML.SethtmlTabRefs(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) + HTML.SethtmlTabNames(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) + HTML.SethtmlTabIcons(xmlRoot.findtext('htmlTabIcon',default='info-sign')) + #CiTestObj.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) + #CiTestObj.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count))) + #CiTestObj.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign')) foundCount += 1 count += 1 - if foundCount != CiTestObj.nbTestXMLfiles: - CiTestObj.nbTestXMLfiles = foundCount - CiTestObj.CreateHtmlHeader() + if foundCount != HTML.GetnbTestXMLfiles(): + HTML.SetnbTestXMLfiles(foundcount) + + if (CiTestObj.ADBIPAddress != 'none'): + terminate_ue_flag = False + CiTestObj.GetAllUEDevices(terminate_ue_flag) + CiTestObj.GetAllCatMDevices(terminate_ue_flag) + HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices)) + HTML.SethtmlNb_Smartphones(len(CiTestObj.UEDevices)) + HTML.SethtmlNb_CATM_Modules(len(CiTestObj.CatMDevices)) + HTML.CreateHtmlHeader(CiTestObj.ADBIPAddress) elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): - CiTestObj.CreateHtmlFooter(CiTestObj.finalStatus) + HTML.SetreseNB(RetrieveSystemVersion('eNB')) + HTML.SetresUE(RetrieveSystemVersion('UE')) + HTML.CreateHtmlFooter(CiTestObj.finalStatus) elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE): if re.match('^TesteNB$', mode, re.IGNORECASE): - if CiTestObj.eNBIPAddress == '' or CiTestObj.ranRepository == '' or CiTestObj.ranBranch == '' or CiTestObj.eNBUserName == '' or CiTestObj.eNBPassword == '' or CiTestObj.eNBSourceCodePath == '' or EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '': + if RAN.GeteNBIPAddress() == '' or RAN.GetranRepository() == '' or RAN.GetranBranch() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '' or EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '': GenericHelp(Version) if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '' or EPC.GetType() == '': EPCSrvHelp(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), EPC.GetSourceCodePath(), EPC.GetType()) - # Gabriele: other if conditions relevant to eNB etc. to be added + if RAN.GetranRepository() == '': + GitSrvHelp(RAN.GetranRepository(),RAN.GetranBranch(),RAN.GetranCommitID(),RAN.GetranAllowMerge(),RAN.GetranTargetBranch()) + if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '': + eNBSrvHelp(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath()) sys.exit('Insufficient Parameter') if (EPC.GetIPAddress() != '') and (EPC.GetIPAddress() != 'none'): SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), cwd + "/tcp_iperf_stats.awk", "/tmp") SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), cwd + "/active_net_interfaces.awk", "/tmp") else: - if CiTestObj.UEIPAddress == '' or CiTestObj.ranRepository == '' or CiTestObj.ranBranch == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == '': + if CiTestObj.UEIPAddress == '' or RAN.GetranRepository() == '' or RAN.GetranBranch() == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == '': GenericHelp(Version) sys.exit('UE: Insufficient Parameter') #read test_case_list.xml file # if no parameters for XML file, use default value - if (CiTestObj.nbTestXMLfiles != 1): + if (HTML.GetnbTestXMLfiles() != 1): xml_test_file = cwd + "/test_case_list.xml" else: xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[0] @@ -4617,9 +3508,11 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re exclusion_tests=xmlRoot.findtext('TestCaseExclusionList',default='') requested_tests=xmlRoot.findtext('TestCaseRequestedList',default='') - if (CiTestObj.nbTestXMLfiles == 1): - CiTestObj.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) - CiTestObj.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0')) + if (HTML.GetnbTestXMLfiles() == 1): + HTML.SethtmlTabRefs(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) + HTML.SethtmlTabNames(xmlRoot.findtext('htmlTabName',default='Test-0')) + #CiTestObj.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) + #CiTestObj.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0')) repeatCount = xmlRoot.findtext('repeatCount',default='1') CiTestObj.repeatCounts.append(int(repeatCount)) all_tests=xmlRoot.findall('testCase') @@ -4661,26 +3554,38 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re signal.signal(signal.SIGUSR1, receive_signal) - CiTestObj.CreateHtmlTabHeader() + if (CiTestObj.ADBIPAddress != 'none'): + terminate_ue_flag = False + CiTestObj.GetAllUEDevices(terminate_ue_flag) + CiTestObj.GetAllCatMDevices(terminate_ue_flag) + else: + CiTestObj.UEDevices.append('OAI-UE') + HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices)) + HTML.CreateHtmlTabHeader() CiTestObj.FailReportCnt = 0 - CiTestObj.prematureExit = True + RAN.SetprematureExit(True) CiTestObj.startTime = int(round(time.time() * 1000)) - while CiTestObj.FailReportCnt < CiTestObj.repeatCounts[0] and CiTestObj.prematureExit: - CiTestObj.prematureExit = False + HTML.SetstartTime(CiTestObj.startTime) + while CiTestObj.FailReportCnt < CiTestObj.repeatCounts[0] and RAN.GetprematureExit(): + RAN.SetprematureExit(False) # At every iteratin of the retry loop, a separator will be added - CiTestObj.CreateHtmlRetrySeparator() + # pass CiTestObj.FailReportCnt as parameter of HTML.CreateHtmlRetrySeparator + HTML.CreateHtmlRetrySeparator(CiTestObj.FailReportCnt) for test_case_id in todo_tests: - if CiTestObj.prematureExit: + if RAN.GetprematureExit(): break for test in all_tests: - if CiTestObj.prematureExit: + if RAN.GetprematureExit(): break id = test.get('id') if test_case_id != id: continue CiTestObj.testCase_id = id + RAN.SettestCase_id(CiTestObj.testCase_id) + HTML.SettestCase_id(CiTestObj.testCase_id) CiTestObj.desc = test.findtext('desc') + HTML.Setdesc(CiTestObj.desc) action = test.findtext('class') if (CheckClassValidity(action, id) == False): continue @@ -4691,13 +3596,17 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re terminate_ue_flag = False CiTestObj.GetAllUEDevices(terminate_ue_flag) if action == 'Build_eNB': - CiTestObj.BuildeNB() + RAN.BuildeNB() elif action == 'WaitEndBuild_eNB': - CiTestObj.WaitBuildeNBisFinished() + RAN.WaitBuildeNBisFinished() elif action == 'Initialize_eNB': - CiTestObj.InitializeeNB() + check_eNB = False + check_OAI_UE = False + RAN.SetpStatus(CiTestObj.CheckProcessExist(check_eNB, check_OAI_UE)) + + RAN.InitializeeNB() elif action == 'Terminate_eNB': - CiTestObj.TerminateeNB() + RAN.TerminateeNB() elif action == 'Initialize_UE': CiTestObj.InitializeUE() elif action == 'Terminate_UE': @@ -4757,13 +3666,13 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re else: sys.exit('Invalid action') CiTestObj.FailReportCnt += 1 - if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and CiTestObj.prematureExit: + if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and RAN.GetprematureExit(): logging.debug('Testsuite failed ' + str(CiTestObj.FailReportCnt) + ' time(s)') - CiTestObj.CreateHtmlTabFooter(False) + HTML.CreateHtmlTabFooter(False) sys.exit('Failed Scenario') else: logging.info('Testsuite passed after ' + str(CiTestObj.FailReportCnt) + ' time(s)') - CiTestObj.CreateHtmlTabFooter(True) + HTML.CreateHtmlTabFooter(True) else: GenericHelp(Version) sys.exit('Invalid mode') diff --git a/ci-scripts/main_enb.py b/ci-scripts/main_enb.py deleted file mode 100644 index 3b3428eec42a4c7faf29beabf8c033947a3de35b..0000000000000000000000000000000000000000 --- a/ci-scripts/main_enb.py +++ /dev/null @@ -1,3680 +0,0 @@ - -# * 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 -# */ -#--------------------------------------------------------------------- -# Python for CI of OAI-eNB + COTS-UE -# -# Required Python Version -# Python 3.x -# -# Required Python Package -# pexpect -#--------------------------------------------------------------------- - -import constants as CONST - -#----------------------------------------------------------- -# Version -#----------------------------------------------------------- -Version = '0.1' - -#----------------------------------------------------------- -# Import -#----------------------------------------------------------- -import sys # arg -import re # reg -import pexpect # pexpect -import time # sleep -import os -import subprocess -import xml.etree.ElementTree as ET -import logging -import datetime -import signal -from multiprocessing import Process, Lock, SimpleQueue -logging.basicConfig( - level=logging.DEBUG, - format="[%(asctime)s] %(name)s:%(levelname)s: %(message)s" -) - - -#----------------------------------------------------------- -# Class Declaration -#----------------------------------------------------------- -class OaiCiTest(): - - def __init__(self): - self.FailReportCnt = 0 - self.ADBIPAddress = '' - self.ADBUserName = '' - self.ADBPassword = '' - self.ADBCentralized = True - self.testCase_id = '' - self.testXMLfiles = [] - self.nbTestXMLfiles = 0 - self.desc = '' - self.ping_args = '' - self.ping_packetloss_threshold = '' - self.iperf_args = '' - self.iperf_packetloss_threshold = '' - self.iperf_profile = '' - self.iperf_options = '' - self.nbMaxUEtoAttach = -1 - self.UEDevices = [] - self.UEDevicesStatus = [] - self.UEDevicesRemoteServer = [] - self.UEDevicesRemoteUser = [] - self.UEDevicesOffCmd = [] - self.UEDevicesOnCmd = [] - self.UEDevicesRebootCmd = [] - self.CatMDevices = [] - self.UEIPAddresses = [] - self.htmlFile = '' - # self.htmlHeaderCreated = False - # self.htmlFooterCreated = False - self.htmlUEConnected = -1 - self.htmleNBFailureMsg = '' - self.htmlUEFailureMsg = '' - self.picocom_closure = False - self.idle_sleep_time = 0 - self.x2_ho_options = 'network' - self.x2NbENBs = 0 - self.x2ENBBsIds = [] - self.x2ENBConnectedUEs = [] - self.repeatCounts = [] - self.finalStatus = False - self.OsVersion = '' - self.KernelVersion = '' - self.UhdVersion = '' - self.UsrpBoard = '' - self.CpuNb = '' - self.CpuModel = '' - self.CpuMHz = '' - self.UEIPAddress = '' - self.UEUserName = '' - self.UEPassword = '' - self.UE_instance = '' - self.UESourceCodePath = '' - self.UELogFile = '' - self.Build_OAI_UE_args = '' - self.Initialize_OAI_UE_args = '' - self.clean_repository = True - self.flexranCtrlInstalled = False - self.flexranCtrlStarted = False - self.expectedNbOfConnectedUEs = 0 - self.startTime = 0 - - - def BuildOAIUE(self): - if self.UEIPAddress == '' or RAN.GetranRepository() == '' or RAN.GetranBranch() == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - result = re.search('--nrUE', self.Build_OAI_UE_args) - if result is not None: - RAN.Setair_interface('nr') - ue_prefix = 'NR ' - else: - RAN.Setair_interface('lte') - ue_prefix = '' - result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', RAN.GetranRepository()) - if result is not None: - full_ran_repo_name = RAN.GetranRepository() - else: - full_ran_repo_name = RAN.GetranRepository() + '.git' - SSH.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) - SSH.command('cd ' + self.UESourceCodePath, '\$', 5) - SSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) - # here add a check if git clone or git fetch went smoothly - SSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) - SSH.command('git config user.name "OAI Jenkins"', '\$', 5) - if self.clean_repository: - SSH.command('ls *.txt', '\$', 5) - result = re.search('LAST_BUILD_INFO', SSH.getBefore()) - if result is not None: - mismatch = False - SSH.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) - result = re.search(RAN.GetranCommitID(), SSH.getBefore()) - if result is None: - mismatch = True - SSH.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if (RAN.GetranAllowMerge()): - result = re.search('YES', SSH.getBefore()) - if result is None: - mismatch = True - SSH.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if RAN.GetranTargetBranch() == '': - result = re.search('develop', SSH.getBefore()) - else: - result = re.search(RAN.GetranTargetBranch(), SSH.getBefore()) - if result is None: - mismatch = True - else: - result = re.search('NO', SSH.getBefore()) - if result is None: - mismatch = True - if not mismatch: - SSH.close() - HTML.CreateHtmlTestRow(RAN.GetBuild_eNB_args(), 'OK', CONST.ALL_PROCESSES_OK) - return - - SSH.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30) - - # if the commit ID is provided use it to point to it - if RAN.GetranCommitID() != '': - SSH.command('git checkout -f ' + RAN.GetranCommitID(), '\$', 5) - # if the branch is not develop, then it is a merge request and we need to do - # the potential merge. Note that merge conflicts should already been checked earlier - if (RAN.GetranAllowMerge()): - if RAN.GetranTargetBranch() == '': - if (RAN.GetranBranch() != 'develop') and (RAN.GetranBranch() != 'origin/develop'): - SSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) - else: - logging.debug('Merging with the target branch: ' + RAN.GetranTargetBranch()) - SSH.command('git merge --ff origin/' + RAN.GetranTargetBranch() + ' -m "Temporary merge for CI"', '\$', 5) - SSH.command('source oaienv', '\$', 5) - SSH.command('cd cmake_targets', '\$', 5) - SSH.command('mkdir -p log', '\$', 5) - SSH.command('chmod 777 log', '\$', 5) - # no need to remove in log (git clean did the trick) - SSH.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee compile_oai_ue.log', 'Bypassing the Tests|build have failed', 600) - SSH.command('ls ran_build/build', '\$', 3) - SSH.command('ls ran_build/build', '\$', 3) - buildStatus = True - result = re.search(RAN.Getair_interface() + '-uesoftmodem', SSH.getBefore()) - if result is None: - buildStatus = False - SSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) - SSH.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) - SSH.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5) - if buildStatus: - # Generating a BUILD INFO file - SSH.command('echo "SRC_BRANCH: ' + RAN.GetranBranch() + '" > ../LAST_BUILD_INFO.txt', '\$', 2) - SSH.command('echo "SRC_COMMIT: ' + RAN.GetranCommitID() + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if (RAN.GetranAllowMerge()): - SSH.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if RAN.GetranTargetBranch() == '': - SSH.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - SSH.command('echo "TGT_BRANCH: ' + RAN.GetranTargetBranch() + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - SSH.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) - SSH.close() - HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE') - else: - SSH.close() - logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') - HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', CONST.ALL_PROCESSES_OK, 'OAI UE') - HTML.CreateHtmlTabFooter(False) - sys.exit(1) - - def CheckFlexranCtrlInstallation(self): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '': - return - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('ls -ls /opt/flexran_rtc/*/rt_controller', '\$', 5) - result = re.search('/opt/flexran_rtc/build/rt_controller', SSH.getBefore()) - if result is not None: - self.flexranCtrlInstalled = True - RAN.SetflexranCtrlInstalled(True) - logging.debug('Flexran Controller is installed') - SSH.close() - - def InitializeFlexranCtrl(self): - if self.flexranCtrlInstalled == False: - return - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd /opt/flexran_rtc', '\$', 5) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S rm -f log/*.log', '\$', 5) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5) - SSH.command('ps -aux | grep --color=never rt_controller', '\$', 5) - result = re.search('rt_controller -c ', SSH.getBefore()) - if result is not None: - logging.debug('\u001B[1m Initialize FlexRan Controller Completed\u001B[0m') - self.flexranCtrlStarted = True - RAN.SetflexranCtrlStarted(True) - SSH.close() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def InitializeUE_common(self, device_id, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if not self.ADBCentralized: - # Reboot UE - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesRebootCmd[idx], '\$', 60) - # Wait - #time.sleep(60) - # Put in LTE-Mode only - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode 11"\'', '\$', 60) - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode1 11"\'', '\$', 60) - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode2 11"\'', '\$', 60) - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode3 11"\'', '\$', 60) - # enable data service - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - # we need to do radio on/off cycle to make sure of above changes - # airplane mode off // radio on - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - #time.sleep(10) - # airplane mode on // radio off - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - - # normal procedure without reboot - # enable data service - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - # airplane mode on // radio off - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - SSH.close() - return - # enable data service - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) - - # The following commands are deprecated since we no longer work on Android 7+ - # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10) - # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60) - # a dedicated script has to be installed inside the UE - # airplane mode on means call /data/local/tmp/off - if device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - #airplane mode off means call /data/local/tmp/on - logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m') - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def InitializeUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.InitializeUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def InitializeOAIUE(self): - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - if RAN.Getair_interface() == 'lte': - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is None: - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus) - HTML.CreateHtmlTabFooter(False) - sys.exit(1) - UE_prefix = '' - else: - UE_prefix = 'NR ' - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - # b2xx_fx3_utils reset procedure - SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60) - result = re.search('type: b200', SSH.getBefore()) - if result is not None: - logging.debug('Found a B2xx device --> resetting it') - SSH.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) - # Reloading FGPA bin firmware - SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 30) - result = re.search('type: n3xx', SSH.getBefore()) - if result is not None: - logging.debug('Found a N3xx device --> resetting it') - SSH.command('cd ' + self.UESourceCodePath, '\$', 5) - # Initialize_OAI_UE_args usually start with -C and followed by the location in repository - SSH.command('source oaienv', '\$', 5) - SSH.command('cd cmake_targets/ran_build/build', '\$', 5) - if RAN.Getair_interface() == 'lte': - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - # We may have to regenerate the .u* files - if result is None: - SSH.command('ls /tmp/*.sed', '\$', 5) - result = re.search('adapt_usim_parameters', SSH.getBefore()) - if result is not None: - SSH.command('sed -f /tmp/adapt_usim_parameters.sed ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) - else: - SSH.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5) - SSH.command('echo "ulimit -c unlimited && ./'+ RAN.Getair_interface() +'-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) - self.UELogFile = 'ue_' + self.testCase_id + '.log' - - # We are now looping several times to hope we really sync w/ an eNB - doOutterLoop = True - outterLoopCounter = 5 - gotSyncStatus = True - fullSyncStatus = True - while (doOutterLoop): - SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/ran_build/build', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) - #use nohup instead of daemon - #SSH.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/ran_build/build -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - SSH.command('echo $USER; nohup sudo ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5) - time.sleep(6) - SSH.command('cd ../..', '\$', 5) - doLoop = True - loopCounter = 10 - gotSyncStatus = True - # the 'got sync' message is for the UE threads synchronization - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - # Here should never occur - logging.error('"got sync" message never showed!') - gotSyncStatus = False - doLoop = False - continue - SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) - if RAN.Getair_interface() == 'nr': - result = re.search('Starting sync detection', SSH.getBefore()) - else: - result = re.search('got sync', SSH.getBefore()) - if result is None: - time.sleep(10) - else: - doLoop = False - logging.debug('Found "got sync" message!') - if gotSyncStatus == False: - # we certainly need to stop the lte-uesoftmodem process if it is still running! - SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) - result = re.search('-uesoftmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT -r *-uesoftmodem', '\$', 4) - time.sleep(3) - continue - if RAN.Getair_interface() == 'nr': - fullSyncStatus = True - doOutterLoop = False - else: - # We are now checking if sync w/ eNB DOES NOT OCCUR - # Usually during the cell synchronization stage, the UE returns with No cell synchronization message - doLoop = True - loopCounter = 10 - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - # Here we do have a great chance that the UE did cell-sync w/ eNB - doLoop = False - doOutterLoop = False - fullSyncStatus = True - continue - SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) - result = re.search('No cell synchronization found', SSH.getBefore()) - if result is None: - time.sleep(6) - else: - doLoop = False - fullSyncStatus = False - logging.debug('Found: "No cell synchronization" message! --> try again') - time.sleep(6) - SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) - result = re.search('lte-uesoftmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) - outterLoopCounter = outterLoopCounter - 1 - if (outterLoopCounter == 0): - doOutterLoop = False - - if fullSyncStatus and gotSyncStatus and RAN.Getair_interface() == 'lte': - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is None: - SSH.command('ifconfig oaitun_ue1', '\$', 4) - SSH.command('ifconfig oaitun_ue1', '\$', 4) - # ifconfig output is different between ubuntu 16 and ubuntu 18 - result = re.search('inet addr:1|inet 1', SSH.getBefore()) - if result is not None: - logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m') - tunnelInterfaceStatus = True - else: - logging.debug(SSH.getBefore()) - logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') - tunnelInterfaceStatus = False - if RAN.GeteNBmbmsEnables[0]: - self.command('ifconfig oaitun_uem1', '\$', 4) - result = re.search('inet addr', SSH.getBefore()) - if result is not None: - logging.debug('\u001B[1m oaitun_uem1 interface is mounted and configured\u001B[0m') - tunnelInterfaceStatus = tunnelInterfaceStatus and True - else: - logging.error('\u001B[1m oaitun_uem1 interface is either NOT mounted or NOT configured\u001B[0m') - tunnelInterfaceStatus = False - else: - tunnelInterfaceStatus = True - else: - tunnelInterfaceStatus = True - - SSH.close() - if fullSyncStatus and gotSyncStatus and tunnelInterfaceStatus: - HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE') - logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m') - if (self.ADBIPAddress != 'none'): - self.UEDevices = [] - self.UEDevices.append('OAI-UE') - self.UEDevicesStatus = [] - self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) - else: - if RAN.Getair_interface() == 'lte': - if RAN.GeteNBmbmsEnables[0]: - self.htmlUEFailureMsg = 'oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured' - else: - self.htmlUEFailureMsg = 'oaitun_ue1 interface is either NOT mounted or NOT configured' - HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') - else: - self.htmlUEFailureMsg = 'nr-uesoftmodem did NOT synced' - HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE') - logging.error('\033[91mInitialize OAI UE Failed! \033[0m') - self.AutoTerminateUEandeNB() - - def checkDevTTYisUnlocked(self): - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - count = 0 - while count < 5: - SSH.command('echo ' + self.ADBPassword + ' | sudo -S lsof | grep ttyUSB0', '\$', 10) - result = re.search('picocom', SSH.getBefore()) - if result is None: - count = 10 - else: - time.sleep(5) - count = count + 1 - SSH.close() - - def InitializeCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - self.picocom_closure = True - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - SSH.command('AT', 'OK|ERROR', 5) - SSH.command('AT', 'OK', 5) - # Doing a power cycle - self.command('AT^RESET', 'SIMSTORE,READY', 15) - self.command('AT', 'OK|ERROR', 5) - self.command('AT', 'OK', 5) - self.command('ATE1', 'OK', 5) - # Disabling the Radio - SSH.command('AT+CFUN=0', 'OK', 5) - logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') - # Checking if auto-attach is enabled - SSH.command('AT^AUTOATT?', 'OK', 5) - result = re.search('AUTOATT: (?P<state>[0-9\-]+)', SSH.getBefore()) - if result is not None: - if result.group('state') is not None: - autoAttachState = int(result.group('state')) - if autoAttachState is not None: - if autoAttachState == 0: - SSH.command('AT^AUTOATT=1', 'OK', 5) - logging.debug('\u001B[1m Auto-Attach enabled\u001B[0m') - else: - logging.debug('\u001B[1;37;41m Could not check Auto-Attach! \u001B[0m') - # Force closure of picocom but device might still be locked - SSH.close() - self.picocom_closure = False - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - self.checkDevTTYisUnlocked() - - def TerminateCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - self.picocom_closure = True - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - SSH.command('AT', 'OK|ERROR', 5) - SSH.command('AT', 'OK', 5) - # Disabling the Radio - SSH.command('AT+CFUN=0', 'OK', 5) - logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') - SSH.close() - self.picocom_closure = False - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - self.checkDevTTYisUnlocked() - - def AttachCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - self.picocom_closure = True - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - SSH.command('AT', 'OK|ERROR', 5) - SSH.command('AT', 'OK', 5) - # Enabling the Radio - SSH.command('AT+CFUN=1', 'SIMSTORE,READY', 5) - logging.debug('\u001B[1m Cellular Functionality enabled\u001B[0m') - time.sleep(4) - # We should check if we register - count = 0 - attach_cnt = 0 - attach_status = False - while count < 5: - SSH.command('AT+CEREG?', 'OK', 5) - result = re.search('CEREG: 2,(?P<state>[0-9\-]+),', SSH.getBefore()) - if result is not None: - mDataConnectionState = int(result.group('state')) - if mDataConnectionState is not None: - if mDataConnectionState == 1: - count = 10 - attach_status = True - result = re.search('CEREG: 2,1,"(?P<networky>[0-9A-Z]+)","(?P<networkz>[0-9A-Z]+)"', SSH.getBefore()) - if result is not None: - networky = result.group('networky') - networkz = result.group('networkz') - logging.debug('\u001B[1m CAT-M module attached to eNB (' + str(networky) + '/' + str(networkz) + ')\u001B[0m') - else: - logging.debug('\u001B[1m CAT-M module attached to eNB\u001B[0m') - else: - logging.debug('+CEREG: 2,' + str(mDataConnectionState)) - attach_cnt = attach_cnt + 1 - else: - logging.debug(SSH.getBefore()) - attach_cnt = attach_cnt + 1 - count = count + 1 - time.sleep(1) - if attach_status: - SSH.command('AT+CESQ', 'OK', 5) - result = re.search('CESQ: 99,99,255,255,(?P<rsrq>[0-9]+),(?P<rsrp>[0-9]+)', SSH.getBefore()) - if result is not None: - nRSRQ = int(result.group('rsrq')) - nRSRP = int(result.group('rsrp')) - if (nRSRQ is not None) and (nRSRP is not None): - logging.debug(' RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB') - logging.debug(' RSRP = ' + str(-140+nRSRP) + ' dBm') - SSH.close() - self.picocom_closure = False - html_queue = SimpleQueue() - self.checkDevTTYisUnlocked() - if attach_status: - html_cell = '<pre style="background-color:white">CAT-M module Attachment Completed in ' + str(attach_cnt+4) + ' seconds' - if (nRSRQ is not None) and (nRSRP is not None): - html_cell += '\n RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB' - html_cell += '\n RSRP = ' + str(-140+nRSRP) + ' dBm</pre>' - else: - html_cell += '</pre>' - html_queue.put(html_cell) - HTML.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) - else: - logging.error('\u001B[1m CAT-M module Attachment Failed\u001B[0m') - html_cell = '<pre style="background-color:white">CAT-M module Attachment Failed</pre>' - html_queue.put(html_cell) - HTML.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) - self.AutoTerminateUEandeNB() - - def PingCatM(self): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - try: - statusQueue = SimpleQueue() - lock = Lock() - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5) - SSH.command('cd scripts', '\$', 5) - if re.match('OAI', EPC.GetType(), re.IGNORECASE): - logging.debug('Using the OAI EPC HSS: not implemented yet') - HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - HTML.CreateHtmlTabFooter(False) - sys.exit(1) - else: - SSH.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5) - result = re.search('Allocated ipv4 addr: (?P<ipaddr>[0-9\.]+) from Pool', SSH.getBefore()) - if result is not None: - moduleIPAddr = result.group('ipaddr') - else: - HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - device_id = 'catm' - ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + str(moduleIPAddr) + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with UE (' + str(moduleIPAddr) + ') crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore()) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore()) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - lock.acquire() - logging.debug('\u001B[1;37;44m ping result (' + moduleIPAddr + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - lock.release() - SSH.close() - html_cell = '<pre style="background-color:white">CAT-M module\nIP Address : ' + moduleIPAddr + '\n' + qMsg + '</pre>' - statusQueue.put(html_cell) - if (packetLossOK): - HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue) - else: - HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue) - self.AutoTerminateUEandeNB() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AttachUE_common(self, device_id, statusQueue, lock, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) - else: - # airplane mode off // radio on - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - time.sleep(2) - max_count = 45 - count = max_count - while count > 0: - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep -m 1 mDataConnectionState', '\$', 15) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep -m 1 mDataConnectionState', '\$', 60) - print('#GP: in SSH.getBefore() K=0 (it was K=2 in main.py)') - result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', SSH.getBefore()) - if result is None: - logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put('mDataConnectionState Not Found!') - lock.release() - break - mDataConnectionState = int(result.group('state')) - if mDataConnectionState == 2: - logging.debug('\u001B[1mUE (' + device_id + ') Attach Completed\u001B[0m') - lock.acquire() - statusQueue.put(max_count - count) - statusQueue.put(device_id) - statusQueue.put('Attach Completed') - lock.release() - break - count = count - 1 - if count == 15 or count == 30: - logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m') - if self.ADBCentralized: - if device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - time.sleep(0.5) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - time.sleep(0.5) - logging.debug('\u001B[1mWait UE (' + device_id + ') a second until mDataConnectionState=2 (' + str(max_count-count) + ' times)\u001B[0m') - time.sleep(1) - if count == 0: - logging.debug('\u001B[1;37;41m UE (' + device_id + ') Attach Failed \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put('Attach Failed') - lock.release() - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AttachUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - status_queue = SimpleQueue() - lock = Lock() - nb_ue_to_connect = 0 - for device_id in self.UEDevices: - if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach): - self.UEDevicesStatus[nb_ue_to_connect] = CONST.UE_STATUS_ATTACHING - p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,)) - p.daemon = True - p.start() - multi_jobs.append(p) - nb_ue_to_connect = nb_ue_to_connect + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - return - else: - attach_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - attach_status = False - device_id = status_queue.get() - message = status_queue.get() - if (count < 0): - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>' - else: - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds</pre>' - html_queue.put(html_cell) - if (attach_status): - cnt = 0 - while cnt < len(self.UEDevices): - if self.UEDevicesStatus[cnt] == CONST.UE_STATUS_ATTACHING: - self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED - cnt += 1 - HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - result = re.search('T_stdout', str(RAN.GetInitialize_eNB_args())) - if result is not None: - logging.debug('Waiting 5 seconds to fill up record file') - time.sleep(5) - else: - HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def DetachUE_common(self, device_id, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DetachUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - cnt = 0 - for device_id in self.UEDevices: - self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHING - p = Process(target = self.DetachUE_common, args = (device_id,cnt,)) - p.daemon = True - p.start() - multi_jobs.append(p) - cnt += 1 - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - result = re.search('T_stdout', str(RAN.GetInitialize_eNB_args())) - if result is not None: - logging.debug('Waiting 5 seconds to fill up record file') - time.sleep(5) - cnt = 0 - while cnt < len(self.UEDevices): - self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHED - cnt += 1 - - def RebootUE_common(self, device_id): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - previousmDataConnectionStates = [] - # Save mDataConnectionState - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', SSH.getBefore()) - if result is None: - logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') - sys.exit(1) - previousmDataConnectionStates.append(int(result.group('state'))) - # Reboot UE - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell reboot', '\$', 10) - time.sleep(60) - previousmDataConnectionState = previousmDataConnectionStates.pop(0) - count = 180 - while count > 0: - count = count - 1 - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', SSH.getBefore()) - if result is None: - mDataConnectionState = None - else: - mDataConnectionState = int(result.group('state')) - logging.debug('mDataConnectionState = ' + result.group('state')) - if mDataConnectionState is None or (previousmDataConnectionState == 2 and mDataConnectionState != 2): - logging.debug('\u001B[1mWait UE (' + device_id + ') a second until reboot completion (' + str(180-count) + ' times)\u001B[0m') - time.sleep(1) - else: - logging.debug('\u001B[1mUE (' + device_id + ') Reboot Completed\u001B[0m') - break - if count == 0: - logging.debug('\u001B[1;37;41m UE (' + device_id + ') Reboot Failed \u001B[0m') - sys.exit(1) - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def RebootUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) - HTML.CreateHtmlTabFooter(False) - sys.exit(1) - multi_jobs = [] - for device_id in self.UEDevices: - p = Process(target = self.RebootUE_common, args = (device_id,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def DataDisableUE_common(self, device_id, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # disable data service - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data disable"', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data disable"\'', '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Disabled Data Service\u001B[0m') - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DataDisableUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.DataDisableUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def DataEnableUE_common(self, device_id, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # enable data service - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Enabled Data Service\u001B[0m') - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DataEnableUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.DataEnableUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def GetAllUEDevices(self, terminate_ue_flag): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - SSH.command('adb devices', '\$', 15) - #self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore()) - self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore()) - SSH.close() - else: - if (os.path.isfile('./phones_list.txt')): - os.remove('./phones_list.txt') - SSH.command('ls /etc/*/phones*.txt', '\$', 5) - result = re.search('/etc/ci/phones_list.txt', SSH.getBefore()) - SSH.close() - if (result is not None) and (len(self.UEDevices) == 0): - SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, '/etc/ci/phones_list.txt', '.') - if (os.path.isfile('./phones_list.txt')): - phone_list_file = open('./phones_list.txt', 'r') - for line in phone_list_file.readlines(): - line = line.strip() - result = re.search('^#', line) - if result is not None: - continue - comma_split = line.split(",") - self.UEDevices.append(comma_split[0]) - self.UEDevicesRemoteServer.append(comma_split[1]) - self.UEDevicesRemoteUser.append(comma_split[2]) - self.UEDevicesOffCmd.append(comma_split[3]) - self.UEDevicesOnCmd.append(comma_split[4]) - self.UEDevicesRebootCmd.append(comma_split[5]) - phone_list_file.close() - - if terminate_ue_flag == True: - print('terminate_ue_flag == True') - if len(self.UEDevices) == 0: - logging.debug('\u001B[1;37;41m UE Not Found! \u001B[0m') - sys.exit(1) - if len(self.UEDevicesStatus) == 0: - print('len(self.UEDevicesStatus) == 0') - cnt = 0 - while cnt < len(self.UEDevices): - self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) - cnt += 1 - - def GetAllCatMDevices(self, terminate_ue_flag): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - SSH.command('lsusb | egrep "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15) - #self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore()) - self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore()) - else: - if (os.path.isfile('./modules_list.txt')): - os.remove('./modules_list.txt') - SSH.command('ls /etc/*/modules*.txt', '\$', 5) - result = re.search('/etc/ci/modules_list.txt', SSH.getBefore()) - SSH.close() - if result is not None: - logging.debug('Found a module list file on ADB server') - if terminate_ue_flag == True: - if len(self.CatMDevices) == 0: - logging.debug('\u001B[1;37;41m CAT-M UE Not Found! \u001B[0m') - sys.exit(1) - SSH.close() - - def CheckUEStatus_common(self, lock, device_id, statusQueue, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry"', '\$', 15) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\'', '\$', 60) - result = re.search('mServiceState=(?P<serviceState>[0-9]+)', SSH.getBefore()) - serviceState = 'Service State: UNKNOWN' - if result is not None: - lServiceState = int(result.group('serviceState')) - if lServiceState == 3: - serviceState = 'Service State: RADIO_POWERED_OFF' - if lServiceState == 1: - serviceState = 'Service State: OUT_OF_SERVICE' - if lServiceState == 0: - serviceState = 'Service State: IN_SERVICE' - if lServiceState == 2: - serviceState = 'Service State: EMERGENCY_ONLY' - result = re.search('mDataConnectionState=(?P<dataConnectionState>[0-9]+)', SSH.getBefore()) - dataConnectionState = 'Data State: UNKNOWN' - if result is not None: - lDataConnectionState = int(result.group('dataConnectionState')) - if lDataConnectionState == 0: - dataConnectionState = 'Data State: DISCONNECTED' - if lDataConnectionState == 1: - dataConnectionState = 'Data State: CONNECTING' - if lDataConnectionState == 2: - dataConnectionState = 'Data State: CONNECTED' - if lDataConnectionState == 3: - dataConnectionState = 'Data State: SUSPENDED' - result = re.search('mDataConnectionReason=(?P<dataConnectionReason>[0-9a-zA-Z_]+)', SSH.getBefore()) - dataConnectionReason = 'Data Reason: UNKNOWN' - if result is not None: - dataConnectionReason = 'Data Reason: ' + result.group('dataConnectionReason') - lock.acquire() - logging.debug('\u001B[1;37;44m Status Check (' + str(device_id) + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + serviceState + '\u001B[0m') - logging.debug('\u001B[1;34m ' + dataConnectionState + '\u001B[0m') - logging.debug('\u001B[1;34m ' + dataConnectionReason + '\u001B[0m') - statusQueue.put(0) - statusQueue.put(device_id) - qMsg = serviceState + '\n' + dataConnectionState + '\n' + dataConnectionReason - statusQueue.put(qMsg) - lock.release() - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckStatusUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) - HTML.CreateHtmlTabFooter(False) - sys.exit(1) - multi_jobs = [] - lock = Lock() - status_queue = SimpleQueue() - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.CheckUEStatus_common, args = (lock,device_id,status_queue,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd /opt/flexran_rtc', '\$', 5) - SSH.command('curl http://localhost:9999/stats | jq \'.\' > log/check_status_' + self.testCase_id + '.log 2>&1', '\$', 5) - SSH.command('cat log/check_status_' + self.testCase_id + '.log | jq \'.eNB_config[0].UE\' | grep -c rnti | sed -e "s#^#Nb Connected UE = #"', '\$', 5) - result = re.search('Nb Connected UE = (?P<nb_ues>[0-9]+)', SSH.getBefore()) - passStatus = True - if result is not None: - nb_ues = int(result.group('nb_ues')) - htmlOptions = 'Nb Connected UE(s) to eNB = ' + str(nb_ues) - logging.debug('\u001B[1;37;44m ' + htmlOptions + ' \u001B[0m') - if self.expectedNbOfConnectedUEs > -1: - if nb_ues != self.expectedNbOfConnectedUEs: - passStatus = False - else: - htmlOptions = 'N/A' - SSH.close() - else: - passStatus = True - htmlOptions = 'N/A' - - if (status_queue.empty()): - HTML.CreateHtmlTestRow(htmlOptions, 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - check_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - check_status = False - device_id = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>' - html_queue.put(html_cell) - if check_status and passStatus: - HTML.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def GetAllUEIPAddresses(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - ue_ip_status = 0 - self.UEIPAddresses = [] - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('ifconfig oaitun_ue1', '\$', 4) - result = re.search('inet addr:(?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|inet (?P<ueipaddress2>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', SSH.getBefore()) - if result is not None: - if result.group('ueipaddress') is not None: - UE_IPAddress = result.group('ueipaddress') - else: - UE_IPAddress = result.group('ueipaddress2') - logging.debug('\u001B[1mUE (' + self.UEDevices[0] + ') IP Address is ' + UE_IPAddress + '\u001B[0m') - self.UEIPAddresses.append(UE_IPAddress) - else: - logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') - ue_ip_status -= 1 - SSH.close() - return ue_ip_status - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - idx = 0 - for device_id in self.UEDevices: - print('UE status attched'+CONST.UE_STATUS_ATTACHED) - if self.UEDevicesStatus[idx] != CONST.UE_STATUS_ATTACHED: - idx += 1 - continue - count = 0 - while count < 4: - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "ip addr show | grep rmnet"', '\$', 15) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ip addr show | grep rmnet"\'', '\$', 60) - result = re.search('inet (?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+[0-9a-zA-Z\.\s]+', SSH.getBefore()) - if result is None: - logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') - time.sleep(1) - count += 1 - else: - count = 10 - if count < 9: - ue_ip_status -= 1 - continue - UE_IPAddress = result.group('ueipaddress') - logging.debug('\u001B[1mUE (' + device_id + ') IP Address is ' + UE_IPAddress + '\u001B[0m') - for ueipaddress in self.UEIPAddresses: - if ueipaddress == UE_IPAddress: - logging.debug('\u001B[1mUE (' + device_id + ') IP Address ' + UE_IPAddress + ': has already been allocated to another device !' + '\u001B[0m') - ue_ip_status -= 1 - continue - self.UEIPAddresses.append(UE_IPAddress) - idx += 1 - SSH.close() - return ue_ip_status - - def ping_iperf_wrong_exit(self, lock, UE_IPAddress, device_id, statusQueue, message): - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(message) - lock.release() - - def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue): - try: - # 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 - if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE): - launchFromEpc = False - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - - if launchFromEpc: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5) - SSH.command('cd scripts', '\$', 5) - ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) - else: - cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' - message = cmd + '\n' - logging.debug(cmd) - ret = subprocess.run(cmd, shell=True) - ping_status = ret.returncode - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cat ' + EPC.GetSourceCodePath() + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore()) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore()) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - lock.acquire() - logging.debug('\u001B[1;37;44m ping result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - if (packetLossOK): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(qMsg) - lock.release() - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def PingNoS1_wrong_exit(self, qMsg): - html_queue = SimpleQueue() - html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>' - html_queue.put(html_cell) - HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - - def PingNoS1(self): - check_eNB = True - check_OAI_UE = True - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) - if ping_from_eNB is not None: - if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - else: - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - try: - if ping_from_eNB is not None: - SSH.open(RAN.GeteNBIPAddress, RAN.GeteNBUserName, RAN.GeteNBPassword) - SSH.command('cd ' + RAN.GeteNBSourceCodePath() + '/cmake_targets/', '\$', 5) - else: - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5) - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '.log', '\$', int(ping_time[0])*1.5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with OAI UE crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore()) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore()) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - logging.debug('\u001B[1;37;44m OAI UE ping result \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - SSH.close() - html_queue = SimpleQueue() - ip_addr = 'TBD' - html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>' - html_queue.put(html_cell) - if packetLossOK: - HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - - # copying on the EPC server for logCollection - if ping_from_eNB is not None: - copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') - else: - copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') - if (copyin_res == 0): - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'ping_' + self.testCase_id + '.log', EPC.GetSourceCodePath() + '/scripts') - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def Ping(self): - result = re.search('noS1', str(RAN.GetInitialize_eNB_args())) - if result is not None: - self.PingNoS1() - return - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - check_eNB = True - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - check_OAI_UE = True - else: - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ueIpStatus = self.GetAllUEIPAddresses() - if (ueIpStatus < 0): - HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - i = 0 - lock = Lock() - status_queue = SimpleQueue() - for UE_IPAddress in self.UEIPAddresses: - device_id = self.UEDevices[i] - p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i = i + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - ping_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - ping_status = False - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' - html_queue.put(html_cell) - if (ping_status): - HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def Iperf_ComputeTime(self): - result = re.search('-t (?P<iperf_time>\d+)', str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Iperf time Not Found! \u001B[0m') - sys.exit(1) - return result.group('iperf_time') - - def Iperf_ComputeModifiedBW(self, idx, ue_num): - result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Iperf bandwidth Not Found! \u001B[0m') - sys.exit(1) - iperf_bandwidth = result.group('iperf_bandwidth') - if self.iperf_profile == 'balanced': - iperf_bandwidth_new = float(iperf_bandwidth)/ue_num - if self.iperf_profile == 'single-ue': - iperf_bandwidth_new = float(iperf_bandwidth) - if self.iperf_profile == 'unbalanced': - # residual is 2% of max bw - residualBW = float(iperf_bandwidth) / 50 - if idx == 0: - iperf_bandwidth_new = float(iperf_bandwidth) - ((ue_num - 1) * residualBW) - else: - iperf_bandwidth_new = residualBW - iperf_bandwidth_str = '-b ' + iperf_bandwidth - iperf_bandwidth_str_new = '-b ' + ('%.2f' % iperf_bandwidth_new) - result = re.sub(iperf_bandwidth_str, iperf_bandwidth_str_new, str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Calculate Iperf bandwidth Failed! \u001B[0m') - sys.exit(1) - return result - - def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - SSH.command('awk -f /tmp/tcp_iperf_stats.awk /tmp/CI-eNB/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('Avg Bitrate : (?P<average>[0-9\.]+ Mbits\/sec) Max Bitrate : (?P<maximum>[0-9\.]+ Mbits\/sec) Min Bitrate : (?P<minimum>[0-9\.]+ Mbits\/sec)', SSH.getBefore()) - if result is not None: - avgbitrate = result.group('average') - maxbitrate = result.group('maximum') - minbitrate = result.group('minimum') - lock.acquire() - logging.debug('\u001B[1;37;44m TCP iperf result (' + UE_IPAddress + ') \u001B[0m') - msg = 'TCP Stats :\n' - if avgbitrate is not None: - logging.debug('\u001B[1;34m Avg Bitrate : ' + avgbitrate + '\u001B[0m') - msg += 'Avg Bitrate : ' + avgbitrate + '\n' - if maxbitrate is not None: - logging.debug('\u001B[1;34m Max Bitrate : ' + maxbitrate + '\u001B[0m') - msg += 'Max Bitrate : ' + maxbitrate + '\n' - if minbitrate is not None: - logging.debug('\u001B[1;34m Min Bitrate : ' + minbitrate + '\u001B[0m') - msg += 'Min Bitrate : ' + minbitrate + '\n' - statusQueue.put(0) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - return 0 - - def Iperf_analyzeV2Output(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - result = re.search('-u', str(iperf_real_options)) - if result is None: - return self.Iperf_analyzeV2TCPOutput(lock, UE_IPAddress, device_id, statusQueue, iperf_real_options) - - result = re.search('Server Report:', SSH.getBefore()) - if result is None: - result = re.search('read failed: Connection refused', SSH.getBefore()) - if result is not None: - logging.debug('\u001B[1;37;41m Could not connect to iperf server! \u001B[0m') - else: - logging.debug('\u001B[1;37;41m Server Report and Connection refused Not Found! \u001B[0m') - return -1 - # Computing the requested bandwidth in float - result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(iperf_real_options)) - if result is not None: - req_bandwidth = result.group('iperf_bandwidth') - req_bw = float(req_bandwidth) - result = re.search('-b [0-9\.]+K', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Kbits/sec' % req_bw - req_bw = req_bw * 1000 - result = re.search('-b [0-9\.]+M', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Mbits/sec' % req_bw - req_bw = req_bw * 1000000 - result = re.search('-b [0-9\.]+G', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Gbits/sec' % req_bw - req_bw = req_bw * 1000000000 - - result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', SSH.getBefore()) - if result is not None: - bitrate = result.group('bitrate') - packetloss = result.group('packetloss') - jitter = result.group('jitter') - lock.acquire() - logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') - iperfStatus = True - msg = 'Req Bitrate : ' + req_bandwidth + '\n' - logging.debug('\u001B[1;34m Req Bitrate : ' + req_bandwidth + '\u001B[0m') - if bitrate is not None: - msg += 'Bitrate : ' + bitrate + '\n' - logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') - result = re.search('(?P<real_bw>[0-9\.]+) [KMG]bits/sec', str(bitrate)) - if result is not None: - actual_bw = float(str(result.group('real_bw'))) - result = re.search('[0-9\.]+ K', bitrate) - if result is not None: - actual_bw = actual_bw * 1000 - result = re.search('[0-9\.]+ M', bitrate) - if result is not None: - actual_bw = actual_bw * 1000000 - result = re.search('[0-9\.]+ G', bitrate) - if result is not None: - actual_bw = actual_bw * 1000000000 - br_loss = 100 * actual_bw / req_bw - bitperf = '%.2f ' % br_loss - msg += 'Bitrate Perf: ' + bitperf + '%\n' - logging.debug('\u001B[1;34m Bitrate Perf: ' + bitperf + '%\u001B[0m') - if packetloss is not None: - msg += 'Packet Loss : ' + packetloss + '%\n' - logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') - if float(packetloss) > float(self.iperf_packetloss_threshold): - msg += 'Packet Loss too high!\n' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - iperfStatus = False - if jitter is not None: - msg += 'Jitter : ' + jitter + '\n' - logging.debug('\u001B[1;34m Jitter : ' + jitter + '\u001B[0m') - if (iperfStatus): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - return 0 - 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')): - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') - return - # Computing the requested bandwidth in float - result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', str(iperf_real_options)) - if result is None: - logging.debug('Iperf bandwidth Not Found!') - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not compute Iperf bandwidth!') - return - else: - req_bandwidth = result.group('iperf_bandwidth') - req_bw = float(req_bandwidth) - result = re.search('-b [0-9\.]+K', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Kbits/sec' % req_bw - req_bw = req_bw * 1000 - result = re.search('-b [0-9\.]+M', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Mbits/sec' % req_bw - req_bw = req_bw * 1000000 - result = re.search('-b [0-9\.]+G', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Gbits/sec' % req_bw - req_bw = req_bw * 1000000000 - - server_file = open('iperf_server_' + self.testCase_id + '_' + device_id + '.log', 'r') - br_sum = 0.0 - ji_sum = 0.0 - pl_sum = 0 - ps_sum = 0 - row_idx = 0 - for line in server_file.readlines(): - 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') - packetlost = result.group('lostPack') - packetsent = result.group('sentPack') - br = bitrate.split(' ') - ji = jitter.split(' ') - row_idx = row_idx + 1 - curr_br = float(br[0]) - pl_sum = pl_sum + int(packetlost) - ps_sum = ps_sum + int(packetsent) - if (br[1] == 'Kbits/sec'): - curr_br = curr_br * 1000 - if (br[1] == 'Mbits/sec'): - curr_br = curr_br * 1000 * 1000 - br_sum = curr_br + br_sum - ji_sum = float(ji[0]) + ji_sum - if (row_idx > 0): - br_sum = br_sum / row_idx - ji_sum = ji_sum / row_idx - br_loss = 100 * br_sum / req_bw - if (br_sum > 1000): - br_sum = br_sum / 1000 - if (br_sum > 1000): - br_sum = br_sum / 1000 - bitrate = '%.2f Mbits/sec' % br_sum - else: - bitrate = '%.2f Kbits/sec' % br_sum - else: - bitrate = '%.2f bits/sec' % br_sum - bitperf = '%.2f ' % br_loss - bitperf += '%' - jitter = '%.2f ms' % (ji_sum) - if (ps_sum > 0): - pl = float(100 * pl_sum / ps_sum) - packetloss = '%2.1f ' % (pl) - packetloss += '%' - else: - packetloss = 'unknown' - lock.acquire() - if (br_loss < 90): - statusQueue.put(1) - else: - statusQueue.put(0) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - req_msg = 'Req Bitrate : ' + req_bandwidth - bir_msg = 'Bitrate : ' + bitrate - brl_msg = 'Bitrate Perf: ' + bitperf - jit_msg = 'Jitter : ' + jitter - pal_msg = 'Packet Loss : ' + packetloss - statusQueue.put(req_msg + '\n' + bir_msg + '\n' + brl_msg + '\n' + jit_msg + '\n' + pal_msg + '\n') - logging.debug('\u001B[1;37;45m iperf result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;35m ' + req_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + bir_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + brl_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + jit_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + pal_msg + '\u001B[0m') - lock.release() - else: - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') - - server_file.close() - - - def Iperf_analyzeV3Output(self, lock, UE_IPAddress, device_id, statusQueue): - result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P<packetloss>[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', SSH.getBefore()) - if result is None: - result = re.search('(?P<error>iperf: error - [a-zA-Z0-9 :]+)', SSH.getBefore()) - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - if result is not None: - logging.debug('\u001B[1;37;41m ' + result.group('error') + ' \u001B[0m') - statusQueue.put(result.group('error')) - else: - logging.debug('\u001B[1;37;41m Bitrate and/or Packet Loss Not Found! \u001B[0m') - statusQueue.put('Bitrate and/or Packet Loss Not Found!') - lock.release() - - bitrate = result.group('bitrate') - packetloss = result.group('packetloss') - lock.acquire() - logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') - msg = 'Bitrate : ' + bitrate + '\n' - iperfStatus = True - if packetloss is not None: - logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') - msg += 'Packet Loss : ' + packetloss + '%\n' - if float(packetloss) > float(self.iperf_packetloss_threshold): - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - msg += 'Packet Loss too high!\n' - iperfStatus = False - if (iperfStatus): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - - def Iperf_UL_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): - udpIperf = True - result = re.search('-u', str(self.iperf_args)) - if result is None: - udpIperf = False - ipnumbers = UE_IPAddress.split('.') - if (len(ipnumbers) == 4): - ipnumbers[3] = '1' - EPC_Iperf_UE_IPAddress = ipnumbers[0] + '.' + ipnumbers[1] + '.' + ipnumbers[2] + '.' + ipnumbers[3] - - # Launch iperf server on EPC side (true for ltebox and old open-air-cn0 - # But for OAI-Rel14-CUPS, we launch from python executor and we are using its IP address as iperf client address - launchFromEpc = True - if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE): - launchFromEpc = False - cmd = 'hostname -I' - ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') - if ret.stdout is not None: - EPC_Iperf_UE_IPAddress = ret.stdout.strip() - port = 5001 + idx - if launchFromEpc: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) - SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if udpIperf: - SSH.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.GetUserName(), 5) - else: - SSH.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.GetUserName(), 5) - SSH.close() - else: - if self.ueIperfVersion == self.dummyIperfVersion: - prefix = '' - else: - prefix = '' - if self.ueIperfVersion == '2.0.5': - prefix = '/opt/iperf-2.0.5/bin/' - if udpIperf: - cmd = 'nohup ' + prefix + 'iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' - else: - cmd = 'nohup ' + prefix + 'iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' - logging.debug(cmd) - subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') - time.sleep(0.5) - - # Launch iperf client on UE - if (device_id == 'OAI-UE'): - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - else: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) - iperf_time = self.Iperf_ComputeTime() - time.sleep(0.5) - - if udpIperf: - modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) - else: - modified_options = str(self.iperf_args) - modified_options = modified_options.replace('-R','') - time.sleep(0.5) - - SSH.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if (device_id == 'OAI-UE'): - iperf_status = SSH.command('iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + ' -B ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - if self.ADBCentralized: - iperf_status = SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - iperf_status = SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '"\' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - SSH.command('fromdos -o iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - SSH.command('cat iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - # TIMEOUT Case - if iperf_status < 0: - SSH.close() - message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) - SSH.close() - - # Kill iperf server on EPC side - if launchFromEpc: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('killall --signal SIGKILL iperf', EPC.GetUserName(), 5) - SSH.close() - else: - cmd = 'killall --signal SIGKILL iperf' - logging.debug(cmd) - subprocess.run(cmd, shell=True) - time.sleep(1) - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') - # in case of failure, retrieve server log - if (clientStatus == -1) or (clientStatus == -2): - if launchFromEpc: - time.sleep(1) - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - SSH.copyin(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), EPC.GetSourceCodePath() + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) - # 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.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') - - def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): - try: - logging.debug('entring Iperf_common') - # Single-UE profile -- iperf only on one UE - if self.iperf_profile == 'single-ue' and idx != 0: - return - useIperf3 = False - udpIperf = True - - self.ueIperfVersion = '2.0.5' - if (device_id != 'OAI-UE'): - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it - SSH.command('if [ ! -d ' + EPC.GetSourceCodePath() + '/scripts ]; then mkdir -p ' + EPC.GetSourceCodePath() + '/scripts ; fi', '\$', 5) - SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) - # Checking if iperf / iperf3 are installed - if self.ADBCentralized: - SSH.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ls /data/local/tmp"\'', '\$', 60) - result = re.search('iperf3', SSH.getBefore()) - if result is None: - result = re.search('iperf', SSH.getBefore()) - if result is None: - message = 'Neither iperf nor iperf3 installed on UE!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - else: - if self.ADBCentralized: - SSH.command('adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"', '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"\'', '\$', 60) - result = re.search('iperf version 2.0.5', SSH.getBefore()) - if result is not None: - self.ueIperfVersion = '2.0.5' - result = re.search('iperf version 2.0.10', SSH.getBefore()) - if result is not None: - self.ueIperfVersion = '2.0.10' - else: - useIperf3 = True - SSH.close() - else: - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('iperf --version', '\$', 5) - result = re.search('iperf version 2.0.5', SSH.getBefore()) - if result is not None: - self.ueIperfVersion = '2.0.5' - result = re.search('iperf version 2.0.10', SSH.getBefore()) - if result is not None: - self.ueIperfVersion = '2.0.10' - SSH.close() - # in case of iperf, UL has its own function - if (not useIperf3): - result = re.search('-R', str(self.iperf_args)) - if result is not None: - self.Iperf_UL_common(lock, UE_IPAddress, device_id, idx, ue_num, statusQueue) - return - - # Launch the IPERF server on the UE side for DL - if (device_id == 'OAI-UE'): - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('-u', str(self.iperf_args)) - if result is None: - SSH.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) - udpIperf = False - else: - SSH.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) - else: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) - if self.ADBCentralized: - if (useIperf3): - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) - else: - SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('-u', str(self.iperf_args)) - if result is None: - SSH.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) - udpIperf = False - else: - SSH.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) - else: - SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - SSH.command('echo $USER; nohup ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" \' 2>&1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 60) - - time.sleep(0.5) - SSH.close() - - # 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 - if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE): - launchFromEpc = False - if launchFromEpc: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) - iperf_time = self.Iperf_ComputeTime() - time.sleep(0.5) - - if udpIperf: - modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) - else: - modified_options = str(self.iperf_args) - time.sleep(0.5) - - if launchFromEpc: - SSH.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - else: - if (os.path.isfile('iperf_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_' + self.testCase_id + '_' + device_id + '.log') - if (useIperf3): - SSH.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - - clientStatus = 0 - self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue) - else: - if launchFromEpc: - iperf_status = SSH.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - if self.ueIperfVersion == self.dummyIperfVersion: - prefix = '' - else: - prefix = '' - if self.ueIperfVersion == '2.0.5': - prefix = '/opt/iperf-2.0.5/bin/' - cmd = prefix + 'iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log' - message = cmd + '\n' - logging.debug(cmd) - ret = subprocess.run(cmd, shell=True) - iperf_status = ret.returncode - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cat ' + EPC.GetSourceCodePath() + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if iperf_status < 0: - if launchFromEpc: - SSH.close() - message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) - SSH.close() - - # Kill the IPERF server that runs in background - if (device_id == 'OAI-UE'): - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('killall iperf', '\$', 5) - else: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps" | grep --color=never iperf | grep -v grep\'', '\$', 60) - result = re.search('shell +(?P<pid>\d+)', SSH.getBefore()) - if result is not None: - pid_iperf = result.group('pid') - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) - SSH.close() - # if the client report is absent, try to analyze the server log file - if (clientStatus == -1): - time.sleep(1) - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - if (device_id == 'OAI-UE'): - SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - else: - SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.GetSourceCodePath() + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - SSH.command('fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - # fromdos has to be called on the python executor not on ADB server - cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log' - subprocess.run(cmd, shell=True) - self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) - - # in case of OAI UE: - if (device_id == 'OAI-UE'): - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - if not launchFromEpc: - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') - else: - SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def IperfNoS1(self): - if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = True - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - server_on_enb = re.search('-R', str(self.iperf_args)) - if server_on_enb is not None: - iServerIPAddr = RAN.GeteNBIPAddress() - iServerUser = RAN.GeteNBUserName() - iServerPasswd = RAN.GeteNBPassword() - iClientIPAddr = self.UEIPAddress - iClientUser = self.UEUserName - iClientPasswd = self.UEPassword - else: - iServerIPAddr = self.UEIPAddress - iServerUser = self.UEUserName - iServerPasswd = self.UEPassword - iClientIPAddr = RAN.GeteNBIPAddress() - iClientUser = RAN.GeteNBUserName() - iClientPasswd = RAN.GeteNBPassword() - if self.iperf_options != 'sink': - # Starting the iperf server - SSH.open(iServerIPAddr, iServerUser, iServerPasswd) - # args SHALL be "-c client -u any" - # -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1 - # -B 10.0.1.1 -u -s -i 1 -fm - server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args)) - server_options = server_options.replace('-c','-B') - SSH.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5) - SSH.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5) - time.sleep(0.5) - SSH.close() - - # Starting the iperf client - modified_options = self.Iperf_ComputeModifiedBW(0, 1) - modified_options = modified_options.replace('-R','') - iperf_time = self.Iperf_ComputeTime() - SSH.open(iClientIPAddr, iClientUser, iClientPasswd) - SSH.command('rm -f /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', 5) - iperf_status = SSH.command('stdbuf -o0 iperf ' + modified_options + ' 2>&1 | stdbuf -o0 tee /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', int(iperf_time)*5.0) - status_queue = SimpleQueue() - lock = Lock() - if iperf_status < 0: - message = 'iperf on OAI UE crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - clientStatus = -2 - else: - if self.iperf_options == 'sink': - clientStatus = 0 - status_queue.put(0) - status_queue.put('OAI-UE') - status_queue.put('10.0.1.2') - status_queue.put('Sink Test : no check') - else: - clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) - SSH.close() - - # Stopping the iperf server - if self.iperf_options != 'sink': - SSH.open(iServerIPAddr, iServerUser, iServerPasswd) - SSH.command('killall --signal SIGKILL iperf', '\$', 5) - time.sleep(0.5) - SSH.close() - - if (clientStatus == -1): - 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) - - # copying on the EPC server for logCollection - if (clientStatus == -1): - copyin_res = SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') - if (copyin_res == 0): - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_OAI-UE.log', EPC.GetSourceCodePath() + '/scripts') - copyin_res = SSH.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log') - if (copyin_res == 0): - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_OAI-UE.log', EPC.GetSourceCodePath() + '/scripts') - iperf_noperf = False - if status_queue.empty(): - iperf_status = False - else: - iperf_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - iperf_status = False - if (count > 0): - iperf_noperf = True - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' - html_queue.put(html_cell) - if (iperf_noperf and iperf_status): - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) - elif (iperf_status): - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def Iperf(self): - result = re.search('noS1', str(RAN.GetInitialize_eNB_args())) - if result is not None: - self.IperfNoS1() - return - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - check_eNB = True - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - check_OAI_UE = True - else: - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ueIpStatus = self.GetAllUEIPAddresses() - if (ueIpStatus < 0): - logging.debug('going here') - HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB() - return - - self.dummyIperfVersion = '2.0.10' - #cmd = 'iperf --version' - #logging.debug(cmd + '\n') - #iperfStdout = subprocess.check_output(cmd, shell=True, universal_newlines=True) - #result = re.search('iperf version 2.0.5', str(iperfStdout.strip())) - #if result is not None: - # dummyIperfVersion = '2.0.5' - #result = re.search('iperf version 2.0.10', str(iperfStdout.strip())) - #if result is not None: - # dummyIperfVersion = '2.0.10' - - multi_jobs = [] - i = 0 - ue_num = len(self.UEIPAddresses) - lock = Lock() - status_queue = SimpleQueue() - logging.debug('ue_num = ' + str(ue_num)) - 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,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i = i + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - iperf_status = True - iperf_noperf = False - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - iperf_status = False - if (count > 0): - iperf_noperf = True - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' - html_queue.put(html_cell) - if (iperf_noperf and iperf_status): - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) - elif (iperf_status): - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def CheckProcessExist(self, check_eNB, check_OAI_UE): - multi_jobs = [] - status_queue = SimpleQueue() - # in noS1 config, no need to check status from EPC - # in gNB also currently no need to check - result = re.search('noS1|band78', str(RAN.GetInitialize_eNB_args())) - if result is None: - p = Process(target = EPC.CheckHSSProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = EPC.CheckMMEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = EPC.CheckSPGWProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - else: - if (check_eNB == False) and (check_OAI_UE == False): - return 0 - if check_eNB: - p = Process(target = RAN.CheckeNBProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - if check_OAI_UE: - p = Process(target = self.CheckOAIUEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - return -15 - else: - result = 0 - while (not status_queue.empty()): - status = status_queue.get() - if (status < 0): - result = status - if result == CONST.ENB_PROCESS_FAILED: - fileCheck = re.search('enb_', str(RAN.GeteNBLogFiles[0])) - if fileCheck is not None: - SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/' + RAN.GeteNBLogFiles[0], '.') - logStatus = self.AnalyzeLogFile_eNB(RAN.GeteNBLogFiles[0]) - if logStatus < 0: - result = logStatus - RAN.SeteNBLogFiles[0] = '' - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.TerminateFlexranCtrl() - return result - - def CheckOAIUEProcessExist(self, initialize_OAI_UE_flag): - multi_jobs = [] - status_queue = SimpleQueue() - if initialize_OAI_UE_flag == False: - p = Process(target = self.CheckOAIUEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - return -15 - else: - result = 0 - while (not status_queue.empty()): - status = status_queue.get() - if (status < 0): - result = status - if result == CONST.OAI_UE_PROCESS_FAILED: - fileCheck = re.search('ue_', str(self.UELogFile)) - if fileCheck is not None: - SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') - logStatus = self.AnalyzeLogFile_UE(self.UELogFile) - if logStatus < 0: - result = logStatus - return result - - def CheckOAIUEProcess(self, status_queue): - try: - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + RAN.Getair_interface() + '-uesoftmodem | grep -v grep', '\$', 5) - result = re.search(RAN.Getair_interface() + '-uesoftmodem', SSH.getBefore()) - if result is None: - logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m') - status_queue.put(CONST.OAI_UE_PROCESS_FAILED) - else: - status_queue.put(CONST.OAI_UE_PROCESS_OK) - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - -# def AnalyzeLogFile_eNB(self, eNBlogFile): -# ... - - def AnalyzeLogFile_UE(self, UElogFile): - if (not os.path.isfile('./' + UElogFile)): - return -1 - ue_log_file = open('./' + UElogFile, 'r') - exitSignalReceived = False - foundAssertion = False - msgAssertion = '' - msgLine = 0 - foundSegFault = False - foundRealTimeIssue = False - uciStatMsgCount = 0 - pdcpDataReqFailedCount = 0 - badDciCount = 0 - f1aRetransmissionCount = 0 - fatalErrorCount = 0 - macBsrTimerExpiredCount = 0 - rrcConnectionRecfgComplete = 0 - no_cell_sync_found = False - mib_found = False - frequency_found = False - plmn_found = False - nrUEFlag = False - nrDecodeMib = 0 - nrFoundDCI = 0 - nrCRCOK = 0 - mbms_messages = 0 - self.htmlUEFailureMsg = '' - for line in ue_log_file.readlines(): - result = re.search('nr_synchro_time', str(line)) - if result is not None: - nrUEFlag = True - if nrUEFlag: - result = re.search('decode mib', str(line)) - if result is not None: - nrDecodeMib += 1 - result = re.search('found 1 DCIs', str(line)) - if result is not None: - nrFoundDCI += 1 - result = re.search('CRC OK', str(line)) - if result is not None: - nrCRCOK += 1 - result = re.search('Exiting OAI softmodem', str(line)) - if result is not None: - exitSignalReceived = True - result = re.search('System error|[Ss]egmentation [Ff]ault|======= Backtrace: =========|======= Memory map: ========', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('./lte-uesoftmodem', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Aa]ssertion', str(line)) - if result is not None and not exitSignalReceived: - foundAssertion = True - result = re.search('LLL', str(line)) - if result is not None and not exitSignalReceived: - foundRealTimeIssue = True - if foundAssertion and (msgLine < 3): - msgLine += 1 - msgAssertion += str(line) - result = re.search('uci->stat', str(line)) - if result is not None and not exitSignalReceived: - uciStatMsgCount += 1 - result = re.search('PDCP data request failed', str(line)) - if result is not None and not exitSignalReceived: - pdcpDataReqFailedCount += 1 - result = re.search('bad DCI 1', str(line)) - if result is not None and not exitSignalReceived: - badDciCount += 1 - result = re.search('Format1A Retransmission but TBS are different', str(line)) - if result is not None and not exitSignalReceived: - f1aRetransmissionCount += 1 - result = re.search('FATAL ERROR', str(line)) - if result is not None and not exitSignalReceived: - fatalErrorCount += 1 - result = re.search('MAC BSR Triggered ReTxBSR Timer expiry', str(line)) - if result is not None and not exitSignalReceived: - macBsrTimerExpiredCount += 1 - result = re.search('Generating RRCConnectionReconfigurationComplete', str(line)) - if result is not None: - rrcConnectionRecfgComplete += 1 - # No cell synchronization found, abandoning - result = re.search('No cell synchronization found, abandoning', str(line)) - if result is not None: - no_cell_sync_found = True - if RAN.GeteNBmbmsEnables[0]: - result = re.search('TRIED TO PUSH MBMS DATA', str(line)) - if result is not None: - mbms_messages += 1 - result = re.search("MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P<nidcell>\d{1,3}), N_RB_DL (?P<n_rb_dl>\d{1,3}), PHICH DURATION (?P<phich_duration>\d), PHICH RESOURCE (?P<phich_resource>.{1,4}), TX_ANT (?P<tx_ant>\d)", str(line)) - if result is not None and (not mib_found): - try: - mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2) - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " nidcell = " + result.group('nidcell') - self.htmlUEFailureMsg += mibMsg - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " n_rb_dl = " + result.group('n_rb_dl') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " phich_duration = " + result.group('phich_duration') - self.htmlUEFailureMsg += mibMsg - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " phich_resource = " + result.group('phich_resource') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " tx_ant = " + result.group('tx_ant') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mib_found = True - except Exception as e: - logging.error('\033[91m' + "MIB marker was not found" + '\033[0m') - result = re.search("Measured Carrier Frequency (?P<measured_carrier_frequency>\d{1,15}) Hz", str(line)) - if result is not None and (not frequency_found): - try: - mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz' - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - frequency_found = True - except Exception as e: - logging.error('\033[91m' + "Measured Carrier Frequency not found" + '\033[0m') - result = re.search("PLMN MCC (?P<mcc>\d{1,3}), MNC (?P<mnc>\d{1,3}), TAC", str(line)) - if result is not None and (not plmn_found): - try: - mibMsg = 'PLMN MCC = ' + result.group('mcc') + ' MNC = ' + result.group('mnc') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - plmn_found = True - except Exception as e: - logging.error('\033[91m' + "PLMN not found" + '\033[0m') - result = re.search("Found (?P<operator>[\w,\s]{1,15}) \(name from internal table\)", str(line)) - if result is not None: - try: - mibMsg = "The operator is: " + result.group('operator') - self.htmlUEFailureMsg += mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - except Exception as e: - logging.error('\033[91m' + "Operator name not found" + '\033[0m') - result = re.search("SIB5 InterFreqCarrierFreq element (.{1,4})/(.{1,4})", str(line)) - if result is not None: - try: - mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2) - self.htmlUEFailureMsg += mibMsg + ' -> ' - logging.debug('\033[94m' + mibMsg + '\033[0m') - except Exception as e: - logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m') - result = re.search("DL Carrier Frequency/ARFCN : (?P<carrier_frequency>\d{1,15}/\d{1,4})", str(line)) - if result is not None: - try: - freq = result.group('carrier_frequency') - new_freq = re.sub('/[0-9]+','',freq) - float_freq = float(new_freq) / 1000000 - self.htmlUEFailureMsg += 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz' - logging.debug('\033[94m' + " DL Carrier Frequency is: " + freq + '\033[0m') - except Exception as e: - logging.error('\033[91m' + " DL Carrier Frequency not found" + '\033[0m') - result = re.search("AllowedMeasBandwidth : (?P<allowed_bandwidth>\d{1,7})", str(line)) - if result is not None: - try: - prb = result.group('allowed_bandwidth') - self.htmlUEFailureMsg += ' -- PRB: ' + prb + '\n' - logging.debug('\033[94m' + " AllowedMeasBandwidth: " + prb + '\033[0m') - except Exception as e: - logging.error('\033[91m' + " AllowedMeasBandwidth not found" + '\033[0m') - ue_log_file.close() - if rrcConnectionRecfgComplete > 0: - statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)' - logging.debug('\033[94m' + statMsg + '\033[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if nrUEFlag: - if nrDecodeMib > 0: - statMsg = 'UE showed ' + str(nrDecodeMib) + ' MIB decode message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if nrFoundDCI > 0: - statMsg = 'UE showed ' + str(nrFoundDCI) + ' DCI found message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if nrCRCOK > 0: - statMsg = 'UE showed ' + str(nrCRCOK) + ' PDSCH decoding message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if not frequency_found: - statMsg = 'NR-UE could NOT synch!' - logging.error('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if uciStatMsgCount > 0: - statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if pdcpDataReqFailedCount > 0: - statMsg = 'UE showed ' + str(pdcpDataReqFailedCount) + ' "PDCP data request failed" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if badDciCount > 0: - statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1(A)" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if f1aRetransmissionCount > 0: - statMsg = 'UE showed ' + str(f1aRetransmissionCount) + ' "Format1A Retransmission but TBS are different" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if fatalErrorCount > 0: - statMsg = 'UE showed ' + str(fatalErrorCount) + ' "FATAL ERROR:" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if macBsrTimerExpiredCount > 0: - statMsg = 'UE showed ' + str(fatalErrorCount) + ' "MAC BSR Triggered ReTxBSR Timer expiry" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if RAN.GeteNBmbmsEnables[0]: - if mbms_messages > 0: - statMsg = 'UE showed ' + str(mbms_messages) + ' "TRIED TO PUSH MBMS DATA" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - else: - statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)' - logging.debug('\u001B[1;30;41m ' + statMsg + ' \u001B[0m') - self.htmlUEFailureMsg += statMsg + '\n' - if foundSegFault: - logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') - if not nrUEFlag: - return CONST.OAI_UE_PROCESS_SEG_FAULT - else: - if not frequency_found: - return CONST.OAI_UE_PROCESS_SEG_FAULT - if foundAssertion: - logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m') - self.htmlUEFailureMsg += 'UE showed an assertion!\n' - if not nrUEFlag: - if not mib_found or not frequency_found: - return CONST.OAI_UE_PROCESS_ASSERTION - else: - if not frequency_found: - return CONST.OAI_UE_PROCESS_ASSERTION - if foundRealTimeIssue: - logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m') - self.htmlUEFailureMsg += 'UE faced real time issues!\n' - #return CONST.ENB_PROCESS_REALTIME_ISSUE - if nrUEFlag: - if not frequency_found: - return CONST.OAI_UE_PROCESS_COULD_NOT_SYNC - else: - if no_cell_sync_found and not mib_found: - logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m') - self.htmlUEFailureMsg += 'UE could not synchronize!\n' - return CONST.OAI_UE_PROCESS_COULD_NOT_SYNC - return 0 - - - def TerminateFlexranCtrl(self): - if self.flexranCtrlInstalled == False or self.flexranCtrlStarted == False: - return - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5) - time.sleep(1) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5) - time.sleep(1) - SSH.close() - self.flexranCtrlStarted = False - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def TerminateUE_common(self, device_id, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # back in airplane mode on (ie radio off) - if self.ADBCentralized: - if device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') - - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"', '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"\'', '\$', 60) - result = re.search('shell +(?P<pid>\d+)', SSH.getBefore()) - if result is not None: - pid_iperf = result.group('pid') - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"', '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def TerminateUE(self): - terminate_ue_flag = False - self.GetAllUEDevices(terminate_ue_flag) - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target= self.TerminateUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def TerminateOAIUE(self): - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - SSH.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('-uesoftmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT -r .*-uesoftmodem || true', '\$', 5) - time.sleep(10) - SSH.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('-uesoftmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL -r .*-uesoftmodem || true', '\$', 5) - time.sleep(5) - SSH.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - SSH.close() - result = re.search('ue_', str(self.UELogFile)) - if result is not None: - copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') - if (copyin_res == -1): - logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m') - self.htmlUEFailureMsg = 'Could not copy UE logfile to analyze it!' - HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE') - self.UELogFile = '' - return - logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m') - logStatus = self.AnalyzeLogFile_UE(self.UELogFile) - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is not None: - ueAction = 'Sniffing' - else: - ueAction = 'Connection' - if (logStatus < 0): - logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') - self.htmlUEFailureMsg = '<b>' + ueAction + ' Failed</b>\n' + self.htmlUEFailureMsg - HTML.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') - if RAN.Getair_interface() == 'lte': - # In case of sniffing on commercial eNBs we have random results - # Not an error then - if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): - self.Initialize_OAI_UE_args = '' - self.AutoTerminateUEandeNB() - else: - if (logStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC): - self.Initialize_OAI_UE_args = '' - self.AutoTerminateUEandeNB() - else: - logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') - self.htmlUEFailureMsg = '<b>' + ueAction + ' Completed</b>\n' + self.htmlUEFailureMsg - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - self.UELogFile = '' - else: - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def AutoTerminateUEandeNB(self): - if (self.ADBIPAddress != 'none'): - self.testCase_id = 'AUTO-KILL-UE' - RAN.SettestCase_id(self.testCase_id) - self.desc = 'Automatic Termination of UE' - self.ShowTestID() - self.TerminateUE() - if (self.Initialize_OAI_UE_args != ''): - self.testCase_id = 'AUTO-KILL-UE' - RAN.SettestCase_id(self.testCase_id) - self.desc = 'Automatic Termination of UE' - self.ShowTestID() - self.TerminateOAIUE() - if (RAN.GetInitialize_eNB_args() != ''): - self.testCase_id = 'AUTO-KILL-eNB' - RAN.SettestCase_id(self.testCase_id) - self.desc = 'Automatic Termination of eNB' - self.ShowTestID() - RAN.SeteNB_instance('0') - RAN.TerminateeNB() - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.testCase_id = 'AUTO-KILL-flexran-ctl' - RAN.SettestCase_id(self.testCase_id) - self.desc = 'Automatic Termination of FlexRan CTL' - self.ShowTestID() - self.TerminateFlexranCtrl() - RAN.SetprematureExit(True) - - def IdleSleep(self): - time.sleep(self.idle_sleep_time) - HTML.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', CONST.ALL_PROCESSES_OK) - - def X2_Status(self, idx, fileName): - cmd = "curl --silent http://" + EPC.GetIPAddress() + ":9999/stats | jq '.' > " + fileName - message = cmd + '\n' - logging.debug(cmd) - subprocess.run(cmd, shell=True) - if idx == 0: - cmd = "jq '.mac_stats | length' " + fileName - strNbEnbs = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2NbENBs = int(strNbEnbs.strip()) - cnt = 0 - while cnt < self.x2NbENBs: - cmd = "jq '.mac_stats[" + str(cnt) + "].bs_id' " + fileName - bs_id = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2ENBBsIds[idx].append(bs_id.strip()) - cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats | length' " + fileName - stNbUEs = subprocess.check_output(cmd, shell=True, universal_newlines=True) - nbUEs = int(stNbUEs.strip()) - ueIdx = 0 - self.x2ENBConnectedUEs[idx].append([]) - while ueIdx < nbUEs: - cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats[" + str(ueIdx) + "].rnti' " + fileName - rnti = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2ENBConnectedUEs[idx][cnt].append(rnti.strip()) - ueIdx += 1 - cnt += 1 - - msg = "FlexRan Controller is connected to " + str(self.x2NbENBs) + " eNB(s)" - logging.debug(msg) - message += msg + '\n' - cnt = 0 - while cnt < self.x2NbENBs: - msg = " -- eNB: " + str(self.x2ENBBsIds[idx][cnt]) + " is connected to " + str(len(self.x2ENBConnectedUEs[idx][cnt])) + " UE(s)" - logging.debug(msg) - message += msg + '\n' - ueIdx = 0 - while ueIdx < len(self.x2ENBConnectedUEs[idx][cnt]): - msg = " -- UE rnti: " + str(self.x2ENBConnectedUEs[idx][cnt][ueIdx]) - logging.debug(msg) - message += msg + '\n' - ueIdx += 1 - cnt += 1 - return message - - def Perform_X2_Handover(self): - html_queue = SimpleQueue() - fullMessage = '<pre style="background-color:white">' - msg = 'Doing X2 Handover w/ option ' + self.x2_ho_options - logging.debug(msg) - fullMessage += msg + '\n' - if self.x2_ho_options == 'network': - if self.flexranCtrlInstalled and self.flexranCtrlStarted: - self.x2ENBBsIds = [] - self.x2ENBConnectedUEs = [] - self.x2ENBBsIds.append([]) - self.x2ENBBsIds.append([]) - self.x2ENBConnectedUEs.append([]) - self.x2ENBConnectedUEs.append([]) - fullMessage += self.X2_Status(0, self.testCase_id + '_pre_ho.json') - - msg = "Activating the X2 Net control on each eNB" - logging.debug(msg) - fullMessage += msg + '\n' - eNB_cnt = self.x2NbENBs - cnt = 0 - while cnt < eNB_cnt: - cmd = "curl -XPOST http://" + EPC.GetIPAddress() + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1" - logging.debug(cmd) - fullMessage += cmd + '\n' - subprocess.run(cmd, shell=True) - cnt += 1 - # Waiting for the activation to be active - time.sleep(10) - msg = "Switching UE(s) from eNB to eNB" - logging.debug(msg) - fullMessage += msg + '\n' - cnt = 0 - while cnt < eNB_cnt: - ueIdx = 0 - while ueIdx < len(self.x2ENBConnectedUEs[0][cnt]): - cmd = "curl -XPOST http://" + EPC.GetIPAddress() + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1]) - logging.debug(cmd) - fullMessage += cmd + '\n' - subprocess.run(cmd, shell=True) - ueIdx += 1 - cnt += 1 - time.sleep(10) - # check - logging.debug("Checking the Status after X2 Handover") - fullMessage += self.X2_Status(1, self.testCase_id + '_post_ho.json') - cnt = 0 - x2Status = True - while cnt < eNB_cnt: - if len(self.x2ENBConnectedUEs[0][cnt]) == len(self.x2ENBConnectedUEs[1][cnt]): - x2Status = False - cnt += 1 - if x2Status: - msg = "X2 Handover was successful" - logging.debug(msg) - fullMessage += msg + '</pre>' - html_queue.put(fullMessage) - HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - else: - msg = "X2 Handover FAILED" - logging.error(msg) - fullMessage += msg + '</pre>' - html_queue.put(fullMessage) - HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', CONST.ALL_PROCESSES_OK) - - def LogCollectBuild(self): - if (RAN.GeteNBIPAddress() != '' and RAN.GeteNBUserName() != '' and RAN.GeteNBPassword() != ''): - IPAddress = RAN.GeteNBIPAddress() - UserName = RAN.GeteNBUserName() - Password = RAN.GeteNBPassword() - SourceCodePath = RAN.GeteNBSourceCodePath() - elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''): - IPAddress = self.UEIPAddress - UserName = self.UEUserName - Password = self.UEPassword - SourceCodePath = self.UESourceCodePath - else: - sys.exit('Insufficient Parameter') - SSH.open(IPAddress, UserName, Password) - SSH.command('cd ' + SourceCodePath, '\$', 5) - SSH.command('cd cmake_targets', '\$', 5) - SSH.command('rm -f build.log.zip', '\$', 5) - SSH.command('zip build.log.zip build_log_*/*', '\$', 60) - SSH.close() - def LogCollectPing(self): - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5) - SSH.command('cd scripts', '\$', 5) - SSH.command('rm -f ping.log.zip', '\$', 5) - SSH.command('zip ping.log.zip ping*.log', '\$', 60) - SSH.command('rm ping*.log', '\$', 5) - SSH.close() - - def LogCollectIperf(self): - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5) - SSH.command('cd scripts', '\$', 5) - SSH.command('rm -f iperf.log.zip', '\$', 5) - SSH.command('zip iperf.log.zip iperf*.log', '\$', 60) - SSH.command('rm iperf*.log', '\$', 5) - SSH.close() - - def LogCollectOAIUE(self): - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('cd ' + self.UESourceCodePath, '\$', 5) - SSH.command('cd cmake_targets', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -f ue.log.zip', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S zip ue.log.zip ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 60) - SSH.command('echo ' + self.UEPassword + ' | sudo -S rm ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 5) - SSH.close() - - def RetrieveSystemVersion(self, machine): - if RAN.GeteNBIPAddress() == 'none' or self.UEIPAddress == 'none': - self.OsVersion = 'Ubuntu 16.04.5 LTS' - self.KernelVersion = '4.15.0-45-generic' - self.UhdVersion = '3.13.0.1-0' - self.UsrpBoard = 'B210' - self.CpuNb = '4' - self.CpuModel = 'Intel(R) Core(TM) i5-6200U' - self.CpuMHz = '2399.996 MHz' - return 0 - if machine == 'eNB': - if RAN.GeteNBIPAddress() != '' and RAN.GeteNBUserName() != '' and RAN.GeteNBPassword() != '': - IPAddress = RAN.GeteNBIPAddress() - UserName = RAN.GeteNBUserName() - Password = RAN.GeteNBPassword() - else: - return -1 - if machine == 'UE': - if self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != '': - IPAddress = self.UEIPAddress - UserName = self.UEUserName - Password = self.UEPassword - else: - return -1 - - SSH.open(IPAddress, UserName, Password) - SSH.command('lsb_release -a', '\$', 5) - result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) - if result is not None: - self.OsVersion = result.group('os_type') - logging.debug('OS is: ' + self.OsVersion) - else: - SSH.command('hostnamectl', '\$', 5) - result = re.search('Operating System: (?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) - if result is not None: - self.OsVersion = result.group('os_type') - if self.OsVersion == 'CentOS Linux 7 ': - SSH.command('cat /etc/redhat-release', '\$', 5) - result = re.search('CentOS Linux release (?P<os_version>[0-9\.]+)', SSH.getBefore()) - if result is not None: - self.OsVersion = self.OsVersion.replace('7 ', result.group('os_version')) - logging.debug('OS is: ' + self.OsVersion) - SSH.command('uname -r', '\$', 5) - result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', SSH.getBefore()) - if result is not None: - self.KernelVersion = result.group('kernel_version') - logging.debug('Kernel Version is: ' + self.KernelVersion) - SSH.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) - result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', SSH.getBefore()) - if result is not None: - self.UhdVersion = result.group('uhd_version') - logging.debug('UHD Version is: ' + self.UhdVersion) - else: - SSH.command('uhd_config_info --version', '\$', 5) - result = re.search('UHD (?P<uhd_version>[a-zA-Z0-9\.\-]+)', SSH.getBefore()) - if result is not None: - self.UhdVersion = result.group('uhd_version') - logging.debug('UHD Version is: ' + self.UhdVersion) - SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 30) - usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore()) - count = 0 - for board in usrp_boards: - if count == 0: - self.UsrpBoard = board - else: - self.UsrpBoard += ',' + board - count += 1 - if count > 0: - logging.debug('USRP Board(s) : ' + self.UsrpBoard) - SSH.command('lscpu', '\$', 5) - result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', SSH.getBefore()) - if result is not None: - self.CpuNb = result.group('nb_cpus') - logging.debug('nb_cpus: ' + self.CpuNb) - self.CpuModel = result.group('model') - logging.debug('model: ' + self.CpuModel) - self.CpuMHz = result.group('cpu_mhz') + ' MHz' - logging.debug('cpu_mhz: ' + self.CpuMHz) - SSH.close() - -#----------------------------------------------------------- -# ShowTestID() -#----------------------------------------------------------- - def ShowTestID(self): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1mTest ID:' + self.testCase_id + '\u001B[0m') - logging.debug('\u001B[1m' + self.desc + '\u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - -def CheckClassValidity(action,id): - if action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover': - logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) - return False - return True - -def GetParametersFromXML(action): - if action == 'Build_eNB': - RAN.SetBuild_eNB_args(test.findtext('Build_eNB_args')) - forced_workspace_cleanup = test.findtext('forced_workspace_cleanup') - if (forced_workspace_cleanup is None): - RAN.SetBuild_eNB_forced_workspace_cleanup(False) - else: - if re.match('true', forced_workspace_cleanup, re.IGNORECASE): - RAN.SetBuild_eNB_forced_workspace_cleanup(True) - else: - RAN.SetBuild_eNB_forced_workspace_cleanup(False) - RAN.SeteNB_instance(test.findtext('eNB_instance')) - if (RAN.GeteNB_instance() is None): - RAN.SeteNB_instance('0') - RAN.SeteNB_serverId(test.findtext('eNB_serverId')) - if (RAN.GeteNB_serverId() is None): - RAN.SeteNB_serverId('0') - xmlBgBuildField = test.findtext('backgroundBuild') - if (xmlBgBuildField is None): - RAN.SetbackgroundBuild(False) - else: - if re.match('true', xmlBgBuildField, re.IGNORECASE): - RAN.SetbackgroundBuild(True) - else: - RAN.SetbackgroundBuild(False) - - if action == 'WaitEndBuild_eNB': - RAN.SetBuild_eNB_args(test.findtext('Build_eNB_args')) - RAN.SeteNB_instance(test.findtext('eNB_instance')) - if (RAN.GeteNB_instance() is None): - RAN.SeteNB_instance('0') - RAN.SeteNB_serverId(test.findtext('eNB_serverId')) - if (RAN.GeteNB_serverId() is None): - RAN.SeteNB_serverId('0') - - if action == 'Initialize_eNB': - RAN.SetInitialize_eNB_args(test.findtext('Initialize_eNB_args')) - RAN.SeteNB_instance(test.findtext('eNB_instance')) - if (RAN.GeteNB_instance() is None): - RAN.SeteNB_instance('0') - RAN.SeteNB_serverId(test.findtext('eNB_serverId')) - if (RAN.GeteNB_serverId() is None): - RAN.SeteNB_serverId('0') - CiTestObj.air_interface = test.findtext('air_interface') - if (CiTestObj.air_interface is None): - CiTestObj.air_interface = 'lte' - else: - CiTestObj.air_interface = CiTestObj.air_interface.lower() - - if action == 'Terminate_eNB': - RAN.SeteNB_instance(test.findtext('eNB_instance')) - if (RAN.GeteNB_instance() is None): - RAN.SeteNB_instance('0') - RAN.SeteNB_serverId(test.findtext('eNB_serverId')) - if (RAN.GeteNB_serverId() is None): - RAN.SeteNB_serverId('0') - CiTestObj.air_interface = test.findtext('air_interface') - if (CiTestObj.air_interface is None): - CiTestObj.air_interface = 'lte' - else: - CiTestObj.air_interface = CiTestObj.air_interface.lower() - - if action == 'Attach_UE': - nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach') - if (nbMaxUEtoAttach is None): - CiTestObj.nbMaxUEtoAttach = -1 - else: - CiTestObj.nbMaxUEtoAttach = int(nbMaxUEtoAttach) - - if action == 'CheckStatusUE': - expectedNBUE = test.findtext('expectedNbOfConnectedUEs') - if (expectedNBUE is None): - CiTestObj.expectedNbOfConnectedUEs = -1 - else: - CiTestObj.expectedNbOfConnectedUEs = int(expectedNBUE) - - if action == 'Build_OAI_UE': - CiTestObj.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args') - CiTestObj.clean_repository = test.findtext('clean_repository') - if (CiTestObj.clean_repository == 'false'): - CiTestObj.clean_repository = False - else: - CiTestObj.clean_repository = True - - if action == 'Initialize_OAI_UE': - CiTestObj.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args') - CiTestObj.UE_instance = test.findtext('UE_instance') - if (CiTestObj.UE_instance is None): - CiTestObj.UE_instance = '0' - CiTestObj.air_interface = test.findtext('air_interface') - if (CiTestObj.air_interface is None): - CiTestObj.air_interface = 'lte' - else: - CiTestObj.air_interface = SSH.air_interface.lower() - - if action == 'Terminate_OAI_UE': - RAN.SeteNB_instance(test.findtext('UE_instance')) - if (CiTestObj.UE_instance is None): - CiTestObj.UE_instance = '0' - - if action == 'Ping' or action == 'Ping_CatM_module': - CiTestObj.ping_args = test.findtext('ping_args') - CiTestObj.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold') - - if action == 'Iperf': - CiTestObj.iperf_args = test.findtext('iperf_args') - CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold') - CiTestObj.iperf_profile = test.findtext('iperf_profile') - if (CiTestObj.iperf_profile is None): - CiTestObj.iperf_profile = 'balanced' - else: - if CiTestObj.iperf_profile != 'balanced' and CiTestObj.iperf_profile != 'unbalanced' and CiTestObj.iperf_profile != 'single-ue': - logging.debug('ERROR: test-case has wrong profile ' + CiTestObj.iperf_profile) - CiTestObj.iperf_profile = 'balanced' - CiTestObj.iperf_options = test.findtext('iperf_options') - if (CiTestObj.iperf_options is None): - CiTestObj.iperf_options = 'check' - else: - if CiTestObj.iperf_options != 'check' and CiTestObj.iperf_options != 'sink': - logging.debug('ERROR: test-case has wrong option ' + CiTestObj.iperf_options) - CiTestObj.iperf_options = 'check' - - if action == 'IdleSleep': - string_field = test.findtext('idle_sleep_time_in_sec') - if (string_field is None): - CiTestObj.idle_sleep_time = 5 - else: - CiTestObj.idle_sleep_time = int(string_field) - - if action == 'Perform_X2_Handover': - string_field = test.findtext('x2_ho_options') - if (string_field is None): - CiTestObj.x2_ho_options = 'network' - else: - if string_field != 'network': - logging.error('ERROR: test-case has wrong option ' + string_field) - CiTestObj.x2_ho_options = 'network' - else: - CiTestObj.x2_ho_options = string_field - - -#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 - -def receive_signal(signum, frame): - sys.exit(1) - -#----------------------------------------------------------- -# Parameter Check -#----------------------------------------------------------- -mode = '' -CiTestObj = OaiCiTest() - -import sshconnection -import epc -import helpreadme -import ran -import html -import constants - -SSH = sshconnection.SSHConnection() -EPC = epc.EPCManagement() -RAN = ran.RANManagement() -HTML = html.HTMLManagement() - - -argvs = sys.argv -argc = len(argvs) -cwd = os.getcwd() - -while len(argvs) > 1: - myArgv = argvs.pop(1) # 0th is this file's name - - if re.match('^\-\-help$', myArgv, re.IGNORECASE): - GenericHelp(Version) - sys.exit(0) - elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE) - mode = matchReg.group(1) - elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE) - RAN.SetranRepository(matchReg.group(1)) - HTML.SetranRepository(matchReg.group(1)) - elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE) - doMerge = matchReg.group(1) - if ((doMerge == 'true') or (doMerge == 'True')): - RAN.SetranAllowMerge(True) - HTML.SetranAllowMerge(True) - elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE) - RAN.SetranBranch(matchReg.group(1)) - HTML.SetranBranch(matchReg.group(1)) - elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE) - RAN.SetranCommitID(matchReg.group(1)) - HTML.SetranCommitID(matchReg.group(1)) - elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE) - RAN.SetranTargetBranch(matchReg.group(1)) - elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNBIPAddress(matchReg.group(1)) - elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB1IPAddress(matchReg.group(1)) - elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB2IPAddress(matchReg.group(1)) - elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNBUserName(matchReg.group(1)) - elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB1UserName(matchReg.group(1)) - elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB2UserName(matchReg.group(1)) - elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNBPassword(matchReg.group(1)) - elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB1Password(matchReg.group(1)) - elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB2Password(matchReg.group(1)) - elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNBSourceCodePath(matchReg.group(1)) - elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB1SourceCodePath(matchReg.group(1)) - elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB2SourceCodePath(matchReg.group(1)) - elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) - EPC.SetIPAddress(matchReg.group(1)) -#GP250220: do we still need EPCBranch? it's not used anywhere - elif re.match('^\-\-EPCBranch=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCBranch=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.EPCBranch = matchReg.group(1) - elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE) - EPC.SetUserName(matchReg.group(1)) - elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE) - EPC.SetPassword(matchReg.group(1)) - elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - EPC.SetSourceCodePath(matchReg.group(1)) - elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE) - if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE): - EPC.SetType(matchReg.group(1)) - else: - sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS)') - elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.ADBIPAddress = matchReg.group(1) - elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.ADBUserName = matchReg.group(1) - elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE) - if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE): - if re.match('distributed', matchReg.group(1), re.IGNORECASE): - CiTestObj.ADBCentralized = False - else: - CiTestObj.ADBCentralized = True - else: - sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)') - elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.ADBPassword = matchReg.group(1) - elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.testXMLfiles.append(matchReg.group(1)) - HTML.SettestXMLfiles(matchReg.group(1)) - CiTestObj.nbTestXMLfiles += 1 - elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.UEIPAddress = matchReg.group(1) - elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.UEUserName = matchReg.group(1) - elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.UEPassword = matchReg.group(1) - elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.UESourceCodePath = matchReg.group(1) - elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE) - finalStatus = matchReg.group(1) - if ((finalStatus == 'true') or (finalStatus == 'True')): - CiTestObj.finalStatus = True - else: - GenericHelp(Version) - sys.exit('Invalid Parameter: ' + myArgv) - -if re.match('^TerminateeNB$', mode, re.IGNORECASE): - if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - RAN.SeteNB_serverId('0') - RAN.SeteNB_instance('0') - RAN.SeteNBSourceCodePath('/tmp/') - CiTestObj.TerminateeNB() -elif re.match('^TerminateUE$', mode, re.IGNORECASE): - if (CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == ''): - GenericHelp(Version) - sys.exit('Insufficient Parameter') - signal.signal(signal.SIGUSR1, receive_signal) - CiTestObj.TerminateUE() -elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE): - if CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - signal.signal(signal.SIGUSR1, receive_signal) - CiTestObj.TerminateOAIUE() -elif re.match('^TerminateHSS$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - CiTestObj.TerminateHSS() -elif re.match('^TerminateMME$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - CiTestObj.TerminateMME() -elif re.match('^TerminateSPGW$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - CiTestObj.TerminateSPGW() -elif re.match('^LogCollectBuild$', mode, re.IGNORECASE): - if (RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''): - GenericHelp(Version) - sys.exit('Insufficient Parameter') - CiTestObj.LogCollectBuild() -elif re.match('^LogCollecteNB$', mode, re.IGNORECASE): - if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - CiTestObj.LogCollecteNB() -elif re.match('^LogCollectHSS$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - EPC.LogCollectHSS() -elif re.match('^LogCollectMME$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - EPC.LogCollectMME() -elif re.match('^LogCollectSPGW$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - EPC.LogCollectSPGW() -elif re.match('^LogCollectPing$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - CiTestObj.LogCollectPing() -elif re.match('^LogCollectIperf$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - CiTestObj.LogCollectIperf() -elif re.match('^LogCollectOAIUE$', mode, re.IGNORECASE): - if CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == '': - GenericHelp(Version) - sys.exit('Insufficient Parameter') - CiTestObj.LogCollectOAIUE() -elif re.match('^InitiateHtml$', mode, re.IGNORECASE): - if (CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == ''): - GenericHelp(Version) - sys.exit('Insufficient Parameter') - count = 0 - foundCount = 0 - while (count < CiTestObj.nbTestXMLfiles): - #xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[count] - xml_test_file = sys.path[0] + "/" + CiTestObj.testXMLfiles[count] - if (os.path.isfile(xml_test_file)): - try: - xmlTree = ET.parse(xml_test_file) - except: - print("Error while parsing file: " + xml_test_file) - xmlRoot = xmlTree.getroot() - HTML.SethtmlTabRefs(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) - HTML.SethtmlTabNames(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) - HTML.SethtmlTabIcons(xmlRoot.findtext('htmlTabIcon',default='info-sign')) - #CiTestObj.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) - #CiTestObj.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count))) - #CiTestObj.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign')) - foundCount += 1 - count += 1 - if foundCount != CiTestObj.nbTestXMLfiles: - CiTestObj.nbTestXMLfiles = foundCount - HTML.SetnbTestXMLfiles(CiTestObj.nbTestXMLfiles) - - if (CiTestObj.ADBIPAddress != 'none'): - terminate_ue_flag = False - CiTestObj.GetAllUEDevices(terminate_ue_flag) - CiTestObj.GetAllCatMDevices(terminate_ue_flag) - HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices)) - HTML.SethtmlNb_Smartphones(len(CiTestObj.UEDevices)) - HTML.SethtmlNb_CATM_Modules(len(CiTestObj.CatMDevices)) - HTML.CreateHtmlHeader(CiTestObj.ADBIPAddress) -elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): - HTML.SetreseNB(RetrieveSystemVersion('eNB')) - HTML.SetresUE(RetrieveSystemVersion('UE')) - HTML.CreateHtmlFooter(CiTestObj.finalStatus) -elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE): - if re.match('^TesteNB$', mode, re.IGNORECASE): - if RAN.GeteNBIPAddress() == '' or RAN.GetranRepository() == '' or RAN.GetranBranch() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '' or EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '': - GenericHelp(Version) - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '' or EPC.GetType() == '': - EPCSrvHelp(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), EPC.GetSourceCodePath(), EPC.GetType()) - if RAN.GetranRepository() == '': - GitSrvHelp(RAN.GetranRepository(),RAN.GetranBranch(),RAN.GetranCommitID(),RAN.GetranAllowMerge(),RAN.GetranTargetBranch()) - if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '': - eNBSrvHelp(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath()) - sys.exit('Insufficient Parameter') - - if (EPC.GetIPAddress() != '') and (EPC.GetIPAddress() != 'none'): - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), cwd + "/tcp_iperf_stats.awk", "/tmp") - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), cwd + "/active_net_interfaces.awk", "/tmp") - else: - if CiTestObj.UEIPAddress == '' or RAN.GetranRepository() == '' or RAN.GetranBranch() == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == '': - GenericHelp(Version) - sys.exit('UE: Insufficient Parameter') - - #read test_case_list.xml file - # if no parameters for XML file, use default value - if (CiTestObj.nbTestXMLfiles != 1): - xml_test_file = cwd + "/test_case_list.xml" - else: - xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[0] - - xmlTree = ET.parse(xml_test_file) - xmlRoot = xmlTree.getroot() - - exclusion_tests=xmlRoot.findtext('TestCaseExclusionList',default='') - requested_tests=xmlRoot.findtext('TestCaseRequestedList',default='') - if (CiTestObj.nbTestXMLfiles == 1): - HTML.SethtmlTabRefs(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) - HTML.SethtmlTabNames(xmlRoot.findtext('htmlTabName',default='Test-0')) - #CiTestObj.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) - #CiTestObj.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0')) - repeatCount = xmlRoot.findtext('repeatCount',default='1') - CiTestObj.repeatCounts.append(int(repeatCount)) - all_tests=xmlRoot.findall('testCase') - - exclusion_tests=exclusion_tests.split() - requested_tests=requested_tests.split() - - #check that exclusion tests are well formatted - #(6 digits or less than 6 digits followed by +) - for test in exclusion_tests: - if (not re.match('^[0-9]{6}$', test) and - not re.match('^[0-9]{1,5}\+$', test)): - logging.debug('ERROR: exclusion test is invalidly formatted: ' + test) - sys.exit(1) - else: - logging.debug(test) - - #check that requested tests are well formatted - #(6 digits or less than 6 digits followed by +) - #be verbose - for test in requested_tests: - if (re.match('^[0-9]{6}$', test) or - re.match('^[0-9]{1,5}\+$', test)): - logging.debug('INFO: test group/case requested: ' + test) - else: - logging.debug('ERROR: requested test is invalidly formatted: ' + test) - sys.exit(1) - if (EPC.GetIPAddress() != '') and (EPC.GetIPAddress() != 'none'): - CiTestObj.CheckFlexranCtrlInstallation() - - #get the list of tests to be done - todo_tests=[] - for test in requested_tests: - if (test_in_list(test, exclusion_tests)): - logging.debug('INFO: test will be skipped: ' + test) - else: - #logging.debug('INFO: test will be run: ' + test) - todo_tests.append(test) - - signal.signal(signal.SIGUSR1, receive_signal) - - if (CiTestObj.ADBIPAddress != 'none'): - terminate_ue_flag = False - CiTestObj.GetAllUEDevices(terminate_ue_flag) - CiTestObj.GetAllCatMDevices(terminate_ue_flag) - else: - CiTestObj.UEDevices.append('OAI-UE') - HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices)) - HTML.CreateHtmlTabHeader() - - CiTestObj.FailReportCnt = 0 - RAN.SetprematureExit(True) - CiTestObj.startTime = int(round(time.time() * 1000)) - HTML.SetstartTime(CiTestObj.startTime) - while CiTestObj.FailReportCnt < CiTestObj.repeatCounts[0] and RAN.GetprematureExit(): - RAN.SetprematureExit(False) - # At every iteratin of the retry loop, a separator will be added - # pass CiTestObj.FailReportCnt as parameter of HTML.CreateHtmlRetrySeparator - HTML.CreateHtmlRetrySeparator(CiTestObj.FailReportCnt) - for test_case_id in todo_tests: - if RAN.GetprematureExit(): - break - for test in all_tests: - if RAN.GetprematureExit(): - break - id = test.get('id') - if test_case_id != id: - continue - CiTestObj.testCase_id = id - RAN.SettestCase_id(CiTestObj.testCase_id) - HTML.SettestCase_id(CiTestObj.testCase_id) - CiTestObj.desc = test.findtext('desc') - HTML.Setdesc(CiTestObj.desc) - action = test.findtext('class') - if (CheckClassValidity(action, id) == False): - continue - CiTestObj.ShowTestID() - GetParametersFromXML(action) - if action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Ping' or action == 'Iperf' or action == 'Reboot_UE' or action == 'DataDisable_UE' or action == 'DataEnable_UE' or action == 'CheckStatusUE': - if (CiTestObj.ADBIPAddress != 'none'): - terminate_ue_flag = False - CiTestObj.GetAllUEDevices(terminate_ue_flag) - if action == 'Build_eNB': - RAN.BuildeNB() - elif action == 'WaitEndBuild_eNB': - RAN.WaitBuildeNBisFinished() - elif action == 'Initialize_eNB': - check_eNB = False - check_OAI_UE = False - RAN.SetpStatus(CiTestObj.CheckProcessExist(check_eNB, check_OAI_UE)) - - RAN.InitializeeNB() - elif action == 'Terminate_eNB': - RAN.TerminateeNB() - elif action == 'Initialize_UE': - CiTestObj.InitializeUE() - elif action == 'Terminate_UE': - CiTestObj.TerminateUE() - elif action == 'Attach_UE': - CiTestObj.AttachUE() - elif action == 'Detach_UE': - CiTestObj.DetachUE() - elif action == 'DataDisable_UE': - CiTestObj.DataDisableUE() - elif action == 'DataEnable_UE': - CiTestObj.DataEnableUE() - elif action == 'CheckStatusUE': - CiTestObj.CheckStatusUE() - elif action == 'Build_OAI_UE': - CiTestObj.BuildOAIUE() - elif action == 'Initialize_OAI_UE': - CiTestObj.InitializeOAIUE() - elif action == 'Terminate_OAI_UE': - CiTestObj.TerminateOAIUE() - elif action == 'Initialize_CatM_module': - CiTestObj.InitializeCatM() - elif action == 'Terminate_CatM_module': - CiTestObj.TerminateCatM() - elif action == 'Attach_CatM_module': - CiTestObj.AttachCatM() - elif action == 'Detach_CatM_module': - CiTestObj.TerminateCatM() - elif action == 'Ping_CatM_module': - CiTestObj.PingCatM() - elif action == 'Ping': - CiTestObj.Ping() - elif action == 'Iperf': - CiTestObj.Iperf() - elif action == 'Reboot_UE': - CiTestObj.RebootUE() - elif action == 'Initialize_HSS': - EPC.InitializeHSS() - elif action == 'Terminate_HSS': - EPC.TerminateHSS() - elif action == 'Initialize_MME': - EPC.InitializeMME() - elif action == 'Terminate_MME': - EPC.TerminateMME() - elif action == 'Initialize_SPGW': - EPC.InitializeSPGW() - elif action == 'Terminate_SPGW': - EPC.TerminateSPGW() - elif action == 'Initialize_FlexranCtrl': - CiTestObj.InitializeFlexranCtrl() - elif action == 'Terminate_FlexranCtrl': - CiTestObj.TerminateFlexranCtrl() - elif action == 'IdleSleep': - CiTestObj.IdleSleep() - elif action == 'Perform_X2_Handover': - CiTestObj.Perform_X2_Handover() - else: - sys.exit('Invalid action') - CiTestObj.FailReportCnt += 1 - if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and RAN.GetprematureExit(): - logging.debug('Testsuite failed ' + str(CiTestObj.FailReportCnt) + ' time(s)') - HTML.CreateHtmlTabFooter(False) - sys.exit('Failed Scenario') - else: - logging.info('Testsuite passed after ' + str(CiTestObj.FailReportCnt) + ' time(s)') - HTML.CreateHtmlTabFooter(True) -else: - GenericHelp(Version) - sys.exit('Invalid mode') -sys.exit(0)