fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/38279?usp=email )
Change subject: s1gw: add testcases for INITIAL CONTEXT SETUP ......................................................................
s1gw: add testcases for INITIAL CONTEXT SETUP
Change-Id: I72e3ab932fee1de0fce8ddf4041b8f2174416bc1 --- M s1gw/S1GW_ConnHdlr.ttcn M s1gw/S1GW_Tests.ttcn M s1gw/expected-results.xml 3 files changed, 192 insertions(+), 1 deletion(-)
Approvals: pespin: Looks good to me, but someone else must approve fixeria: Looks good to me, approved laforge: Looks good to me, but someone else must approve Jenkins Builder: Verified
diff --git a/s1gw/S1GW_ConnHdlr.ttcn b/s1gw/S1GW_ConnHdlr.ttcn index 97df4c0..775f44c 100644 --- a/s1gw/S1GW_ConnHdlr.ttcn +++ b/s1gw/S1GW_ConnHdlr.ttcn @@ -501,6 +501,110 @@ return pdu; }
+function f_ConnHdlr_tx_initial_ctx_setup_req(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id := c_MME_UE_ID) +runs on ConnHdlr { + var template (value) E_RABToBeSetupListCtxtSUReq items; + var template (value) E_RABLevelQoSParameters qos_params; + var ENB_UE_S1AP_ID enb_ue_id := g_pars.idx; + + qos_params := valueof(ts_E_RABLevelQoSParameters); + + for (var integer i := 0; i < lengthof(erabs); i := i + 1) { + var template (value) E_RABToBeSetupItemCtxtSUReq item; + var template (value) TransportLayerAddress tla; + var ERabParams epars := erabs[i].u2c; + + tla := oct2bit(f_inet_addr(epars.tla)); + item := ts_E_RABToBeSetupItemCtxtSUReq(rab_id := erabs[i].erab_id, + qos_params := qos_params, + tla := tla, + gtp_teid := epars.teid, + nas_pdu := omit); + items[i] := ts_E_RABToBeSetupListCtxtSUReq(item)[0]; + } + + f_ConnHdlr_tx_s1ap_from_mme(ts_S1AP_IntialCtxSetupReq(mme_id := mme_ue_id, + enb_id := enb_ue_id, + max_br := ts_UEAggregateMaximumBitrate, + rab_setup_items := items, + ue_sec_par := ts_UESecurityCapabilities, + sec_key := f_rnd_bitstring(256))); +} + +function f_ConnHdlr_rx_initial_ctx_setup_req(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id := c_MME_UE_ID) +runs on ConnHdlr return S1AP_PDU { + var template (present) E_RABToBeSetupListCtxtSUReq items; + var ENB_UE_S1AP_ID enb_ue_id := g_pars.idx; + var S1AP_PDU pdu; + + for (var integer i := 0; i < lengthof(erabs); i := i + 1) { + var template (present) E_RABToBeSetupItemCtxtSUReq item; + var template (present) TransportLayerAddress tla; + var ERabParams epars := erabs[i].a2u; + + tla := oct2bit(f_inet_addr(epars.tla)); + item := tr_E_RABToBeSetupItemCtxtSUReq(rab_id := erabs[i].erab_id, + qos_params := ?, + tla := tla, + gtp_teid := epars.teid, + nas_pdu := omit); + items[i] := tr_E_RABToBeSetupListCtxtSUReq(item)[0]; + } + + f_ConnHdlr_rx_s1ap_from_mme(pdu, tr_S1AP_IntialCtxSetupReq(mme_id := mme_ue_id, + enb_id := enb_ue_id, + max_br := tr_UEAggregateMaximumBitrate, + rab_setup_items := items, + ue_sec_par := tr_UESecurityCapabilities)); + return pdu; +} + +function f_ConnHdlr_tx_initial_ctx_setup_rsp(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id := c_MME_UE_ID) +runs on ConnHdlr { + var template (value) E_RABSetupListCtxtSURes items; + var ENB_UE_S1AP_ID enb_ue_id := g_pars.idx; + + for (var integer i := 0; i < lengthof(erabs); i := i + 1) { + var template (value) E_RABSetupItemCtxtSURes item; + var template (value) TransportLayerAddress tla; + var ERabParams epars := erabs[i].u2a; + + tla := oct2bit(f_inet_addr(epars.tla)); + item := ts_S1AP_RABSetupItemCtxtSURes(rab_id := erabs[i].erab_id, + tla := tla, + gtp_teid := epars.teid); + items[i] := ts_S1AP_RABSetupListCtxtSURes(item)[0]; + } + + f_ConnHdlr_tx_s1ap_from_enb(ts_S1AP_InitialCtxSetupResp(mme_ue_id, enb_ue_id, items)); +} + +function f_ConnHdlr_rx_initial_ctx_setup_rsp(in ERabList erabs, + MME_UE_S1AP_ID mme_ue_id := c_MME_UE_ID) +runs on ConnHdlr return S1AP_PDU { + var template (present) E_RABSetupListCtxtSURes items; + var ENB_UE_S1AP_ID enb_ue_id := g_pars.idx; + var S1AP_PDU pdu; + + for (var integer i := 0; i < lengthof(erabs); i := i + 1) { + var template (present) E_RABSetupItemCtxtSURes item; + var template (present) TransportLayerAddress tla; + var ERabParams epars := erabs[i].c2u; + + tla := oct2bit(f_inet_addr(epars.tla)); + item := tr_S1AP_RABSetupItemCtxtSURes(rab_id := erabs[i].erab_id, + tla := tla, + gtp_teid := epars.teid); + items[i] := tr_S1AP_RABSetupListCtxtSURes(item)[0]; + } + + f_ConnHdlr_rx_s1ap_from_enb(pdu, tr_S1AP_InitialCtxSetupResp(mme_ue_id, enb_ue_id, items)); + return pdu; +} + function f_ConnHdlr_rx_session_establish_req(in ERab erab) runs on ConnHdlr return PDU_PFCP { var OCT4 addr := f_inet_addr(g_pars.pfcp_rem_addr); @@ -725,4 +829,41 @@ f_ConnHdlr_rx_erab_release_ind(erabs, cause); }
+function f_ConnHdlr_initial_ctx_setup_req(inout ERabList erabs) +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 S1AP E-RAB SETUP 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]: INITIAL CONTEXT SETUP REQUEST"); + f_ConnHdlr_tx_initial_ctx_setup_req(erabs); + 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: INITIAL CONTEXT SETUP REQUEST"); + f_ConnHdlr_rx_initial_ctx_setup_req(erabs); +} + +function f_ConnHdlr_initial_ctx_setup_rsp(inout ERabList erabs) +runs on ConnHdlr { + log("[eNB -> S1GW] -> MME: INITIAL CONTEXT SETUP RESPONSE"); + f_ConnHdlr_tx_initial_ctx_setup_rsp(erabs); + f_ConnHdlr_session_modify(erabs); + log("eNB -> [S1GW -> MME]: INITIAL CONTEXT SETUP RESPONSE"); + f_ConnHdlr_rx_initial_ctx_setup_rsp(erabs); +} + } diff --git a/s1gw/S1GW_Tests.ttcn b/s1gw/S1GW_Tests.ttcn index 9713c1a..2e8ebcb 100644 --- a/s1gw/S1GW_Tests.ttcn +++ b/s1gw/S1GW_Tests.ttcn @@ -366,6 +366,48 @@ vc_conn.done; }
+/* Test INITIAL CONTEXT SETUP procedure */ +function f_TC_initial_ctx_setup(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_initial_ctx_setup_req(g_pars.erabs); + f_ConnHdlr_initial_ctx_setup_rsp(g_pars.erabs); + + f_ConnHdlr_s1ap_disconnect(); + f_ConnHdlr_s1ap_unregister(g_pars.genb_id); +} +private function f_TC_initial_ctx_setup_exec(integer num_enbs, integer num_erabs) +runs on test_CT { + var ConnHdlrList vc_conns; + + f_init(); + + for (var integer i := 0; i < num_enbs; i := i + 1) { + var ConnHdlrPars pars := valueof(t_ConnHdlrPars(i, num_erabs)); + vc_conns[i] := f_ConnHdlr_spawn(refers(f_TC_initial_ctx_setup), pars); + } + + f_ConnHdlrList_all_done(vc_conns); +} +/* 1 E-RAB at a time, single eNB */ +testcase TC_initial_ctx_setup() runs on test_CT { + f_TC_initial_ctx_setup_exec(num_enbs := 1, num_erabs := 1); +} +/* 1 E-RAB at a time, multiple eNB connections */ +testcase TC_initial_ctx_setup_multi() runs on test_CT { + f_TC_initial_ctx_setup_exec(num_enbs := mp_multi_enb_num, num_erabs := 1); +} +/* 3 E-RABs at a time, single eNB */ +testcase TC_initial_ctx_setup3() runs on test_CT { + f_TC_initial_ctx_setup_exec(num_enbs := 1, num_erabs := 3); +} +/* 3 E-RABs at a time, multiple eNB connections */ +testcase TC_initial_ctx_setup3_multi() runs on test_CT { + f_TC_initial_ctx_setup_exec(num_enbs := mp_multi_enb_num, num_erabs := 3); +} + function f_TC_pfcp_heartbeat(charstring id) runs on ConnHdlr { var integer rts := f_PFCPEM_get_recovery_timestamp(); var PDU_PFCP pfcp_pdu; @@ -399,6 +441,10 @@ execute( TC_e_rab_setup_multi() ); execute( TC_e_rab_setup3_multi() ); execute( TC_e_rab_release_ind() ); + execute( TC_initial_ctx_setup() ); + execute( TC_initial_ctx_setup3() ); + execute( TC_initial_ctx_setup_multi() ); + execute( TC_initial_ctx_setup3_multi() ); execute( TC_pfcp_heartbeat() ); }
diff --git a/s1gw/expected-results.xml b/s1gw/expected-results.xml index 9075dc3..e50f978 100644 --- a/s1gw/expected-results.xml +++ b/s1gw/expected-results.xml @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<testsuite name='S1GW_Tests' tests='10' failures='0' errors='0' skipped='0' inconc='0' time='MASKED'> +<testsuite name='S1GW_Tests' tests='14' 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'/> @@ -9,5 +9,9 @@ <testcase classname='S1GW_Tests' name='TC_e_rab_setup_multi' time='MASKED'/> <testcase classname='S1GW_Tests' name='TC_e_rab_setup3_multi' time='MASKED'/> <testcase classname='S1GW_Tests' name='TC_e_rab_release_ind' time='MASKED'/> + <testcase classname='S1GW_Tests' name='TC_initial_ctx_setup' time='MASKED'/> + <testcase classname='S1GW_Tests' name='TC_initial_ctx_setup3' time='MASKED'/> + <testcase classname='S1GW_Tests' name='TC_initial_ctx_setup_multi' time='MASKED'/> + <testcase classname='S1GW_Tests' name='TC_initial_ctx_setup3_multi' time='MASKED'/> <testcase classname='S1GW_Tests' name='TC_pfcp_heartbeat' time='MASKED'/> </testsuite>