diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index f32e8b38646196b406836b45d2602190f639037b..63b707aa748a79db8c90eb049b9672f7e70cbe99 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -36,6 +36,7 @@ import re # reg import logging import os import shutil +import subprocess import time from multiprocessing import Process, Lock, SimpleQueue from zipfile import ZipFile @@ -76,6 +77,9 @@ class Containerize(): self.eNB_instance = 0 self.eNB_serverId = ['', '', ''] self.yamlPath = ['', '', ''] + self.services = ['', '', ''] + self.nb_healthy = [0, 0, 0] + self.exitStatus = 0 self.eNB_logFile = ['', '', ''] self.testCase_id = '' @@ -89,6 +93,14 @@ class Containerize(): self.allImagesSize = {} self.collectInfo = {} + self.pingContName = '' + self.pingOptions = '' + self.pingLossThreshold = '' + self.svrContName = '' + self.svrOptions = '' + self.cliContName = '' + self.cliOptions = '' + #----------------------------------------------------------- # Container management functions #----------------------------------------------------------- @@ -476,7 +488,6 @@ class Containerize(): HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) def UndeployObject(self, HTML, RAN): - logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m') if self.eNB_serverId[self.eNB_instance] == '0': lIpAddr = self.eNBIPAddress lUserName = self.eNBUserName @@ -529,4 +540,307 @@ class Containerize(): HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus) else: HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) + logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m') + + def DeployGenObject(self, HTML): + self.exitStatus = 0 + logging.info('\u001B[1m Checking Services to deploy\u001B[0m') + cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose config --services' + logging.debug(cmd) + try: + listServices = subprocess.check_output(cmd, shell=True, universal_newlines=True) + except Exception as e: + self.exitStatus = 1 + HTML.CreateHtmlTestRow('SVC not Found', 'KO', CONST.ALL_PROCESSES_OK) + return + for reqSvc in self.services[0].split(' '): + res = re.search(reqSvc, listServices) + if res is None: + logging.error(reqSvc + ' not found in specified docker-compose') + self.exitStatus = 1 + if (self.exitStatus == 1): + HTML.CreateHtmlTestRow('SVC not Found', 'KO', CONST.ALL_PROCESSES_OK) + return + + if (self.ranAllowMerge): + cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@ci-temp@" docker-compose.y*ml > docker-compose-ci.yml' + else: + cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@develop@" docker-compose.y*ml > docker-compose-ci.yml' + logging.debug(cmd) + subprocess.run(cmd, shell=True) + + cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml up -d ' + self.services[0] + logging.debug(cmd) + try: + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30) + except Exception as e: + self.exitStatus = 1 + logging.error('Could not deploy') + HTML.CreateHtmlTestRow('Could not deploy', 'KO', CONST.ALL_PROCESSES_OK) + return + + logging.info('\u001B[1m Checking if all deployed healthy\u001B[0m') + cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml ps -a' + count = 0 + healthy = 0 + while (count < 10): + count += 1 + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + healthy = 0 + for state in deployStatus.split('\n'): + res = re.search('Up \(healthy\)', state) + if res is not None: + healthy += 1 + if healthy == self.nb_healthy[0]: + count = 100 + else: + time.sleep(10) + + # HACK TO REMOVE LATER WHEN FIX + res = re.search('oai-nr-ue', self.services[0]) + if res is not None: + cmd = 'docker exec rfsim5g-oai-nr-ue /bin/bash -c "ip route del default"' + logging.debug(cmd) + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + cmd = 'docker exec rfsim5g-oai-nr-ue /bin/bash -c "ip route del 12.1.1.0/24"' + logging.debug(cmd) + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + cmd = 'docker exec rfsim5g-oai-nr-ue /bin/bash -c "ip route add default via 12.1.1.2 dev oaitun_ue1"' + logging.debug(cmd) + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + # END OF HACK TO REMOVE LATER WHEN FIX + + if count == 100 and healthy == self.nb_healthy[0]: + HTML.CreateHtmlTestRow('n/a', 'OK', CONST.ALL_PROCESSES_OK) + logging.info('\u001B[1m Deploying OAI Object(s) PASS\u001B[0m') + else: + self.exitStatus = 1 + HTML.CreateHtmlTestRow('Could not deploy in time', 'KO', CONST.ALL_PROCESSES_OK) + logging.error('\u001B[1m Deploying OAI Object(s) FAILED\u001B[0m') + + def UndeployGenObject(self, HTML): + self.exitStatus = 0 + + if (self.ranAllowMerge): + cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@ci-temp@" docker-compose.y*ml > docker-compose-ci.yml' + else: + cmd = 'cd ' + self.yamlPath[0] + ' && sed -e "s@develop@develop@" docker-compose.y*ml > docker-compose-ci.yml' + logging.debug(cmd) + subprocess.run(cmd, shell=True) + +# if the containers are running, recover the logs! + cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml ps --all' + logging.debug(cmd) + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + anyLogs = False + for state in deployStatus.split('\n'): + res = re.search('Name|----------', state) + if res is not None: + continue + if len(state) == 0: + continue + res = re.search('^(?P<container_name>[a-zA-Z0-9\-\_]+) ', state) + if res is not None: + anyLogs = True + cName = res.group('container_name') + cmd = 'cd ' + self.yamlPath[0] + ' && docker logs ' + cName + ' > ' + cName + '.log 2>&1' + logging.debug(cmd) + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + if anyLogs: + cmd = 'mkdir -p ../cmake_targets/log && mv ' + self.yamlPath[0] + '/*.log ../cmake_targets/log' + logging.debug(cmd) + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + + cmd = 'cd ' + self.yamlPath[0] + ' && docker-compose -f docker-compose-ci.yml down' + logging.debug(cmd) + try: + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100) + except Exception as e: + self.exitStatus = 1 + logging.error('Could not undeploy') + HTML.CreateHtmlTestRow('Could not undeploy', 'KO', CONST.ALL_PROCESSES_OK) + logging.error('\u001B[1m Undeploying OAI Object(s) FAILED\u001B[0m') + return + + HTML.CreateHtmlTestRow('n/a', 'OK', CONST.ALL_PROCESSES_OK) + logging.info('\u001B[1m Undeploying OAI Object(s) PASS\u001B[0m') + + def PingFromContainer(self, HTML): + self.exitStatus = 0 + cmd = 'mkdir -p ../cmake_targets/log' + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + + cmd = 'docker exec ' + self.pingContName + ' /bin/bash -c "ping ' + self.pingOptions + '" 2>&1 | tee ../cmake_targets/log/ping_' + HTML.testCase_id + '.log' + logging.debug(cmd) + deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100) + + result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', deployStatus) + if result is None: + self.PingExit(HTML, False, 'Packet Loss Not Found') + return + + packetloss = result.group('packetloss') + if float(packetloss) == 100: + self.PingExit(HTML, False, 'Packet Loss is 100%') + 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', deployStatus) + if result is None: + self.PingExit(HTML, False, 'Ping RTT_Min RTT_Avg RTT_Max Not Found!') + 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' + + message = 'ping result\n' + message += ' ' + pal_msg + '\n' + message += ' ' + min_msg + '\n' + message += ' ' + avg_msg + '\n' + message += ' ' + max_msg + '\n' + packetLossOK = True + if float(packetloss) > float(self.pingLossThreshold): + message += '\nPacket Loss too high' + packetLossOK = False + elif float(packetloss) > 0: + message += '\nPacket Loss is not 0%' + self.PingExit(HTML, packetLossOK, message) + + if packetLossOK: + logging.debug('\u001B[1;37;44m 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') + logging.info('\u001B[1m Ping Test PASS\u001B[0m') + + def PingExit(self, HTML, status, message): + html_queue = SimpleQueue() + html_cell = '<pre style="background-color:white">UE\n' + message + '</pre>' + html_queue.put(html_cell) + if status: + HTML.CreateHtmlTestRowQueue(self.pingOptions, 'OK', 1, html_queue) + else: + self.exitStatus = 1 + logging.error('\u001B[1;37;41m ' + message + ' \u001B[0m') + HTML.CreateHtmlTestRowQueue(self.pingOptions, 'KO', 1, html_queue) + + def IperfFromContainer(self, HTML): + self.exitStatus = 0 + + cmd = 'mkdir -p ../cmake_targets/log' + logStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + + # Start the server process + cmd = 'docker exec -d ' + self.svrContName + ' /bin/bash -c "nohup iperf ' + self.svrOptions + ' > /tmp/iperf_server.log 2>&1"' + logging.debug(cmd) + serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + time.sleep(5) + + # Start the client process + cmd = 'docker exec ' + self.cliContName + ' /bin/bash -c "iperf ' + self.cliOptions + '" 2>&1 | tee ../cmake_targets/log/iperf_client_' + HTML.testCase_id + '.log' + logging.debug(cmd) + clientStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100) + + # Stop the server process + cmd = 'docker exec ' + self.svrContName + ' /bin/bash -c "pkill iperf"' + logging.debug(cmd) + serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + time.sleep(5) + cmd = 'docker cp ' + self.svrContName + ':/tmp/iperf_server.log ../cmake_targets/log/iperf_server_' + HTML.testCase_id + '.log' + logging.debug(cmd) + serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) + + # Analyze client output + result = re.search('Server Report:', clientStatus) + if result is None: + result = re.search('read failed: Connection refused', clientStatus) + if result is not None: + message = 'Could not connect to iperf server!' + else: + message = 'Server Report and Connection refused Not Found!' + self.IperfExit(HTML, False, message) + return + + # Computing the requested bandwidth in float + result = re.search('-b (?P<iperf_bandwidth>[0-9\.]+)[KMG]', self.cliOptions) + if result is not None: + req_bandwidth = result.group('iperf_bandwidth') + req_bw = float(req_bandwidth) + result = re.search('-b [0-9\.]+K', self.cliOptions) + if result is not None: + req_bandwidth = '%.1f Kbits/sec' % req_bw + req_bw = req_bw * 1000 + result = re.search('-b [0-9\.]+M', self.cliOptions) + if result is not None: + req_bandwidth = '%.1f Mbits/sec' % req_bw + req_bw = req_bw * 1000000 + + reportLine = None + reportLineFound = False + for iLine in clientStatus.split('\n'): + if reportLineFound: + reportLine = iLine + reportLineFound = False + res = re.search('Server Report:', iLine) + if res is not None: + reportLineFound = True + result = None + if reportLine is not None: + result = re.search('(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/ ..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', reportLine) + iperfStatus = True + if result is not None: + bitrate = result.group('bitrate') + packetloss = result.group('packetloss') + jitter = result.group('jitter') + logging.debug('\u001B[1;37;44m iperf result \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 + br_loss = 100 * actual_bw / req_bw + if br_loss < 90: + iperfStatus = False + 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(5): + 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') + self.IperfExit(HTML, iperfStatus, msg) + else: + logging.error('problem?') + if iperfStatus: + logging.info('\u001B[1m Iperf Test PASS\u001B[0m') + + def IperfExit(self, HTML, status, message): + html_queue = SimpleQueue() + html_cell = '<pre style="background-color:white">UE\n' + message + '</pre>' + html_queue.put(html_cell) + if status: + HTML.CreateHtmlTestRowQueue(self.cliOptions, 'OK', 1, html_queue) + else: + self.exitStatus = 1 + HTML.CreateHtmlTestRowQueue(self.cliOptions, 'KO', 1, html_queue) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 8a76d8dbce5482d26f330a4596b0b39ac50911b2..f87fc1ed9c04f1df697aaf510a256421b6398c81 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -372,6 +372,41 @@ def GetParametersFromXML(action): if (string_field is not None): CONTAINERS.yamlPath[CONTAINERS.eNB_instance] = string_field + elif action == 'DeployGenObject' or action == 'UndeployGenObject': + string_field=test.findtext('yaml_path') + if (string_field is not None): + CONTAINERS.yamlPath[0] = string_field + string_field=test.findtext('services') + if (string_field is not None): + CONTAINERS.services[0] = string_field + string_field=test.findtext('nb_healthy') + if (string_field is not None): + CONTAINERS.nb_healthy[0] = int(string_field) + + elif action == 'PingFromContainer': + string_field = test.findtext('container_name') + if (string_field is not None): + CONTAINERS.pingContName = string_field + string_field = test.findtext('options') + if (string_field is not None): + CONTAINERS.pingOptions = string_field + string_field = test.findtext('loss_threshold') + if (string_field is not None): + CONTAINERS.pingLossThreshold = string_field + + elif action == 'IperfFromContainer': + string_field = test.findtext('server_container_name') + if (string_field is not None): + CONTAINERS.svrContName = string_field + string_field = test.findtext('server_options') + if (string_field is not None): + CONTAINERS.svrOptions = string_field + string_field = test.findtext('client_container_name') + if (string_field is not None): + CONTAINERS.cliContName = string_field + string_field = test.findtext('client_options') + if (string_field is not None): + CONTAINERS.cliOptions = string_field else: # ie action == 'Run_PhySim': ldpc.runargs = test.findtext('physim_run_args') @@ -479,6 +514,8 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE): if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') + if RAN.eNBIPAddress == 'none': + sys.exit(0) RAN.eNB_instance=0 RAN.eNB_serverId[0]='0' RAN.eNBSourceCodePath='/tmp/' @@ -514,11 +551,15 @@ elif re.match('^LogCollectBuild$', mode, re.IGNORECASE): if (RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''): HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') + if RAN.eNBIPAddress == 'none': + sys.exit(0) CiTestObj.LogCollectBuild(RAN) elif re.match('^LogCollecteNB$', mode, re.IGNORECASE): if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') + if RAN.eNBIPAddress == 'none': + sys.exit(0) RAN.LogCollecteNB() elif re.match('^LogCollectHSS$', mode, re.IGNORECASE): if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '': @@ -802,7 +843,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re elif action == 'Build_PhySim': HTML=ldpc.Build_PhySim(HTML,CONST) if ldpc.exitStatus==1: - RAN.prematureExit = False + RAN.prematureExit = True elif action == 'Run_PhySim': HTML=ldpc.Run_PhySim(HTML,CONST,id) elif action == 'Build_Image': @@ -815,9 +856,25 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re SCA.CppCheckAnalysis(HTML) elif action == 'Deploy_Run_PhySim': PHYSIM.Deploy_PhySim(HTML, RAN) + elif action == 'DeployGenObject': + CONTAINERS.DeployGenObject(HTML) + if CONTAINERS.exitStatus==1: + RAN.prematureExit = True + elif action == 'UndeployGenObject': + CONTAINERS.UndeployGenObject(HTML) + if CONTAINERS.exitStatus==1: + RAN.prematureExit = True + elif action == 'PingFromContainer': + CONTAINERS.PingFromContainer(HTML) + if CONTAINERS.exitStatus==1: + RAN.prematureExit = True + elif action == 'IperfFromContainer': + CONTAINERS.IperfFromContainer(HTML) + if CONTAINERS.exitStatus==1: + RAN.prematureExit = True else: sys.exit('Invalid class (action) from xml') - if not RAN.prematureExit: + if RAN.prematureExit: if CiTestObj.testCase_id == CiTestObj.testMinStableId: logging.debug('Scenario has reached minimal stability point') CiTestObj.testStabilityPointReached = True diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml index a43e5b79c01a33b54146edad0976624e8ccb523e..d8e1b26a215ddabafbea38471a0c6f0b34e71f86 100755 --- a/ci-scripts/xml_class_list.yml +++ b/ci-scripts/xml_class_list.yml @@ -41,3 +41,7 @@ - Undeploy_Object - Cppcheck_Analysis - Deploy_Run_PhySim + - DeployGenObject + - UndeployGenObject + - PingFromContainer + - IperfFromContainer diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml new file mode 100644 index 0000000000000000000000000000000000000000..8847c1189429ec8acc3f9f18d71a5d064a2a141e --- /dev/null +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -0,0 +1,103 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>rfsim-5gnr</htmlTabRef> + <htmlTabName>Testing 5G NR RF sim in containers</htmlTabName> + <htmlTabIcon>wrench</htmlTabIcon> + <TestCaseRequestedList> + 000001 + 000002 + 000003 + 020001 + 020002 + 030001 + 030002 + 100001 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="000001"> + <class>DeployGenObject</class> + <desc>Deploy OAI 5G CoreNetwork</desc> + <yaml_path>yaml_files/5g_rfsimulator</yaml_path> + <services>mysql oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn</services> + <nb_healthy>6</nb_healthy> + </testCase> + + <testCase id="000002"> + <class>DeployGenObject</class> + <desc>Deploy OAI 5G gNB RF sim SA</desc> + <yaml_path>yaml_files/5g_rfsimulator</yaml_path> + <services>oai-gnb</services> + <nb_healthy>7</nb_healthy> + </testCase> + + <testCase id="000003"> + <class>DeployGenObject</class> + <desc>Deploy OAI 5G NR-UE RF sim SA</desc> + <yaml_path>yaml_files/5g_rfsimulator</yaml_path> + <services>oai-nr-ue</services> + <nb_healthy>8</nb_healthy> + </testCase> + + <testCase id="020001"> + <class>PingFromContainer</class> + <desc>Ping ext-dn from NR-UE</desc> + <container_name>rfsim5g-oai-nr-ue</container_name> + <options>-I oaitun_ue1 -c 20 192.168.72.135</options> + <loss_threshold>5</loss_threshold> + </testCase> + + <testCase id="020002"> + <class>PingFromContainer</class> + <desc>Ping NR-UE from ext-dn</desc> + <container_name>rfsim5g-oai-ext-dn</container_name> + <options>-c 20 12.1.1.2</options> + <loss_threshold>5</loss_threshold> + </testCase> + + <testCase id="030001"> + <class>IperfFromContainer</class> + <desc>Iperf UDP Downlink</desc> + <server_container_name>rfsim5g-oai-nr-ue</server_container_name> + <client_container_name>rfsim5g-oai-ext-dn</client_container_name> + <server_options>-B 12.1.1.2 -u -i 1 -s</server_options> + <client_options>-c 12.1.1.2 -u -i 1 -t 30 -b 400K</client_options> + </testCase> + + <testCase id="030002"> + <class>IperfFromContainer</class> + <desc>Iperf UDP Uplink</desc> + <server_container_name>rfsim5g-oai-ext-dn</server_container_name> + <client_container_name>rfsim5g-oai-nr-ue</client_container_name> + <server_options>-u -i 1 -s</server_options> + <client_options>-B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 30 -b 20K</client_options> + </testCase> + + <testCase id="100001"> + <class>UndeployGenObject</class> + <desc>Undeploy all OAI 5G stack</desc> + <yaml_path>yaml_files/5g_rfsimulator</yaml_path> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/container_5g_rfsim_down.xml b/ci-scripts/xml_files/container_5g_rfsim_down.xml new file mode 100644 index 0000000000000000000000000000000000000000..57b0f67a214c297fe86648559e29aaf04012c1f7 --- /dev/null +++ b/ci-scripts/xml_files/container_5g_rfsim_down.xml @@ -0,0 +1,38 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>rfsim-5gnr-down</htmlTabRef> + <htmlTabName>CleanUp 5G RF</htmlTabName> + <htmlTabIcon>trash</htmlTabIcon> + <TestCaseRequestedList> + 100002 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="100002"> + <class>UndeployGenObject</class> + <desc>Undeploy all OAI 5G stack</desc> + <yaml_path>yaml_files/5g_rfsimulator</yaml_path> + </testCase> + +</testCaseList> diff --git a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml index 02cf95bc5910c7452278c047f38b743ba8296e84..5da7a353ab3ccc373d9d7830c85775be06fb5dea 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml @@ -206,7 +206,7 @@ services: privileged: true container_name: rfsim5g-oai-ext-dn entrypoint: /bin/bash -c \ - "apt update; apt install -y iptables iproute2 iperf iputils-ping;"\ + "apt update; apt install -y procps iptables iproute2 iperf iputils-ping;"\ "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\ "ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity" depends_on: