From 36a9f701115a00250c4fba6695532f54180beca8 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 19 Jul 2019 16:06:04 +0200 Subject: [PATCH] CI: initial support for X2 HO (net control) Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 23 +- ci-scripts/main.py | 198 +++++++++++++++++- .../xml_files/f1_usrp210_band7_test_05mhz.xml | 1 - ...x2ho_enb_usrp210_band13_full_terminate.xml | 46 ++++ ...x2ho_enb_usrp210_band13_test_05mhz_tm1.xml | 166 ++++----------- 5 files changed, 297 insertions(+), 137 deletions(-) create mode 100644 ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 36ee747982..ed7489aa93 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -44,7 +44,7 @@ pipeline { disableConcurrentBuilds() timestamps() gitLabConnection('OAI GitLab') - gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13", "Test-IF4p5-TDD-Band38-Multi-RRU"]) + gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13", "Test-IF4p5-TDD-Band38-Multi-RRU" , "Test-Mono-FDD-Band13-X2-HO"]) ansiColor('xterm') } @@ -481,6 +481,26 @@ pipeline { } } } + stage ("Test X2 Handover - FDD - Band 13 - B210") { + steps { + script { + sh "sleep 60" + triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-X2HO-B210', 'Test-Mono-FDD-Band13-X2-HO') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-CI-MONO-FDD-Band13-X2HO-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } stage ("Test IF4p5 - TDD - Band 38 - B210 - MultiRRU") { steps { script { @@ -523,6 +543,7 @@ pipeline { stage ("Test MONOLITHIC - FDD - Band 13 - B210") { steps { script { + sh "sleep 60" triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-B210', 'Test-Mono-FDD-Band13') } } diff --git a/ci-scripts/main.py b/ci-scripts/main.py index fd8d8c9b6c..8a0b10d257 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -63,6 +63,12 @@ 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 #----------------------------------------------------------- @@ -144,6 +150,10 @@ class SSHConnection(): 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 = [] @@ -792,7 +802,10 @@ class SSHConnection(): # 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 - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + 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() @@ -1179,7 +1192,10 @@ class SSHConnection(): def AttachUE_common(self, device_id, statusQueue, lock): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) + 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) time.sleep(2) max_count = 45 count = max_count @@ -1206,9 +1222,15 @@ class SSHConnection(): count = count - 1 if count == 15 or count == 30: logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m') - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + 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) time.sleep(0.5) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) + 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) 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) @@ -1285,7 +1307,10 @@ class SSHConnection(): def DetachUE_common(self, device_id): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + 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) logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') self.close() except: @@ -2678,7 +2703,36 @@ class SSHConnection(): 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[0-9]+)', self.eNBOptions[int(self.eNB_instance)]) res2 = re.search('max_rxgain (?P[0-9]+)', str(line)) @@ -2806,6 +2860,14 @@ class SSHConnection(): 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: @@ -3272,6 +3334,116 @@ class SSHConnection(): 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 = '
'
+		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 + '
' + html_queue.put(fullMessage) + self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) + else: + msg = "X2 Handover FAILED" + logging.error(msg) + fullMessage += msg + '' + 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 @@ -3785,7 +3957,7 @@ def Usage(): 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': + 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 @@ -3884,6 +4056,18 @@ def GetParametersFromXML(action): 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): @@ -4292,6 +4476,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re SSH.TerminateFlexranCtrl() elif action == 'IdleSleep': SSH.IdleSleep() + elif action == 'Perform_X2_Handover': + SSH.Perform_X2_Handover() else: sys.exit('Invalid action') if SSH.prematureExit: diff --git a/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml b/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml index 2399511301..c2a48037ba 100644 --- a/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml +++ b/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml @@ -24,7 +24,6 @@ test-f1-05 Test-F1-CU-DU-05MHz tasks - 4 2 030201 diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml new file mode 100644 index 0000000000..91280462b7 --- /dev/null +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml @@ -0,0 +1,46 @@ + + + test-x2-ho-full-end + Test-X2-HO-Full-Terminate + tasks + + 030201 030202 + + + + + Terminate_eNB + Terminate Master eNB + 0 + 0 + + + + Terminate_eNB + Terminate Slave eNB + 1 + 1 + + + diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml index 7acd27ccb9..400ccb3b89 100644 --- a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml @@ -19,27 +19,25 @@ For more information about the OpenAirInterface (OAI) Software Alliance: contact@openairinterface.org - 030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201 - 030102 000010 040301 040502 000011 040302 000001 000012 040303 000002 000013 040503 040401 040201 030201 - 030103 000020 040301 040504 000021 040302 000001 000022 040303 000002 040504 000023 040401 040201 030201 + 030101 000002 030102 040301 040501 040601 040641 050401 000002 040502 040602 040642 050402 000002 040503 040603 040643 040401 040201 030201 030202 --> - test-05-tm1 - Test-05MHz-TM1 + test-x2-ho-05-tm1 + Test-X2-HO-FDD-05MHz-TM1 tasks 030201 030202 040101 050102 - 030101 000002 030102 000001 030201 030202 + 030101 000002 030102 040301 040501 050401 000002 040502 050402 000002 040503 040401 040201 030201 030202 050202 IdleSleep - Waiting for 35 seconds - 35 + Waiting for 60 seconds + 60 @@ -48,54 +46,6 @@ 10 - - CheckStatusUE - Check UE(s) status before attachment - 0 - - - - CheckStatusUE - Check UE(s) status before data disabling - 2 - - - - CheckStatusUE - Check UE(s) status after data disabling - 0 - - - - CheckStatusUE - Check UE(s) status after data re-enabling - 2 - - - - CheckStatusUE - Check UE(s) status before attachment - 0 - - - - CheckStatusUE - Check UE(s) status before data disabling - 2 - - - - CheckStatusUE - Check UE(s) status after data disabling - 0 - - - - CheckStatusUE - Check UE(s) status after data re-enabling - 2 - - Initialize_FlexranCtrl Starting Flexran Controller @@ -122,12 +72,6 @@ 1 - - Initialize_eNB - Initialize eNB (FDD/Band7/5MHz) for RRC Inactivity Timer testing -- with FlexRan Ctl - -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf - - Terminate_eNB Terminate Master eNB @@ -162,16 +106,6 @@ Detach UE - - DataDisable_UE - Disabling Data Service on UE - - - - DataEnable_UE - Enabling Data Service on UE - - Ping ping (5MHz - 20 sec) @@ -193,90 +127,64 @@ 5 - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 + + Iperf + iperf (5MHz - DL/8Mbps/UDP)(30 sec) + -u -b 8M -t 30 -i 1 + 50 + single-ue - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 + + Iperf + iperf (5MHz - DL/8Mbps/UDP)(30 sec) + -u -b 8M -t 30 -i 1 + 50 + single-ue Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) - -u -b 15M -t 30 -i 1 - 50 - balanced - - - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) - -u -b 15M -t 30 -i 1 + iperf (5MHz - DL/8Mbps/UDP)(30 sec) + -u -b 8M -t 30 -i 1 50 single-ue - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile) - -u -b 15M -t 30 -i 1 - 50 - unbalanced - - - - Iperf - iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - - - - Iperf - iperf (5MHz - DL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm - 50 - balanced - - Iperf - iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) - -u -b 9M -t 30 -i 1 -R + iperf (5MHz - UL/5Mbps/UDP)(30 sec) + -u -b 5M -t 30 -i 1 -R 50 - balanced + single-ue Iperf - iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) - -u -b 9M -t 30 -i 1 -R + iperf (5MHz - UL/5Mbps/UDP)(30 sec) + -u -b 5M -t 30 -i 1 -R 50 single-ue Iperf - iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm -R + iperf (5MHz - UL/5Mbps/UDP)(30 sec) + -u -b 5M -t 30 -i 1 -R 50 single-ue - - Iperf - iperf (5MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm -R - 50 - balanced + + Perform_X2_Handover + Doing a Flexran-Controlled X2 Handover + network + + + + Perform_X2_Handover + Doing a Flexran-Controlled X2 Handover + network