fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/41009?usp=email )
Change subject: S1GW tests: Add test cases for S1 handover procedure ......................................................................
S1GW tests: Add test cases for S1 handover procedure
The test cases expect the handover preparation and resource allocation to be passed on correctly with expected modifcation of E-RABs.
Related: SYS#7309 Change-Id: Id349c84749f7e897defa8cfd2ecd2c1f2fb52fc7 --- M s1gw/S1GW_ConnHdlr.ttcn M s1gw/S1GW_Tests.ttcn M s1gw/expected-results.xml 3 files changed, 323 insertions(+), 1 deletion(-)
Approvals: fixeria: Looks good to me, approved Jenkins Builder: Verified
diff --git a/s1gw/S1GW_ConnHdlr.ttcn b/s1gw/S1GW_ConnHdlr.ttcn index 8e01c1f..1d41d0d 100644 --- a/s1gw/S1GW_ConnHdlr.ttcn +++ b/s1gw/S1GW_ConnHdlr.ttcn @@ -68,6 +68,22 @@ iE_Extensions := omit }
+const TargetID c_TargetID := { + targeteNB_ID := { + global_ENB_ID := { + pLMNidentity := '62F210'O, + eNB_ID := { homeENB_ID := '0000000000000000000000000000'B }, + iE_Extensions := omit + }, + selected_TAI := { + pLMNidentity := '62F210'O, + tAC := '0007'O, + iE_Extensions := omit + }, + iE_Extensions := omit + } +} + type function void_fn(charstring id) runs on ConnHdlr;
function f_ConnHdlr_init(void_fn fn, charstring id, ConnHdlrPars pars) @@ -1050,6 +1066,190 @@ PFCP.send(resp); }
+function f_ConnHdlr_tx_handover_req(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id) +runs on ConnHdlr { + var template (value) E_RABToBeSetupListHOReq items; + var template (value) E_RABLevelQoSParameters qos_params; + + qos_params := valueof(ts_E_RABLevelQoSParameters); + + for (var integer i := 0; i < lengthof(erabs); i := i + 1) { + var template (value) E_RABToBeSetupItemHOReq item; + var template (value) TransportLayerAddress tla; + var ERabParams epars := erabs[i].u2c; + + tla := oct2bit(f_inet_addr(epars.tla)); + item := ts_E_RABToBeSetupItemHOReq(rab_id := erabs[i].erab_id, + tla := tla, + gtp_teid := epars.teid, + qos_params := qos_params); + items[i] := ts_E_RABToBeSetupListHOReq(item)[0]; + } + + f_ConnHdlr_tx_s1ap_from_mme(ts_S1AP_HandoverReq(mme_id := mme_ue_id, + ho_type := intralte, + cause := { radioNetwork := s1_intra_system_handover_triggered }, + max_br := ts_UEAggregateMaximumBitrate, + rab_setup_items := items, + container := '123456'O, + ue_sec_par := ts_UESecurityCapabilities, + sec_ctx := ts_SecurityContext(5, f_rnd_bitstring(256)))); +} + +function f_ConnHdlr_rx_handover_req(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id) +runs on ConnHdlr return S1AP_PDU { + var template (present) E_RABToBeSetupListHOReq items; + var S1AP_PDU pdu; + + for (var integer i := 0; i < lengthof(erabs); i := i + 1) { + var template (present) E_RABToBeSetupItemHOReq item; + var template (present) TransportLayerAddress tla; + var ERabParams epars := erabs[i].a2u; + + tla := oct2bit(f_inet_addr(epars.tla)); + item := tr_E_RABToBeSetupItemHOReq(rab_id := erabs[i].erab_id, + tla := tla, + gtp_teid := epars.teid, + qos_params := ?); + items[i] := tr_E_RABToBeSetupListHOReq(item)[0]; + } + + f_ConnHdlr_rx_s1ap_from_mme(pdu, tr_S1AP_HandoverReq(mme_id := mme_ue_id, + ho_type := intralte, + cause := { radioNetwork := s1_intra_system_handover_triggered }, + rab_setup_items := items, + container := '123456'O, + ue_sec_par := tr_UESecurityCapabilities)); + return pdu; +} + +function f_ConnHdlr_tx_handover_ack(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id, + ENB_UE_S1AP_ID enb_ue_id) +runs on ConnHdlr { + var template (value) E_RABAdmittedList items; + + for (var integer i := 0; i < lengthof(erabs); i := i + 1) { + var template (value) E_RABAdmittedItem item; + var template (value) TransportLayerAddress tla; + var ERabParams epars := erabs[i].u2a; + + tla := oct2bit(f_inet_addr(epars.tla)); + item := ts_E_RABAdmittedItem(rab_id := erabs[i].erab_id, + tla := tla, + gtp_teid := epars.teid, + dl_tla := omit, + dl_gtp_teid := omit, + ul_tla := omit, + ul_gtp_teid := omit); + items[i] := ts_E_RABAdmittedList(item)[0]; + } + + f_ConnHdlr_tx_s1ap_from_enb(ts_S1AP_HandoverAck(mme_id := mme_ue_id, + enb_id := enb_ue_id, + rab_admit_items := items, + container := '123456'O)); +} + +function f_ConnHdlr_rx_handover_ack(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id, + ENB_UE_S1AP_ID enb_ue_id) +runs on ConnHdlr return S1AP_PDU { + var template (present) E_RABAdmittedList items; + var S1AP_PDU pdu; + + for (var integer i := 0; i < lengthof(erabs); i := i + 1) { + var template (present) E_RABAdmittedItem item; + var template (present) TransportLayerAddress tla; + var ERabParams epars := erabs[i].c2u; + + tla := oct2bit(f_inet_addr(epars.tla)); + item := tr_E_RABAdmittedItem(rab_id := erabs[i].erab_id, + tla := tla, + gtp_teid := epars.teid); + items[i] := tr_E_RABAdmittedList(item)[0]; + } + + f_ConnHdlr_rx_s1ap_from_enb(pdu, tr_S1AP_HandoverAck(mme_id := mme_ue_id, + enb_id := enb_ue_id, + rab_admit_items := items, + container := '123456'O)); + return pdu; +} + +function f_ConnHdlr_tx_handover_rqd(MME_UE_S1AP_ID mme_ue_id, + ENB_UE_S1AP_ID enb_ue_id) +runs on ConnHdlr { + f_ConnHdlr_tx_s1ap_from_enb(ts_S1AP_HandoverRqd(mme_id := mme_ue_id, + enb_id := enb_ue_id, + ho_type := intralte, + cause := { radioNetwork := s1_intra_system_handover_triggered }, + target_id := c_TargetID, + container := '123456'O)); +} + +function f_ConnHdlr_rx_handover_rqd(MME_UE_S1AP_ID mme_ue_id, + ENB_UE_S1AP_ID enb_ue_id) +runs on ConnHdlr return S1AP_PDU { + var S1AP_PDU pdu; + + f_ConnHdlr_rx_s1ap_from_enb(pdu, tr_S1AP_HandoverRqd(mme_id := mme_ue_id, + enb_id := enb_ue_id, + ho_type := intralte, + cause := { radioNetwork := s1_intra_system_handover_triggered }, + target_id := c_TargetID, + container := '123456'O)); + return pdu; +} + +function f_ConnHdlr_tx_handover_cmd(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id, + ENB_UE_S1AP_ID enb_ue_id) +runs on ConnHdlr { + var template (value) E_RABSubjecttoDataForwardingList items; + + for (var integer i := 0; i < lengthof(erabs); i := i + 1) { + var template (value) E_RABDataForwardingItem item; + + item := ts_E_RABDataForwardingItem(rab_id := erabs[i].erab_id, + dl_tla := omit, + dl_gtp_teid := omit, + ul_tla := omit, + ul_gtp_teid := omit); + items[i] := ts_E_RABSubjecttoDataForwardingList(item)[0]; + } + + f_ConnHdlr_tx_s1ap_from_enb(ts_S1AP_HandoverCmd(mme_id := mme_ue_id, + enb_id := enb_ue_id, + ho_type := intralte, + rab_forward_items := items, + container := '123456'O)); +} + +function f_ConnHdlr_rx_handover_cmd(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id, + ENB_UE_S1AP_ID enb_ue_id) +runs on ConnHdlr return S1AP_PDU { + var template (present) E_RABSubjecttoDataForwardingList items; + var S1AP_PDU pdu; + + for (var integer i := 0; i < lengthof(erabs); i := i + 1) { + var template (present) E_RABDataForwardingItem item; + + item := tr_E_RABDataForwardingItem(rab_id := erabs[i].erab_id) + items[i] := tr_E_RABSubjecttoDataForwardingList(item)[0]; + } + + f_ConnHdlr_rx_s1ap_from_enb(pdu, tr_S1AP_HandoverCmd(mme_id := mme_ue_id, + enb_id := enb_ue_id, + ho_type := intralte, + rab_forward_items := items, + container := '123456'O)); + return pdu; +} + function f_ConnHdlr_session_establish(inout ERabList erabs) runs on ConnHdlr { for (var integer i := 0; i < lengthof(erabs); i := i + 1) { @@ -1415,4 +1615,84 @@ f_ConnHdlr_rx_s1ap_from_enb(pdu, tr_S1AP_UeContextReleaseCompl(mme_ue_id, enb_ue_id)); }
+function f_ConnHdlr_handover_req_() +runs on ConnHdlr { + f_ConnHdlr_handover_req(g_pars.erabs, g_pars.mme_ue_id); +} + +function f_ConnHdlr_handover_req(inout ERabList erabs, + MME_UE_S1AP_ID mme_ue_id) +runs on ConnHdlr { + const OCT8 c_SEID0 := '0000000000000000'O; + + /* This code block cannot be executed by more than one component at a time because + * the HANDOVER REQUEST triggers the IUT to send PFCP Session Establishment + * Request PDU(s), with need to be routed to the respective ConnHdlr component (us). + * As per 3GPP TS 29.244, section 7.2.2.4.2, these PFCP PDUs shall all have SEID=0, + * so that the PFCPEM component cannot route them unambiguously. This is why we + * need to ensure that only one ConnHdlr is triggering PFCP session establishment + * at the given moment of time. */ + f_Mutex_lock(__BFILE__, __LINE__); + f_PFCPEM_subscribe_seid(c_SEID0); + + log("eNB <- [S1GW <- MME]: HANDOVER REQUEST"); + f_ConnHdlr_tx_handover_req(erabs, mme_ue_id); + f_ConnHdlr_session_establish(erabs); + + /* We're done establishing PFCP sessions, so at this point we no longer expect to + * receive Session Establishment Request PDUs with SEID=0. Unregister and unlock + * the mutex, enabling other components to establish PFCP sessions after us. */ + f_PFCPEM_unsubscribe_seid(c_SEID0); + f_Mutex_unlock(__BFILE__, __LINE__); + + log("[eNB <- S1GW] <- MME: HANDOVER REQUEST"); + f_ConnHdlr_rx_handover_req(erabs, mme_ue_id); +} + +function f_ConnHdlr_handover_ack_() +runs on ConnHdlr { + f_ConnHdlr_handover_ack(g_pars.erabs, g_pars.mme_ue_id, g_pars.idx); +} + +function f_ConnHdlr_handover_ack(inout ERabList erabs, + MME_UE_S1AP_ID mme_ue_id, + ENB_UE_S1AP_ID enb_ue_id) +runs on ConnHdlr { + log("[eNB -> S1GW] -> MME: HANDOVER REQUEST ACKNOWLEDGE"); + f_ConnHdlr_tx_handover_ack(erabs, mme_ue_id, enb_ue_id); + f_ConnHdlr_session_modify(erabs); + log("eNB -> [S1GW -> MME]: HANDOVER REQUEST ACKNOWLEDGE"); + f_ConnHdlr_rx_handover_ack(erabs, mme_ue_id, enb_ue_id); +} + +function f_ConnHdlr_handover_rqd_() +runs on ConnHdlr { + f_ConnHdlr_handover_rqd(g_pars.erabs, g_pars.mme_ue_id, g_pars.idx); +} + +function f_ConnHdlr_handover_rqd(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id, + ENB_UE_S1AP_ID enb_ue_id) +runs on ConnHdlr { + log("[eNB -> S1GW] -> MME: HANDOVER REQUIRED"); + f_ConnHdlr_tx_handover_rqd(mme_ue_id, enb_ue_id); + log("eNB -> [S1GW -> MME]: HANDOVER REQUIRED"); + f_ConnHdlr_rx_handover_rqd(mme_ue_id, enb_ue_id); +} + +function f_ConnHdlr_handover_cmd_() +runs on ConnHdlr { + f_ConnHdlr_handover_cmd(g_pars.erabs, g_pars.mme_ue_id, g_pars.idx); +} + +function f_ConnHdlr_handover_cmd(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id, + ENB_UE_S1AP_ID enb_ue_id) +runs on ConnHdlr { + log("[eNB -> S1GW] -> MME: HANDOVER COMMAND"); + f_ConnHdlr_tx_handover_cmd(erabs, mme_ue_id, enb_ue_id); + log("eNB -> [S1GW -> MME]: HANDOVER COMMAND"); + f_ConnHdlr_rx_handover_cmd(erabs, mme_ue_id, enb_ue_id); +} + } diff --git a/s1gw/S1GW_Tests.ttcn b/s1gw/S1GW_Tests.ttcn index e6ce2f4..17c63cb 100644 --- a/s1gw/S1GW_Tests.ttcn +++ b/s1gw/S1GW_Tests.ttcn @@ -869,6 +869,44 @@ f_UEMuxUEList_all_done(vc_ues); }
+/* Test Handover Preparation procedures (no change in E-RAB) */ +function f_TC_handover_preparation(charstring id) runs on ConnHdlr { + f_ConnHdlr_s1ap_register(g_pars.genb_id); + f_ConnHdlr_s1ap_connect(mp_enb_bind_ip, mp_s1gw_enb_ip); + f_ConnHdlr_s1ap_setup(g_pars.genb_id); + + f_ConnHdlr_erab_setup_req_(); + f_ConnHdlr_erab_setup_rsp_(); + f_ConnHdlr_handover_rqd_(); + f_ConnHdlr_handover_cmd_(); + f_ConnHdlr_erab_release_cmd_(); + f_ConnHdlr_erab_release_rsp_(); + + f_ConnHdlr_s1ap_disconnect(); + f_ConnHdlr_s1ap_unregister(g_pars.genb_id); +} +testcase TC_handover_preparation() runs on test_CT { + f_TC_exec(refers(f_TC_handover_preparation)); +} + +/* Test Handover Resource Allocation procedures */ +function f_TC_handover_res_alloc(charstring id) runs on ConnHdlr { + f_ConnHdlr_s1ap_register(g_pars.genb_id); + f_ConnHdlr_s1ap_connect(mp_enb_bind_ip, mp_s1gw_enb_ip); + f_ConnHdlr_s1ap_setup(g_pars.genb_id); + + f_ConnHdlr_handover_req_(); + f_ConnHdlr_handover_ack_(); + f_ConnHdlr_erab_release_cmd_(); + f_ConnHdlr_erab_release_rsp_(); + + f_ConnHdlr_s1ap_disconnect(); + f_ConnHdlr_s1ap_unregister(g_pars.genb_id); +} +testcase TC_handover_res_alloc() runs on test_CT { + f_TC_exec(refers(f_TC_handover_res_alloc)); +} + function f_TC_pfcp_heartbeat(charstring id) runs on ConnHdlr { var integer rts := f_PFCPEM_get_recovery_timestamp(); var PDU_PFCP pfcp_pdu; @@ -917,6 +955,8 @@ execute( TC_uemux_initial_ctx_setup() ); execute( TC_uemux_ue_ctx_release_req() ); execute( TC_uemux_ue_ctx_release_cmd() ); + execute( TC_handover_preparation() ); + execute( TC_handover_res_alloc() ); execute( TC_pfcp_heartbeat() ); }
diff --git a/s1gw/expected-results.xml b/s1gw/expected-results.xml index a44108e..24c0fe0 100644 --- a/s1gw/expected-results.xml +++ b/s1gw/expected-results.xml @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<testsuite name='S1GW_Tests' tests='31' failures='0' errors='0' skipped='0' inconc='0' time='MASKED'> +<testsuite name='S1GW_Tests' tests='33' failures='0' errors='0' skipped='0' inconc='0' time='MASKED'> <testcase classname='S1GW_Tests' name='TC_setup' time='MASKED'/> <testcase classname='S1GW_Tests' name='TC_setup_multi' time='MASKED'/> <testcase classname='S1GW_Tests' name='TC_conn_term_by_mme' time='MASKED'/> @@ -30,5 +30,7 @@ <testcase classname='S1GW_Tests' name='TC_uemux_initial_ctx_setup' time='MASKED'/> <testcase classname='S1GW_Tests' name='TC_uemux_ue_ctx_release_req' time='MASKED'/> <testcase classname='S1GW_Tests' name='TC_uemux_ue_ctx_release_cmd' time='MASKED'/> + <testcase classname='S1GW_Tests' name='TC_handover_preparation' time='MASKED'/> + <testcase classname='S1GW_Tests' name='TC_handover_res_alloc' time='MASKED'/> <testcase classname='S1GW_Tests' name='TC_pfcp_heartbeat' time='MASKED'/> </testsuite>