msc: verify conn and VLR cell id in most tests
osmo-msc failed to record the Complete Layer 3 Information LAC and CI in the MSC-A as well as the VLR record. Since osmo-msc Iee1781985fb25b21ce27526c6a3768bf70d4dc9a and I194271af2acb37b4f8cc2d106ab2fd2b0d443589, osmo-msc properly records these for successful Complete Layer 3 procedures. Incorporate verification of the LAC and CI in all tests calling f_perform_lu() and f_expect_clear(). Implement by scraping the output of vty 'show subscriber imsi 1234 conn' Some tests model a failure to attach, or expire the VLR record: for those, add parameter verify_cell_id to g_pars, and pass it as false, to skip checking the LAC and CI. Disable CI checking for all Iu tests globally in f_verify_vty_lac_ci(), see OS#4634. For the latest build, which does not yet record LAC and CI properly, provide mp_enable_cell_id_test, which skips all cell id verification if set to false. Put to effect by docker-playground I052fea208021509e12826c50474b96474e7a58c2. Related: OS#4627 Depends: Iee1781985fb25b21ce27526c6a3768bf70d4dc9a (osmo-msc) Change-Id: Ie410714a96353f74a52a104c56fa0a08683e0004
This commit is contained in:
parent
a5f0ed2ba4
commit
4e18cccb9c
|
@ -59,6 +59,8 @@ import from Osmocom_VTY_Functions all;
|
|||
|
||||
import from SGsAP_Emulation all;
|
||||
|
||||
import from TCCConversion_Functions { function f_strstr };
|
||||
|
||||
/* this component represents a single subscriber connection */
|
||||
type component BSC_ConnHdlr extends RAN_ConnHdlr, MNCC_ConnHdlr, GSUP_ConnHdlr, MGCP_ConnHdlr, SMPP_ConnHdlr, CTRL_Adapter_CT, SGsAP_ConnHdlr {
|
||||
var BSC_ConnHdlrPars g_pars;
|
||||
|
@ -101,7 +103,8 @@ type record BSC_ConnHdlrPars {
|
|||
integer ran_idx,
|
||||
boolean use_umts_aka,
|
||||
boolean ran_is_geran,
|
||||
boolean use_osmux
|
||||
boolean use_osmux,
|
||||
boolean verify_cell_id
|
||||
};
|
||||
|
||||
/* get a one-octet bitmaks of supported algorithms based on Classmark information */
|
||||
|
@ -364,6 +367,8 @@ runs on BSC_ConnHdlr {
|
|||
/* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
|
||||
f_cl3_or_initial_ue(l3_info);
|
||||
|
||||
f_verify_vty_lac_ci(verify_vlr := false);
|
||||
|
||||
f_mm_common();
|
||||
if (g_pars.net.expect_ciph or not g_pars.ran_is_geran) {
|
||||
/* implicit CM SERVICE ACCEPT? */
|
||||
|
@ -571,6 +576,96 @@ function f_expect_mm_info() runs on BSC_ConnHdlr {
|
|||
}
|
||||
}
|
||||
|
||||
private function f_lac_ci_vty_str(BSSMAP_IE_CellIdentifier cell_id) return charstring
|
||||
{
|
||||
return "LAC / cell ID: "
|
||||
& int2str(oct2int(cell_id.cellIdentification.cI_CGI.lac)) & " / "
|
||||
& int2str(oct2int(cell_id.cellIdentification.cI_CGI.ci));
|
||||
}
|
||||
|
||||
/* Get an IMSI's info and verify that the g_pars.cell_id is reflected in the info.
|
||||
* Verify both the "LAC / cell ID" in the VLR and the "LAC / cell ID" in the "Connection:" part, if any.
|
||||
* If verify_vlr == false, then only verify the "Connection:" part, and fail if there is no "Connection:"; this is
|
||||
* useful when a conn has been established, but the subscriber has not been authenticated, so the VLR does not yet
|
||||
* reflect the new conn's cell ID.
|
||||
*/
|
||||
function f_verify_vty_lac_ci(boolean verify_vlr := true) runs on BSC_ConnHdlr {
|
||||
if (not g_pars.ran_is_geran) {
|
||||
log("Skipping f_verify_vty_lac_ci(), disabled for Iu");
|
||||
setverdict(pass);
|
||||
return;
|
||||
}
|
||||
if (not g_pars.verify_cell_id) {
|
||||
/* Skip this verification; either the TC expects no cell id to end up being accepted, or this was
|
||||
* disabled globally to test an older osmo-msc which doesn't store the cell id properly yet. */
|
||||
log("Skipping f_verify_vty_lac_ci()");
|
||||
setverdict(pass);
|
||||
return;
|
||||
}
|
||||
|
||||
var charstring vty_cmd := "show subscriber imsi " & hex2str(g_pars.imsi) & " conn";
|
||||
var charstring result := f_vty_transceive_ret(MSCVTY, vty_cmd);
|
||||
var charstring expect_lac_ci := "LAC / cell ID: "
|
||||
& int2str(oct2int(g_pars.cell_id.cellIdentification.cI_CGI.lac)) & " / "
|
||||
& int2str(oct2int(g_pars.cell_id.cellIdentification.cI_CGI.ci));
|
||||
|
||||
var boolean vlr_matches := false;
|
||||
var boolean connection_present := false;
|
||||
var boolean connection_matches := false;
|
||||
|
||||
/* There are two occurences of LAC / cell ID: once for the VLR record, and once for the active connection. The
|
||||
* active connection part starts with 'Connection:'. If there is no active connection, that part is omitted.
|
||||
* So, first find out whether there is a 'Connection:' part. Then verify the LAC / cell ID above 'Connection:'
|
||||
* and below 'Connection:', separately.
|
||||
*/
|
||||
var integer connection_start := f_strstr(result, "Connection:");
|
||||
connection_present := (connection_start >= 0);
|
||||
|
||||
var integer lac_ci_match := f_strstr(result, expect_lac_ci);
|
||||
if (connection_present) {
|
||||
if (lac_ci_match > connection_start) {
|
||||
/* The first match is below 'Connection:', so the VLR part above it did not match. */
|
||||
vlr_matches := false;
|
||||
connection_matches := true;
|
||||
} else if (lac_ci_match >= 0) {
|
||||
/* The first match is above 'Connection:', so the VLR part matches. */
|
||||
vlr_matches := true;
|
||||
|
||||
/* Now find a match below 'Connection:' */
|
||||
lac_ci_match := f_strstr(result, expect_lac_ci, connection_start);
|
||||
connection_matches := (lac_ci_match > 0);
|
||||
}
|
||||
} else {
|
||||
/* There is no 'Connection:', so a match, if any, is from the VLR part. */
|
||||
vlr_matches := (lac_ci_match >= 0);
|
||||
}
|
||||
|
||||
if (verify_vlr) {
|
||||
if (not vlr_matches) {
|
||||
setverdict(fail, vty_cmd, " shows mismatching LAC / cell ID in the VLR part, expecting: ",
|
||||
expect_lac_ci, " -- got: ", result);
|
||||
return;
|
||||
} else {
|
||||
log("f_verify_vty_lac_ci(): VLR record matches ", expect_lac_ci);
|
||||
setverdict(pass);
|
||||
}
|
||||
}
|
||||
|
||||
if (connection_present) {
|
||||
if (not connection_matches) {
|
||||
setverdict(fail, vty_cmd, " shows mismatching LAC cell ID in the 'Connection' part, expecting: ",
|
||||
expect_lac_ci, " -- got: ", result);
|
||||
} else {
|
||||
log("f_verify_vty_lac_ci(): Active connection matches ", expect_lac_ci);
|
||||
setverdict(pass);
|
||||
}
|
||||
}
|
||||
|
||||
if (not verify_vlr and not connection_present) {
|
||||
setverdict(fail, "f_verify_vty_lac_ci(verify_vlr := false) called, which requires an active connection, but there is no 'Connection:' part to verify in ", result);
|
||||
}
|
||||
}
|
||||
|
||||
function f_perform_lu()
|
||||
runs on BSC_ConnHdlr {
|
||||
var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
|
||||
|
@ -589,6 +684,10 @@ runs on BSC_ConnHdlr {
|
|||
f_ranap_initial_ue(l3_lu);
|
||||
}
|
||||
|
||||
/* at this point the conn has been established, but the subscriber has not been authenticated, so the VLR does
|
||||
* not yet reflect this conn's cell ID. */
|
||||
f_verify_vty_lac_ci(verify_vlr := false);
|
||||
|
||||
f_mm_imei_early();
|
||||
f_mm_common();
|
||||
f_msc_lu_hlr();
|
||||
|
@ -1574,7 +1673,7 @@ altstep as_clear_cmd_compl_disc(float t := 5.0) runs on BSC_ConnHdlr {
|
|||
}
|
||||
}
|
||||
|
||||
function f_expect_clear(float t := 5.0) runs on BSC_ConnHdlr {
|
||||
function f_expect_clear(float t := 5.0, boolean verify_vlr_cell_id := true) runs on BSC_ConnHdlr {
|
||||
timer T := t;
|
||||
|
||||
T.start;
|
||||
|
@ -1586,6 +1685,11 @@ function f_expect_clear(float t := 5.0) runs on BSC_ConnHdlr {
|
|||
mtc.stop;
|
||||
}
|
||||
}
|
||||
|
||||
if (verify_vlr_cell_id) {
|
||||
/* Now the conn is gone, but the VLR reflects the cell ID */
|
||||
f_verify_vty_lac_ci();
|
||||
}
|
||||
}
|
||||
|
||||
function f_create_bssmap_exp_handoverRequest(integer targetPointCode) runs on BSC_ConnHdlr {
|
||||
|
|
|
@ -167,6 +167,8 @@ modulepar {
|
|||
rctx := 1
|
||||
}
|
||||
};
|
||||
|
||||
boolean mp_enable_cell_id_test := true;
|
||||
}
|
||||
|
||||
/* altstep for the global guard timer (only used when BSSAP_DIRECT
|
||||
|
@ -368,7 +370,8 @@ type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr
|
|||
|
||||
/* FIXME: move into BSC_ConnectionHandler? */
|
||||
function f_init_pars(integer imsi_suffix, boolean sgsap := false, boolean gsup := true, integer ran_idx := 0,
|
||||
boolean ran_is_geran := true, boolean use_osmux := false, OCT4 gsup_sid := '20000101'O)
|
||||
boolean ran_is_geran := true, boolean use_osmux := false, OCT4 gsup_sid := '20000101'O,
|
||||
boolean verify_cell_id := true)
|
||||
runs on MTC_CT return BSC_ConnHdlrPars {
|
||||
var BSC_ConnHdlrNetworkPars net_pars := {
|
||||
kc_support := '0A'O, /* A5/1 and A5/3 enabled */
|
||||
|
@ -404,7 +407,8 @@ runs on MTC_CT return BSC_ConnHdlrPars {
|
|||
ran_idx := ran_idx,
|
||||
use_umts_aka := false,
|
||||
ran_is_geran := ran_is_geran,
|
||||
use_osmux := use_osmux
|
||||
use_osmux := use_osmux,
|
||||
verify_cell_id := mp_enable_cell_id_test and verify_cell_id
|
||||
};
|
||||
if (not ran_is_geran) {
|
||||
pars.use_umts_aka := true;
|
||||
|
@ -447,9 +451,10 @@ function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars, integer bs
|
|||
return vc_conn;
|
||||
}
|
||||
|
||||
function f_start_handler(void_fn fn, integer imsi_suffix, integer ran_idx := 0, boolean ran_is_geran := true, boolean use_osmux := false)
|
||||
function f_start_handler(void_fn fn, integer imsi_suffix, integer ran_idx := 0, boolean ran_is_geran := true, boolean use_osmux := false,
|
||||
boolean verify_cell_id := true)
|
||||
runs on MTC_CT return BSC_ConnHdlr {
|
||||
return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix, ran_idx := ran_idx, ran_is_geran := ran_is_geran, use_osmux := use_osmux));
|
||||
return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix, ran_idx := ran_idx, ran_is_geran := ran_is_geran, use_osmux := use_osmux, verify_cell_id := verify_cell_id));
|
||||
}
|
||||
|
||||
private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
|
||||
|
@ -502,7 +507,7 @@ testcase TC_lu_imsi_reject() runs on MTC_CT {
|
|||
var BSC_ConnHdlr vc_conn;
|
||||
f_init();
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3);
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -533,7 +538,7 @@ testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
|
|||
var BSC_ConnHdlr vc_conn;
|
||||
f_init();
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4);
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -611,7 +616,7 @@ friend function f_tc_lu_imsi_timeout_tmsi_realloc(charstring id, BSC_ConnHdlrPar
|
|||
|
||||
/* f_expect_lu_reject() already waits for T"-1" (X1, 5 seconds), but give some
|
||||
extra time to avoid race conditons... */
|
||||
f_expect_clear(7.0);
|
||||
f_expect_clear(7.0, verify_vlr_cell_id := false);
|
||||
|
||||
setverdict(pass);
|
||||
}
|
||||
|
@ -663,7 +668,7 @@ runs on BSC_ConnHdlr {
|
|||
testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
|
||||
var BSC_ConnHdlr vc_conn;
|
||||
f_init();
|
||||
vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6);
|
||||
vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -751,7 +756,7 @@ testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
|
|||
f_init();
|
||||
f_vty_config(MSCVTY, "network", "authentication required");
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8);
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -785,7 +790,7 @@ testcase TC_lu_auth_sai_err() runs on MTC_CT {
|
|||
f_init();
|
||||
f_vty_config(MSCVTY, "network", "authentication required");
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9);
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -894,7 +899,7 @@ testcase TC_lu_by_imei() runs on MTC_CT {
|
|||
var BSC_ConnHdlr vc_conn;
|
||||
f_init();
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12);
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -974,7 +979,7 @@ testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
|
|||
var BSC_ConnHdlr vc_conn;
|
||||
f_init();
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14);
|
||||
vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -1000,7 +1005,7 @@ testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
|
|||
var BSC_ConnHdlr vc_conn;
|
||||
f_init();
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15);
|
||||
vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -1026,7 +1031,7 @@ testcase TC_imsi_detach_by_imei() runs on MTC_CT {
|
|||
var BSC_ConnHdlr vc_conn;
|
||||
f_init();
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16);
|
||||
vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -1053,7 +1058,7 @@ testcase TC_emerg_call_imei_reject() runs on MTC_CT {
|
|||
var BSC_ConnHdlr vc_conn;
|
||||
f_init();
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17);
|
||||
vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -1195,7 +1200,7 @@ testcase TC_lu_auth_2G_fail() runs on MTC_CT {
|
|||
f_init();
|
||||
f_vty_config(MSCVTY, "network", "authentication required");
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23);
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -1575,7 +1580,7 @@ testcase TC_gsup_cancel() runs on MTC_CT {
|
|||
var BSC_ConnHdlr vc_conn;
|
||||
f_init();
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33);
|
||||
vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -1659,7 +1664,7 @@ testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
|
|||
f_vty_config(MSCVTY, "network", "authentication required");
|
||||
f_vty_config(MSCVTY, "network", "encryption a5 3");
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 360);
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 360, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
|
||||
|
@ -1669,7 +1674,7 @@ testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
|
|||
f_vty_config(MSCVTY, "network", "authentication required");
|
||||
f_vty_config(MSCVTY, "network", "encryption a5 3");
|
||||
|
||||
pars := f_init_pars(361);
|
||||
pars := f_init_pars(361, verify_cell_id := false);
|
||||
pars.send_early_cm := false;
|
||||
vc_conn := f_start_handler_with_pars(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), pars);
|
||||
vc_conn.done;
|
||||
|
@ -1684,7 +1689,7 @@ testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
|
|||
* message that is reported in OS#2947 to trigger the segfault */
|
||||
f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 362);
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 362, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -1726,7 +1731,7 @@ testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT {
|
|||
f_vty_config(MSCVTY, "network", "authentication required");
|
||||
f_vty_config(MSCVTY, "network", "encryption a5 1 3");
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), 37);
|
||||
vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), 37, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -3986,7 +3991,7 @@ testcase TC_cipher_complete_with_invalid_cipher() runs on MTC_CT {
|
|||
f_init();
|
||||
f_vty_config(MSCVTY, "network", "encryption a5 1");
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_cipher_complete_with_invalid_cipher), 52);
|
||||
vc_conn := f_start_handler(refers(f_tc_cipher_complete_with_invalid_cipher), 52, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -5999,7 +6004,7 @@ testcase TC_mm_id_resp_no_identity() runs on MTC_CT {
|
|||
|
||||
f_init();
|
||||
|
||||
vc_conn := f_start_handler(refers(f_tc_mm_id_resp_no_identity), 7);
|
||||
vc_conn := f_start_handler(refers(f_tc_mm_id_resp_no_identity), 7, verify_cell_id := false);
|
||||
vc_conn.done;
|
||||
}
|
||||
|
||||
|
@ -6030,7 +6035,7 @@ runs on BSC_ConnHdlr {
|
|||
|
||||
/* The recent OsmoMSC keeps subscriber in its VLR unless the Paging is completed.
|
||||
* In this case we do not send anything and just wait for a Clear Command. */
|
||||
f_expect_clear();
|
||||
f_expect_clear(verify_vlr_cell_id := false);
|
||||
}
|
||||
testcase TC_lu_and_expire_while_paging() runs on MTC_CT {
|
||||
var BSC_ConnHdlr vc_conn;
|
||||
|
|
Loading…
Reference in New Issue