diff --git a/ci-scripts/active_net_interfaces.awk b/ci-scripts/active_net_interfaces.awk deleted file mode 100644 index 6d1174c1cc..0000000000 --- a/ci-scripts/active_net_interfaces.awk +++ /dev/null @@ -1,21 +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 -# */ -/inet.*brd/{print "interfaceToUse="$NF"done"} diff --git a/ci-scripts/add_user_to_conf_file.awk b/ci-scripts/add_user_to_conf_file.awk deleted file mode 100644 index b338d5e7ac..0000000000 --- a/ci-scripts/add_user_to_conf_file.awk +++ /dev/null @@ -1,33 +0,0 @@ -BEGIN{lineIdx=0;captureUEDesc=0} -{ - if ($0 ~/UE0/) { - captureUEDesc = 1 - } - if (captureUEDesc == 1) { - captureLine[lineIdx] = $0 - lineIdx = lineIdx + 1 - } - print $0 -} -END { - for (ueIdx = 1; ueIdx < num_ues; ueIdx++) { - print "" - for (k = 0; k < lineIdx; k++) { - if (captureLine[k] ~/UE0/) { - mLine = captureLine[k] - gsub("UE0", "UE"ueIdx, mLine) - print mLine - } else { - if (captureLine[k] ~/MSIN=/) { - mLine = captureLine[k] - MSIN=sprintf("%08d", 1111+int(ueIdx)) - gsub("00001111", MSIN, mLine) - print mLine - } else { - print captureLine[k] - } - } - - } - } -} diff --git a/ci-scripts/add_user_to_subscriber_list.awk b/ci-scripts/add_user_to_subscriber_list.awk deleted file mode 100644 index 1e25990f59..0000000000 --- a/ci-scripts/add_user_to_subscriber_list.awk +++ /dev/null @@ -1,27 +0,0 @@ -BEGIN{lineIdx=0} -{ - captureLine[lineIdx] = $0 - lineIdx = lineIdx + 1 - print $0 -} -END{ - for (ueIdx = 1; ueIdx < num_ues; ueIdx++) { - for (k = 0; k < lineIdx; k++) { - if (captureLine[k] ~/UserName=/) { - mLine = captureLine[k] - MSIN=sprintf("%08d", 1111+int(ueIdx)) - gsub("00001111", MSIN, mLine) - print mLine - } else { - if (captureLine[k] ~/SubscriptionIndex/) { - mLine = captureLine[k] - MSIN=sprintf("%d", 111+int(ueIdx)) - gsub("111", MSIN, mLine) - print mLine - } else { - print captureLine[k] - } - } - } - } -} diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 2eb0a98d16..c5e99500b1 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -169,6 +169,27 @@ def AnalyzeBuildLogs(buildRoot, images, globalStatus): collectInfo[image] = files return collectInfo +# pyshark livecapture launches 2 processes: +# * One using dumpcap -i lIfs -w - (ie redirecting the packets to STDOUT) +# * One using tshark -i - -w loFile (ie capturing from STDIN from previous process) +# but in fact the packets are read by the following loop before being in fact +# really written to loFile. +# So it is mandatory to keep the loop +def LaunchPySharkCapture(lIfs, lFilter, loFile): + capture = pyshark.LiveCapture(interface=lIfs, bpf_filter=lFilter, output_file=loFile, debug=False) + for packet in capture.sniff_continuously(): + pass + +def StopPySharkCapture(testcase): + with cls_cmd.LocalCmd() as myCmd: + cmd = 'killall tshark' + myCmd.run(cmd, reportNonZero=False) + cmd = 'killall dumpcap' + myCmd.run(cmd, reportNonZero=False) + time.sleep(5) + cmd = f'mv /tmp/capture_{testcase}.pcap ../cmake_targets/log/{testcase}/.' + myCmd.run(cmd, timeout=100, reportNonZero=False) + return False #----------------------------------------------------------- # Class Declaration #----------------------------------------------------------- @@ -1183,17 +1204,6 @@ class Containerize(): self.UndeployGenObject(HTML, RAN, UE) self.exitStatus = 1 - # pyshark livecapture launches 2 processes: - # * One using dumpcap -i lIfs -w - (ie redirecting the packets to STDOUT) - # * One using tshark -i - -w loFile (ie capturing from STDIN from previous process) - # but in fact the packets are read by the following loop before being in fact - # really written to loFile. - # So it is mandatory to keep the loop - def LaunchPySharkCapture(self, lIfs, lFilter, loFile): - capture = pyshark.LiveCapture(interface=lIfs, bpf_filter=lFilter, output_file=loFile, debug=False) - for packet in capture.sniff_continuously(): - pass - def CaptureOnDockerNetworks(self): myCmd = cls_cmd.LocalCmd(d = self.yamlPath[0]) cmd = 'docker-compose -f docker-compose-ci.yml config | grep com.docker.network.bridge.name | sed -e "s@^.*name: @@"' @@ -1218,7 +1228,7 @@ class Containerize(): myCmd.run(cmd, timeout=5, reportNonZero=False) myCmd.close() return - x = threading.Thread(target = self.LaunchPySharkCapture, args = (interfaces,capture_filter,output_file,)) + x = threading.Thread(target = LaunchPySharkCapture, args = (interfaces,capture_filter,output_file,)) x.daemon = True x.start() @@ -1307,21 +1317,9 @@ class Containerize(): HTML.CreateHtmlTestRow('UE log Analysis', 'KO', logStatus) else: HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK) - - if self.tsharkStarted: - self.tsharkStarted = True - cmd = 'killall tshark' - myCmd2.run(cmd, reportNonZero=False) - cmd = 'killall dumpcap' - myCmd2.run(cmd, reportNonZero=False) - time.sleep(5) - ymlPath = self.yamlPath[0].split('/') - # The working dir is still logPath - cmd = f'mv /tmp/capture_{ymlPath[1]}.pcap .' - myCmd2.run(cmd, timeout=100, reportNonZero=False) - self.tsharkStarted = False myCmd2.close() - + if self.tsharkStarted: + self.tsharkStarted = StopPySharkCapture(ymlPath[1]) logging.debug('\u001B[1m Undeploying \u001B[0m') logging.debug(f'Working dir is back {self.yamlPath[0]}') cmd = 'docker-compose -f docker-compose-ci.yml down -v' diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 102eb1dfe7..0facb2f51a 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -66,26 +66,28 @@ import numpy as np def Iperf_ComputeModifiedBW(idx, ue_num, profile, args): result = re.search('-b\s*(?P[0-9\.]+)(?P[KMG])', str(args)) if result is None: - raise Exception('Iperf bandwidth not found or in incorrect format!') - iperf_bandwidth = result.group('iperf_bandwidth') + raise ValueError(f'requested iperf bandwidth not found in iperf options "{args}"') + iperf_bandwidth = float(result.group('iperf_bandwidth')) + if iperf_bandwidth == 0: + raise ValueError('iperf bandwidth set to 0 - invalid value') if profile == 'balanced': - iperf_bandwidth_new = float(iperf_bandwidth)/ue_num - if profile == 'single-ue': - iperf_bandwidth_new = float(iperf_bandwidth) + iperf_bandwidth_new = iperf_bandwidth/ue_num + if profile =='single-ue': + iperf_bandwidth_new = iperf_bandwidth if profile == 'unbalanced': # residual is 2% of max bw - residualBW = float(iperf_bandwidth) / 50 + residualBW = iperf_bandwidth / 50 if idx == 0: - iperf_bandwidth_new = float(iperf_bandwidth) - ((ue_num - 1) * residualBW) + iperf_bandwidth_new = iperf_bandwidth - ((ue_num - 1) * residualBW) else: iperf_bandwidth_new = residualBW iperf_bandwidth_str = result.group(0) iperf_bandwidth_unit = result.group(2) iperf_bandwidth_str_new = f"-b {'%.2f' % iperf_bandwidth_new}{iperf_bandwidth_unit}" - result = re.sub(iperf_bandwidth_str, iperf_bandwidth_str_new, str(args)) - if result is None: - raise Exception('Calculate Iperf bandwidth failed!') - return result + args_new = re.sub(iperf_bandwidth_str, iperf_bandwidth_str_new, str(args)) + if iperf_bandwidth_unit == 'K': + iperf_bandwidth_new = iperf_bandwidth_new / 1000 + return iperf_bandwidth_new, args_new def Iperf_ComputeTime(args): result = re.search('-t\s*(?P\d+)', str(args)) @@ -140,7 +142,7 @@ def Iperf_analyzeV3BIDIRJson(filename): msg += f'Receiver Bitrate UL : {receiver_bitrate_ul} Mbps\n' return (True, msg) -def Iperf_analyzeV3UDP(filename, iperf_bitrate_threshold, iperf_packetloss_threshold): +def Iperf_analyzeV3UDP(filename, iperf_bitrate_threshold, iperf_packetloss_threshold, target_bitrate): if (not os.path.isfile(filename)): return (False, 'Iperf3 UDP: Log file not present') if (os.path.getsize(filename)==0): @@ -171,15 +173,15 @@ def Iperf_analyzeV3UDP(filename, iperf_bitrate_threshold, iperf_packetloss_thres sender_bitrate = float(sender_bitrate) / 1000 if receiver_unit == 'Kbits/sec': receiver_bitrate = float(receiver_bitrate) / 1000 - br_perf = 100 * float(receiver_bitrate) / float(sender_bitrate) + br_perf = 100 * float(receiver_bitrate) / float(target_bitrate) br_perf = '%.2f ' % br_perf sender_bitrate = '%.2f ' % float(sender_bitrate) receiver_bitrate = '%.2f ' % float(receiver_bitrate) - req_msg = f'Sender Bitrate : {sender_bitrate} Mbps' - bir_msg = f'Receiver Bitrate : {receiver_bitrate} Mbps' + req_msg = f'Sender Bitrate : {sender_bitrate} Mbps' + bir_msg = f'Receiver Bitrate: {receiver_bitrate} Mbps' brl_msg = f'{br_perf}%' - jit_msg = f'Jitter : {receiver_jitter}' - pal_msg = f'Packet Loss : {receiver_packetloss} %' + jit_msg = f'Jitter : {receiver_jitter}' + pal_msg = f'Packet Loss : {receiver_packetloss} %' if float(br_perf) < float(iperf_bitrate_threshold): brl_msg = f'too low! < {iperf_bitrate_threshold}%' if float(receiver_packetloss) > float(iperf_packetloss_threshold): @@ -189,29 +191,21 @@ def Iperf_analyzeV3UDP(filename, iperf_bitrate_threshold, iperf_packetloss_thres else: return (False, 'Could not analyze iperf report') -def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetloss_threshold, iperf_opt): +def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetloss_threshold, target_bitrate): + result = None if (not os.path.isfile(server_filename)): - return (False, 'Could not analyze, server report not found!') + return (False, 'Iperf UDP: Server report not found!') + if (os.path.getsize(server_filename)==0): + return (False, 'Iperf UDP: Log file is empty') # Computing the requested bandwidth in float - req_bw = 1.0 # default iperf throughput, in Mbps - result = re.search('-b *(?P[0-9\.]+)(?P[kKMG])', iperf_opt) - if result is not None: - req_bw = float(result.group('iperf_bandwidth')) - magn = result.group('magnitude') - if magn == "k" or magn == "K": - req_bw /= 1000 - elif magn == "G": - req_bw *= 1000 - statusTemplate = '(?:|\[ *\d+\].*) +0\.0-\s*(?P[0-9\.]+) +sec +[0-9\.]+ [kKMG]Bytes +(?P[0-9\.]+) (?P[kKMG])bits\/sec +(?P[0-9\.]+) ms +(\d+\/ *\d+) +(\((?P[0-9\.]+)%\))' - + statusTemplate = r'(?:|\[ *\d+\].*) +0\.0-\s*(?P[0-9\.]+) +sec +[0-9\.]+ [kKMG]Bytes +(?P[0-9\.]+) (?P[kKMG])bits\/sec +(?P[0-9\.]+) ms +(\d+\/ *\d+) +(\((?P[0-9\.]+)%\))' with open(server_filename, 'r') as server_file: for line in server_file.readlines(): - res = re.search(statusTemplate, str(line)) - if res is not None: - result = res + result = re.search(statusTemplate, str(line)) + if result is not None: + break if result is None: return (False, 'Could not parse server report!') - bitrate = float(result.group('bitrate')) magn = result.group('magnitude') if magn == "k" or magn == "K": @@ -220,16 +214,16 @@ def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetlos bitrate *= 1000 jitter = float(result.group('jitter')) packetloss = float(result.group('packetloss')) - br_perf = float(bitrate)/float(req_bw) * 100 + br_perf = float(bitrate)/float(target_bitrate) * 100 br_perf = '%.2f ' % br_perf result = float(br_perf) >= float(iperf_bitrate_threshold) and float(packetloss) <= float(iperf_packetloss_threshold) - req_msg = f'Req Bitrate : {req_bw}' - bir_msg = f'Bitrate : {bitrate}' + req_msg = f'Req Bitrate : {target_bitrate}' + bir_msg = f'Bitrate : {bitrate}' brl_msg = f'Bitrate Perf: {br_perf} %' if float(br_perf) < float(iperf_bitrate_threshold): brl_msg += f' (too low! <{iperf_bitrate_threshold}%)' - jit_msg = f'Jitter : {jitter}' + jit_msg = f'Jitter : {jitter}' pal_msg = f'Packet Loss : {packetloss}' if float(packetloss) > float(iperf_packetloss_threshold): pal_msg += f' (too high! >{self.iperf_packetloss_threshold}%)' @@ -801,7 +795,7 @@ class OaiCiTest(): logPath = f'../cmake_targets/log/{ymlPath[1]}' if udpIperf: - iperf_opt = Iperf_ComputeModifiedBW(idx, ue_num, self.iperf_profile, self.iperf_args) + target_bitrate, iperf_opt = Iperf_ComputeModifiedBW(idx, ue_num, self.iperf_profile, self.iperf_args) # note: for UDP testing we don't want to use json report - reports 0 Mbps received bitrate jsonReport = "" # note: enable server report collection on the UE side, no need to store and collect server report separately on the server side @@ -819,7 +813,7 @@ class OaiCiTest(): cmd_svr.run(f'{svr.getCmdPrefix()} iperf -c {ueIP} -B {svrIP} {iperf_opt} -i1 2>&1 | tee {client_filename}', timeout=iperf_time*1.5) cmd_ue.run(f'cp {client_filename} {logPath}/{client_filename}') cmd_ue.run(f'cp {server_filename} {logPath}/{server_filename}') - status, msg = Iperf_analyzeV2UDP(server_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, iperf_opt) + status, msg = Iperf_analyzeV2UDP(server_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate) else: with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr: port = 5002 + idx @@ -835,7 +829,7 @@ class OaiCiTest(): else: cmd_ue.copyin(f'/tmp/{client_filename}', client_filename) if udpIperf: - status, msg = Iperf_analyzeV3UDP(client_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold) + status, msg = Iperf_analyzeV3UDP(client_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate) elif bidirIperf: status, msg = Iperf_analyzeV3BIDIRJson(client_filename) else: diff --git a/ci-scripts/main.py b/ci-scripts/main.py index ad93646de9..2387032e37 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -611,10 +611,6 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '': HELP.eNBSrvHelp(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath) sys.exit('Insufficient Parameter') - - if (EPC.IPAddress!= '') and (EPC.IPAddress != 'none'): - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, cwd + "/tcp_iperf_stats.awk", "/tmp") - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 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 == '': HELP.GenericHelp(CONST.Version) diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 52b9c79abf..afa6036c7e 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -366,7 +366,6 @@ class RANManagement(): self.testCase_id = HTML.testCase_id mySSH = SSH.SSHConnection() cwd = os.getcwd() - mySSH.copyout(lIpAddr,lUserName,lPassWord, cwd + "/active_net_interfaces.awk", "/tmp") #Get pcap on enb and/or gnb if enabled in the xml if self.eNB_Trace=='yes': diff --git a/ci-scripts/tcp_iperf_stats.awk b/ci-scripts/tcp_iperf_stats.awk deleted file mode 100644 index b21bf16a2f..0000000000 --- a/ci-scripts/tcp_iperf_stats.awk +++ /dev/null @@ -1,38 +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 -# */ -BEGIN{max=0;min=10000} -{ - if ($0 ~/Mbits/) { - if ($0 ~/KBytes/) { - split($0,a,"KBytes") - } else { - split($0,a,"MBytes") - } - split(a[2],b) - if (b[1]>max) { - max=b[1] - } - if (b[1]