fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-s1gw/+/41492?usp=email )
Change subject: s1ap_proxy_test: add TCs simulating late E-RAB SETUP Rsp ......................................................................
s1ap_proxy_test: add TCs simulating late E-RAB SETUP Rsp
It happens quite often in production that a UE context is being established and then released even before the eNB acknowledges its establishment. Add a unit tests for this scenario, preparing for a follow-up patch making the E-RAB FSM more flexible. The PDUs triggering late E-RAB SETUP Rsp event are currently being dropped because they reference no longer existing E-RABs.
Change-Id: I60882c728ff06fb71cc458e807a49ca8ba5adcff Related: SYS#7738, SYS#7599 --- M test/s1ap_proxy_test.erl 1 file changed, 77 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-s1gw refs/changes/92/41492/1
diff --git a/test/s1ap_proxy_test.erl b/test/s1ap_proxy_test.erl index b1c0e44..eebbb49 100644 --- a/test/s1ap_proxy_test.erl +++ b/test/s1ap_proxy_test.erl @@ -57,6 +57,8 @@ ?TC(fun test_e_rab_setup/1)}, {"E-RAB SETUP REQUEST (failure)", ?TC(fun test_e_rab_setup_req_fail/1)}, + {"E-RAB SETUP RESPONSE during RELEASE", + ?TC(fun test_e_rab_setup_rsp_during_release/1)}, {"E-RAB SETUP REQUEST (duplicate)", ?TC(fun test_e_rab_setup_dup/1)}, {"E-RAB RELEASE COMMAND/RESPONSE", @@ -77,6 +79,8 @@ ?TC(fun test_initial_context_setup/1)}, {"INITIAL CONTEXT SETUP REQUEST/RESPONSE (duplicate)", ?TC(fun test_initial_context_setup_dup/1)}, + {"INITIAL CONTEXT SETUP RESPONSE during RELEASE", + ?TC(fun test_initial_context_setup_rsp_during_release/1)}, {"HANDOVER REQUIRED/COMMAND", ?TC(fun test_handover_preparation/1)}, {"HANDOVER REQUEST/REQUEST ACKNOWLEDGE", @@ -160,6 +164,40 @@ ?_assertEqual([], s1ap_proxy:fetch_erab_list(Pid))].
+test_e_rab_setup_rsp_during_release(#{handler := Pid}) -> + %% [eNB <- MME] E-RAB SETUP REQUEST + SetupReqIn = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C), + SetupReqExp = e_rab_setup_req_pdu(?ADDR_A2U, ?TEID_A2U), + %% [eNB -> MME] E-RAB SETUP RESPONSE + SetupRspIn = e_rab_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A), + %% [eNB <- MME] E-RAB RELEASE COMMAND + ReleaseCmd = e_rab_release_cmd_pdu(), + %% [eNB -> MME] E-RAB RELEASE RESPONSE + ReleaseRsp = e_rab_release_rsp_pdu(), + + [%% MME orders allocation of an E-RAB + ?_assertEqual({forward, SetupReqExp}, s1ap_proxy:process_pdu(Pid, SetupReqIn)), + %% MME orders release of an E-RAB, even before the eNB responds + ?_assertEqual({forward, ReleaseCmd}, s1ap_proxy:process_pdu(Pid, ReleaseCmd)), + %% eNB confirms allocation of an E-RAB + %% XXX: "Failed to process E-RAB SETUP RESPONSE: {unexpected_call, erab_wait_release_rsp}" + ?_assertMatch({drop, _}, s1ap_proxy:process_pdu(Pid, SetupRspIn)), + %% eNB confirms release of an E-RAB + ?_assertEqual({forward, ReleaseRsp}, s1ap_proxy:process_pdu(Pid, ReleaseRsp)), + %% E-RAB have been released at this point + ?_assertEqual([], s1ap_proxy:fetch_erab_list(Pid)), + + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_ALL, 4), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_ERAB_SETUP_REQ, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_ERAB_SETUP_RSP, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_ERAB_RELEASE_CMD, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_ERAB_RELEASE_RSP, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_DROP_ALL, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_OUT_PKT_FWD_ALL, 3), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_OUT_PKT_FWD_PROC, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_OUT_PKT_FWD_UNMODIFIED, 2)]. + + test_e_rab_setup_dup(#{handler := Pid}) -> %% [eNB <- MME] E-RAB SETUP REQUEST SetupReqIn = e_rab_setup_req_pdu(?ADDR_U2C, ?TEID_U2C), @@ -402,6 +440,45 @@ ?_assertMatch([_], s1ap_proxy:fetch_erab_list(Pid))].
+test_initial_context_setup_rsp_during_release(#{handler := Pid}) -> + %% [eNB <- MME] INITIAL CONTEXT SETUP REQUEST + InitCtxSetupReq = initial_context_setup_req_pdu(?ADDR_U2C, ?TEID_U2C), + InitCtxSetupReqExp = initial_context_setup_req_pdu(?ADDR_A2U, ?TEID_A2U), + %% [eNB -> MME] INITIAL CONTEXT SETUP RESPONSE + InitCtxSetupRsp = initial_context_setup_rsp_pdu(?ADDR_U2A, ?TEID_U2A), + %% [eNB -> MME] UE CONTEXT RELEASE REQUEST + UeCtxReleaseReq = ue_ctx_release_req_pdu(), + %% [eNB <- MME] UE CONTEXT RELEASE COMMAND + UeCtxReleaseCmd = ue_ctx_release_cmd_pdu(), + %% [eNB -> MME] UE CONTEXT RELEASE COMPLETE + UeCtxReleaseCompl = ue_ctx_release_compl_pdu(), + + [%% MME orders creation of the UE context + ?_assertMatch({forward, InitCtxSetupReqExp}, s1ap_proxy:process_pdu(Pid, InitCtxSetupReq)), + %% eNB requests the UE context release before even responding to the first PDU + ?_assertEqual({forward, UeCtxReleaseReq}, s1ap_proxy:process_pdu(Pid, UeCtxReleaseReq)), + %% MME orders release of the UE context, as requested + ?_assertEqual({forward, UeCtxReleaseCmd}, s1ap_proxy:process_pdu(Pid, UeCtxReleaseCmd)), + %% eNB confirms creation of the UE context + %% XXX: "Failed to process INITIAL CONTEXT SETUP RESPONSE: {unexpected_call, erab_wait_release_rsp}" + ?_assertMatch({drop, _}, s1ap_proxy:process_pdu(Pid, InitCtxSetupRsp)), + %% eNB confirms release of the UE context + ?_assertEqual({forward, UeCtxReleaseCompl}, s1ap_proxy:process_pdu(Pid, UeCtxReleaseCompl)), + %% the UE context has been released, so no E-RAB FSMs shall remain + ?_assertEqual([], s1ap_proxy:fetch_erab_list(Pid)), + + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_ALL, 5), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_INIT_CTX_REQ, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_INIT_CTX_RSP, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_RELEASE_CTX_REQ, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_RELEASE_CTX_CMD, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_RELEASE_CTX_COMPL, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_IN_PKT_DROP_ALL, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_OUT_PKT_FWD_ALL, 4), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_OUT_PKT_FWD_PROC, 1), + ?_assertMetric(?S1GW_CTR_S1AP_PROXY_OUT_PKT_FWD_UNMODIFIED, 3)]. + + test_handover_preparation(#{handler := Pid}) -> %% [eNB -> MME] HANDOVER REQUIRED HandoverRqd = handover_required(),