diff options
Diffstat (limited to 'hlr/HLR_Tests.ttcn')
-rw-r--r-- | hlr/HLR_Tests.ttcn | 223 |
1 files changed, 189 insertions, 34 deletions
diff --git a/hlr/HLR_Tests.ttcn b/hlr/HLR_Tests.ttcn index 36e28b8a..46b98c29 100644 --- a/hlr/HLR_Tests.ttcn +++ b/hlr/HLR_Tests.ttcn @@ -15,6 +15,7 @@ module HLR_Tests { import from GSUP_Types all; +import from GSUP_Templates all; import from GSUP_Emulation all; import from IPA_Emulation all; @@ -70,9 +71,6 @@ modulepar { /* emulated GSUP server (second HLR) */ charstring mp_hlr_ts_ip := "127.0.0.99"; integer mp_hlr_ts_port := 4222; - - /* drop after osmo-hlr release > 1.2.0 */ - boolean mp_hlr_supports_dgsm := true; }; type record HlrSubscrAud2G { @@ -154,9 +152,8 @@ function f_init_vty() runs on test_CT { map(self:VTY, system:VTY); f_vty_set_prompts(VTY); f_vty_transceive(VTY, "enable"); - if (mp_hlr_supports_dgsm) { - f_vty_config(VTY, "mslookup", "no mdns bind"); - } + f_vty_config(VTY, "mslookup", "no mdns bind"); + f_vty_config(VTY, "hlr", "reject-cause not-found imsi-unknown"); } private altstep as_Tguard() runs on test_CT { @@ -245,7 +242,7 @@ function f_init(boolean legacy := true, boolean gsup_server := false) runs on te f_init_gsup_server("HLR_Test"); } - f_ipa_ctrl_start(mp_hlr_ip, mp_hlr_ctrl_port); + f_ipa_ctrl_start_client(mp_hlr_ip, mp_hlr_ctrl_port); } /*! Start HLR_ConnHdlr from testCT in a separate thread. @@ -540,12 +537,15 @@ runs on HLR_ConnHdlr return GSUP_PDU { return ret; } +/* return_isd -> return the Insert Subscriber Data instead of the Update Location Result */ function f_perform_UL(hexstring imsi, template hexstring msisdn, template (omit) integer exp_err_cause := omit, GSUP_CnDomain dom := OSMO_GSUP_CN_DOMAIN_PS, template (omit) octetstring source_name := omit) -runs on HLR_ConnHdlr return GSUP_PDU { - var GSUP_PDU ret; +runs on HLR_ConnHdlr return GSUP_PDUs { + var GSUP_PDU pdu; + var GSUP_PDU isd; + var GSUP_PDUs ret; timer T := 3.0; var boolean exp_fail := false; var boolean isd_done := false; @@ -556,31 +556,31 @@ runs on HLR_ConnHdlr return GSUP_PDU { GSUP.send(valueof(ts_GSUP_UL_REQ(imsi, dom, source_name := source_name))); T.start; alt { - [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, exp_err_cause, destination_name := source_name)) -> value ret { + [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, exp_err_cause, destination_name := source_name)) -> value pdu { setverdict(pass); } - [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?, destination_name := source_name)) -> value ret { + [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?, destination_name := source_name)) -> value pdu { setverdict(fail, "Unexpected UL ERROR Cause"); mtc.stop; } - [exp_fail] GSUP.receive(tr_GSUP_UL_RES(imsi, destination_name := source_name)) -> value ret { + [exp_fail] GSUP.receive(tr_GSUP_UL_RES(imsi, destination_name := source_name)) -> value pdu { setverdict(fail, "Unexpected UL.res for unknown IMSI"); mtc.stop; } - [exp_fail] GSUP.receive(tr_GSUP_ISD_REQ(imsi, destination_name := source_name)) -> value ret { + [exp_fail] GSUP.receive(tr_GSUP_ISD_REQ(imsi, destination_name := source_name)) -> value pdu { setverdict(fail, "Unexpected ISD.req in error case"); mtc.stop; } - [not exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?, destination_name := source_name)) -> value ret { + [not exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?, destination_name := source_name)) -> value pdu { setverdict(fail, "Unexpected UL ERROR"); mtc.stop; } - [not exp_fail and not isd_done] GSUP.receive(tr_GSUP_ISD_REQ(imsi, msisdn, destination_name := source_name)) -> value ret { + [not exp_fail and not isd_done] GSUP.receive(tr_GSUP_ISD_REQ(imsi, msisdn, destination_name := source_name)) -> value isd { GSUP.send(ts_GSUP_ISD_RES(imsi, source_name := source_name)); isd_done := true; repeat; } - [not exp_fail and isd_done] GSUP.receive(tr_GSUP_UL_RES(imsi, destination_name := source_name)) -> value ret { + [not exp_fail and isd_done] GSUP.receive(tr_GSUP_UL_RES(imsi, destination_name := source_name)) -> value pdu { setverdict(pass); } [] GSUP.receive { repeat; } @@ -589,6 +589,12 @@ runs on HLR_ConnHdlr return GSUP_PDU { mtc.stop; } } + + ret := { pdu }; + if (isd_done) { + ret := ret & { isd }; + } + return ret; } @@ -983,6 +989,7 @@ testcase TC_gsup_ul_unknown_imsi() runs on test_CT { vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi), pars); vc_conn.done; } + testcase TC_gsup_ul_unknown_imsi_via_proxy() runs on test_CT { var hexstring imsi := f_rnd_imsi('26242'H); var HLR_ConnHdlrPars pars := valueof(t_Pars_via_proxy(imsi)); @@ -993,15 +1000,35 @@ testcase TC_gsup_ul_unknown_imsi_via_proxy() runs on test_CT { vc_conn.done; } +/* Test if the HLR can be configured to a different error code if the subscriber can't be found. + * E.g. on event networks the HLR should return Roaming Not Allowed to unknown subscribers instead + * of Subscriber Unknown in HLR. + */ +private function f_TC_ul_unknown_imsi_roaming_not_allowed() runs on HLR_ConnHdlr { + f_vty_config(VTY, "hlr", "reject-cause not-found roaming-not-allowed"); + f_perform_UL(g_pars.sub.imsi, ?, 13, source_name := g_pars.source_name); + setverdict(pass); +} +testcase TC_gsup_ul_unknown_imsi_roaming_not_allowed() runs on test_CT { + var hexstring imsi := f_rnd_imsi('26242'H); + var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi)); + var HLR_ConnHdlr vc_conn; + + f_init(false); + vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi_roaming_not_allowed), pars); + vc_conn.done; +} + /* test UL for a number of different subscriber cases (algo, 2g/3g, ...) */ private function f_TC_gsup_ul() runs on HLR_ConnHdlr { - var GSUP_PDU res; + var GSUP_PDUs res; res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn, source_name := g_pars.source_name); setverdict(pass); } + testcase TC_gsup_ul() runs on test_CT { var HlrSubscriberList sl; - var GSUP_PDU res; + var GSUP_PDUs res; f_init(false); sl := f_gen_subs(); @@ -1020,6 +1047,72 @@ testcase TC_gsup_ul_via_proxy() runs on test_CT { setverdict(pass); } +private function f_TC_gsup_ul_subscriber_data() runs on HLR_ConnHdlr { + var GSUP_PDUs pdus; + var GSUP_PDU isd; + log("GSUP ul subscriber_data", isd); + pdus := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn, source_name := g_pars.source_name); + isd := pdus[1]; + + template GSUP_IEs tr_pdp_info_internet := { + tr_GSUP_IE_PDP_CONTEXT_ID('01'O), + tr_GSUP_IE_APN(str2apn("internet")) + } + template GSUP_IEs tr_pdp_info_wildcard := { + tr_GSUP_IE_PDP_CONTEXT_ID('02'O), + tr_GSUP_IE_APN(str2apn("*")) + } + + /* Search for PDP info 'internet', '*' */ + var boolean found := false; + var GSUP_IeValue ievalue; + var GSUP_IEs pdp_info; + found := f_gsup_find_nested_ie_multiple(isd.ies, OSMO_GSUP_PDP_INFO_IE, 0, ievalue); + if (not found) { + setverdict(fail, "Multiple APNs: Coulnd't find first PDP Info IE in: ", isd); + return; + } + pdp_info := ievalue.pdp_info; + if (not match(pdp_info, tr_pdp_info_internet)) { + setverdict(fail, "Multiple APNs: first PDP Info doesn't match: ", pdp_info, "on Template: ", tr_pdp_info_internet); + return; + } + + /* wildcard '*' */ + found := f_gsup_find_nested_ie_multiple(isd.ies, OSMO_GSUP_PDP_INFO_IE, 1, ievalue); + if (not found) { + setverdict(fail, "Multiple APNs: Coulnd't find second PDP Info IE in: ", isd); + return; + } + pdp_info := ievalue.pdp_info; + if (not match(pdp_info, tr_pdp_info_wildcard)) { + setverdict(fail, "Multiple APNs: second PDP Info doesn't match: ", pdp_info, "on Template: ", tr_pdp_info_wildcard); + return; + } + + setverdict(pass); +} + +testcase TC_gsup_ul_subscriber_data() runs on test_CT { + /* Do a GSUP Update Location Request to get a Insert Subscriber Data Request (ISD). + * Check for multiple APN in the ISD: + * SGSN -> HLR: Update Location Request + * SGSN <- HLR: Insert Subscriber Data Request (Check the TLV) + * SGSN -> HLR: Insert Subscriber Data Result + * SGSN <- HLR: Update Location Result + */ + var HlrSubscriberList sl; + + f_init(false); + f_vty_config2(VTY, {"hlr", "ps"} , "no pdp-profiles default"); + f_vty_config2(VTY, {"hlr", "ps", "pdp-profiles default", "profile 1"}, "apn internet"); + f_vty_config2(VTY, {"hlr", "ps", "pdp-profiles default", "profile 2"}, "apn *"); + sl := f_gen_subs(); + f_start_handler_per_sub(refers(f_TC_gsup_ul_subscriber_data), sl); + + setverdict(pass); +} + /* Test only the VTY commands */ testcase TC_vty() runs on test_CT { var HlrSubscriber sub; @@ -1051,7 +1144,7 @@ testcase TC_vty() runs on test_CT { /* VTY changes to MSISDN should result in ISD to current VLR */ private function f_TC_vty_msisdn_isd() runs on HLR_ConnHdlr { var hexstring new_msisdn; - var GSUP_PDU res; + var GSUP_PDUs res; timer T := 5.0; /* Create Subscriber */ @@ -1096,9 +1189,10 @@ testcase TC_vty_msisdn_isd() runs on test_CT { /* Test PURGE MS for CS services */ private function f_TC_gsup_purge_cs() runs on HLR_ConnHdlr { - var GSUP_PDU res; + var GSUP_PDUs res; + var GSUP_PDU pdu; res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn); - res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_CS); + pdu := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_CS); } testcase TC_gsup_purge_cs() runs on test_CT { var HlrSubscriberList sl; @@ -1113,9 +1207,10 @@ testcase TC_gsup_purge_cs() runs on test_CT { /* Test PURGE MS for PS services */ private function f_TC_gsup_purge_ps() runs on HLR_ConnHdlr { - var GSUP_PDU res; + var GSUP_PDUs res; + var GSUP_PDU pdu; res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn); - res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_PS); + pdu := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_PS); } testcase TC_gsup_purge_ps() runs on test_CT { var HlrSubscriberList sl; @@ -1545,7 +1640,7 @@ testcase TC_gsup_check_imei_unknown_imsi() runs on test_CT { /* Test create-subscriber-on-demand during Check IMEI (OsmoMSC would be set to "check-imei-rqd early") */ private function f_TC_subscr_create_on_demand_check_imei_early() runs on HLR_ConnHdlr { - var GSUP_PDU res; /* save various return values to prevent ttcn3 compiler warnings */ + var GSUP_PDUs res; /* save various return values to prevent ttcn3 compiler warnings */ var charstring imsi_pattern := "*IMSI: " & hex2str(g_pars.sub.imsi) & "*"; /* Random MSISDN and CS+PS NAM (LU must pass) */ @@ -1618,7 +1713,7 @@ testcase TC_subscr_create_on_demand_check_imei_early() runs on test_CT { /* Test create-subscriber-on-demand during LU (Location Update) */ private function f_TC_subscr_create_on_demand_ul() runs on HLR_ConnHdlr { - var GSUP_PDU res; + var GSUP_PDUs res; var charstring imsi_pattern := "*IMSI: " & hex2str(g_pars.sub.imsi) & "*"; /* Random MSISDN and CS+PS NAM (LU must pass) */ @@ -1685,13 +1780,14 @@ testcase TC_subscr_create_on_demand_ul() runs on test_CT { /* Test create-subscriber-on-demand during SAI (SendAuthInfo) */ private function f_TC_subscr_create_on_demand_sai() runs on HLR_ConnHdlr { - var GSUP_PDU res; + var GSUP_PDUs res; + var GSUP_PDU pdu; var charstring imsi_pattern := "*IMSI: " & hex2str(g_pars.sub.imsi) & "*"; /* HLR creates the subscriber on demand. Then the IMSI is known, but there is no auth data, so the HLR returns * the "slightly inaccurate cause 'IMSI Unknown' via GSUP". The MS is able to do a LU afterwards. */ f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 cs+ps"); - res := f_perform_SAI(g_pars.sub.imsi, 2 /* IMSI Unknown */ ); + pdu := f_perform_SAI(g_pars.sub.imsi, 2 /* IMSI Unknown */ ); /* Verify that it was created before the LU */ f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern); @@ -1922,6 +2018,65 @@ testcase TC_MSLookup_mDNS_service_other_proxy() runs on test_CT { } } + +/* strchr similar to C's/posix strchr but returns the position of the first matching. + * if the char c isn't found it returns -1. + */ +function strchr(in charstring s, in charstring c) return integer { + for (var integer i := 0; i < lengthof(s); i := i+1) { + if (s[i] == c) { + return i; + } + } + return -1; +} + +/* str2apn returns octetstring + * internet -> '08'O & char2oct("internet") + * internet.foo -> '08'O & char2oct("internet") & '03'O & char2oct("foo") + * internet.-> '08'O & char2oct("internet") + */ +function str2apn(in charstring apn) return octetstring { + var octetstring result := ''O; + var charstring remain := apn; + var integer pos := strchr(remain, "."); + + while (pos != -1) { + /* ends on a dot. e.g. "internet.", we must ignore the ending dot and this is then the last element */ + if (pos == 0) { + /* it's not allowed to start with a dot. */ + return ''O; + } + + if (pos + 1 == lengthof(remain)) { + /* remove the dot */ + remain := substr(remain, 0, pos) + break; + } + + result := result & int2oct(pos, 1) & char2oct(substr(remain, 0, pos)); + remain := substr(remain, pos + 1, lengthof(remain) - pos - 1); + pos := strchr(remain, "."); + } + /* last element */ + var integer len := lengthof(remain); + result := result & int2oct(len, 1) & char2oct(remain); + return result; +} + +private function test_assert(boolean term) { + if (term == false) { + setverdict(fail, "Values mismatch"); + } +} + +private function test_str2apn() { + test_assert(str2apn("internet") == '08'O & char2oct("internet")); + test_assert(str2apn("internet.") == '08'O & char2oct("internet")); + test_assert(str2apn("internet.foo") == '08'O & char2oct("internet") & '03'O & char2oct("foo")); + test_assert(str2apn(".internet.foo") == ''O); +} + /* TODO: * UL with ISD error * UL with ISD timeout @@ -1943,9 +2098,11 @@ control { execute( TC_gsup_sai_eps() ); execute( TC_gsup_ul_unknown_imsi() ); execute( TC_gsup_ul_unknown_imsi_via_proxy() ); + execute( TC_gsup_ul_unknown_imsi_roaming_not_allowed() ); execute( TC_gsup_sai_err_unknown_imsi() ); execute( TC_gsup_ul() ); execute( TC_gsup_ul_via_proxy() ); + execute( TC_gsup_ul_subscriber_data() ); execute( TC_vty() ); execute( TC_vty_msisdn_isd() ); execute( TC_gsup_purge_cs() ); @@ -1973,13 +2130,11 @@ control { execute( TC_subscr_create_on_demand_ul() ); execute( TC_subscr_create_on_demand_sai() ); - if (mp_hlr_supports_dgsm) { - execute( TC_MSLookup_mDNS_service_other_home() ); - execute( TC_MSLookup_GSUP_proxy() ); - execute( TC_MSLookup_mDNS_service_GSUP_HLR_home() ); - execute( TC_MSLookup_mDNS_service_GSUP_HLR_proxy() ); - execute( TC_MSLookup_mDNS_service_other_proxy() ); - } + execute( TC_MSLookup_mDNS_service_other_home() ); + execute( TC_MSLookup_GSUP_proxy() ); + execute( TC_MSLookup_mDNS_service_GSUP_HLR_home() ); + execute( TC_MSLookup_mDNS_service_GSUP_HLR_proxy() ); + execute( TC_MSLookup_mDNS_service_other_proxy() ); }; }; |