neels has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/37077?usp=email )
Change subject: hnbgw: TC_hnb_disconnected_timeout; Osmocom_CTRL_Functions
......................................................................
hnbgw: TC_hnb_disconnected_timeout; Osmocom_CTRL_Functions
Test the new timer hnbgw X35: discard all hnb_persistent state after a
given timeout.
While a hnb_persistent is present, its rate_ctrs and stat_items remain
present. When it is discarded, these vanish again. Use this to verify
that discarding and re-registering a hnb_persistent works.
Teach the CTRL functions that retrieve rate counters to return counters
of -1 when a requested object is not present, instead of erroring and
stopping the test. Like this we can expect absence of an object.
Set X35 to five seconds, drop the Iuh link, wait and verify that the
rate counter group for the hnb_persistent is gone.
Then reconnect and disconnect again, to provoke errors like
use-after-free.
Depends: osmo-hnbgw Ic819d7cbc03fb39e98c204b70d016c5170dc6307
Related: SYS#6773
Change-Id: Ibec009203d38f65714561b7c28edbdbd8b34e704
---
M hnbgw/HNBGW_Tests.ttcn
M library/Osmocom_CTRL_Functions.ttcn
2 files changed, 198 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/77/37077/1
diff --git a/hnbgw/HNBGW_Tests.ttcn b/hnbgw/HNBGW_Tests.ttcn
index 88b8c1e..d49d632 100644
--- a/hnbgw/HNBGW_Tests.ttcn
+++ b/hnbgw/HNBGW_Tests.ttcn
@@ -357,6 +357,7 @@
var charstring g_ctr_cn_node_name;
/* Counter state */
var CounterNameValsList g_ctr_cn;
+ var CounterNameValsList g_ctr_hnb;
}
/* global altstep for global guard timer; */
@@ -433,6 +434,15 @@
vc_RUA[hnb_idx].start(RUA_Emulation.main(rua_ops, id & "-RUA"));
}
+function f_drop_hnodeb(integer hnb_idx) runs on test_CT
+{
+
+ vc_Iuh[hnb_idx].stop;
+ vc_RUA[hnb_idx].stop;
+ disconnect(self:HNBAP[hnb_idx], vc_Iuh[hnb_idx]:HNBAP);
+ disconnect(vc_RUA[hnb_idx]:RUA, vc_Iuh[hnb_idx]:RUA);
+}
+
private type record of boolean BooleanList;
private function f_vty_cnlink_allow_attach(TELNETasp_PT pt, boolean ps_domain,
BooleanList allow_attach_list)
@@ -1016,6 +1026,114 @@
f_shutdown_helper();
}
+/* Default list of counters for a 'hnb' entity */
+const CounterNameVals counternames_hnb := {
+ { "iuh:established", 0 }
+};
+
+private function f_ctrs_hnb_init(integer hnb_start := 0, integer hnb_count := 1,
+ CounterNameVals counternames := counternames_hnb) runs on test_CT {
+ g_ctr_hnb := f_counter_name_vals_get_n(IPA_CTRL, "hnb", hnb_count,
counternames, start_idx := hnb_start);
+ log("initial hnb rate counters: ", g_ctr_hnb);
+}
+
+/* f_ctrs_hnb_init();
+ * f_do_thing(on_hnb := 0);
+ * f_do_thing(on_hnb := 0);
+ * f_do_other(on_hnb := 1);
+ * f_ctrs_hnb_add(0, "thing", 2);
+ * f_ctrs_hnb_add(1, "other");
+ * f_ctrs_hnb_verify();
+ */
+private function f_ctrs_hnb_verify() runs on test_CT {
+ log("verifying hnb rate counters: ", g_ctr_hnb);
+ f_counter_name_vals_expect_n(IPA_CTRL, "hnb", g_ctr_hnb);
+}
+
+/* convenience: f_ctrs_hnb_add() and f_ctrs_hnb_verify() in one call.
+ * f_ctrs_hnb_init();
+ * f_do_thing(on_hnb := 0);
+ * f_do_thing(on_hnb := 0);
+ * f_do_thing(on_hnb := 0);
+ * f_ctrs_hnb_expect(0, "thing", 3);
+ */
+private function f_ctrs_hnb_expect(integer hnb_nr, charstring countername, integer val :=
1) runs on test_CT {
+ f_ctrs_hnb_add(hnb_nr, countername, val);
+ f_ctrs_hnb_verify();
+}
+
+private function f_ctrs_hnb_add(integer hnb_nr, charstring countername, integer val := 1)
runs on test_CT {
+ f_counter_name_vals_list_add(g_ctr_hnb, hnb_nr, countername, val);
+}
+
+/* Set all counters for this hnb instance to a specific value. Useful to expect a
disconnected and discarded hnb,
+ * because -1 is returned by f_counter_name_vals_get_n() when the hnb is not present on
the CTRL interface. */
+private function f_ctrs_hnb_set_all(integer hnb_nr, integer val) runs on test_CT {
+ for (var integer i := 0; i < lengthof(counternames_hnb); i := i + 1) {
+ f_counter_name_vals_list_set(g_ctr_hnb, hnb_nr, counternames_hnb[i].name, val);
+ }
+}
+
+private function f_vty_run_hnbgw(TELNETasp_PT pt, charstring cmd)
+{
+ f_vty_enter_config(pt);
+ f_vty_transceive(pt, "hnbgw");
+ f_vty_transceive(pt, cmd);
+ f_vty_transceive(pt, "end");
+}
+
+testcase TC_hnb_disconnected_timeout() runs on test_CT {
+ g_num_hnbs := 1;
+ f_init(start_hnb := true);
+
+ f_vty_run_hnbgw(HNBGWVTY, "timer hnbgw X35 5");
+
+ /* Init the counters when the hnb already exists. There should be a nonzero
iuh:established count now. */
+ f_ctrs_hnb_init();
+
+ /* Drop the Iuh link */
+ f_drop_hnodeb(0);
+ f_sleep(1.0);
+
+ /* The hNodeB persistent state should still be around, because X35 has not yet elapsed.
*/
+ f_ctrs_hnb_verify();
+
+ f_sleep(5.0);
+ /* We get -1 counters when the CTRL interface returned an error for the requested
counter, meaning that the
+ * hnb_persistent no longer exists. Verify that it is gone: */
+ f_ctrs_hnb_set_all(0, -1);
+ f_ctrs_hnb_verify();
+
+ f_sleep(1.0);
+
+ /* Connect again. */
+ var RuaOps rua_ops := {
+ create_cb := refers(IuhRanapCreateCallback),
+ unitdata_cb := refers(IuhRanapUnitdataCallback)
+ };
+ f_init_hnodeb(testcasename(), 0, rua_ops);
+
+ /* still disconnected until actually registered on HNBAP */
+ f_ctrs_hnb_verify();
+
+ f_hnbap_register(0);
+ /* The hNodeB has come back to existence, so expect 0, not -1 anymore: */
+ f_ctrs_hnb_set_all(0, 0);
+ /* Also we've registered once. */
+ f_ctrs_hnb_add(0, "iuh:established", 1);
+ f_ctrs_hnb_verify();
+ f_sleep(1.0);
+
+ /* Again drop the Iuh link, wait for X35 and see that it's gone again. */
+ f_drop_hnodeb(0);
+ f_ctrs_hnb_verify();
+ f_sleep(6.0);
+ f_ctrs_hnb_set_all(0, -1);
+ f_ctrs_hnb_verify();
+
+ f_shutdown_helper();
+}
+
/* regular UE registration */
testcase TC_ue_register() runs on test_CT {
var UE_Identity ue_id := { iMSI := imsi_hex2oct(f_gen_imsi(1)) };
@@ -2882,6 +3000,7 @@
execute(TC_hnb_register());
execute(TC_hnb_register_duplicate());
execute(TC_hnb_register_duplicate_reuse_sctp_assoc());
+ execute(TC_hnb_disconnected_timeout());
execute(TC_ue_register());
execute(TC_ue_register_tmsi_lai());
execute(TC_ue_register_before_hnb_register());
diff --git a/library/Osmocom_CTRL_Functions.ttcn b/library/Osmocom_CTRL_Functions.ttcn
index 75f8646..24b8880 100644
--- a/library/Osmocom_CTRL_Functions.ttcn
+++ b/library/Osmocom_CTRL_Functions.ttcn
@@ -30,7 +30,7 @@
}
/* perform a given GET Operation */
- function f_ctrl_get(IPA_CTRL_PT pt, CtrlVariable variable) return CtrlValue {
+ function f_ctrl_get(IPA_CTRL_PT pt, CtrlVariable variable, template (omit) charstring
on_err := omit) return CtrlValue {
timer T := 2.0;
var CtrlMessage rx;
var CtrlId id := f_gen_rand_id();
@@ -41,8 +41,12 @@
}
[] pt.receive(tr_CtrlMsgTrap) { repeat; }
[] pt.receive(tr_CtrlMsgError) -> value rx {
- setverdict(fail, "Error in CTRL GET ", variable, ": ",
rx.err.reason);
- mtc.stop;
+ if (ispresent(on_err)) {
+ rx.resp.val := valueof(on_err);
+ } else {
+ setverdict(fail, "Error in CTRL GET ", variable, ": ",
rx.err.reason);
+ mtc.stop;
+ }
}
[] T.timeout {
setverdict(fail, "Timeout waiting for CTRL GET REPLY ", variable);
@@ -155,7 +159,7 @@
function f_ctrl_get_ratectr_abs(IPA_CTRL_PT pt, CtrlVariable grp, integer instance,
CtrlVariable name) return integer {
- return str2int(f_ctrl_get(pt, valueof(ts_ctrl_ratectr(grp, instance, name))));
+ return str2int(f_ctrl_get(pt, valueof(ts_ctrl_ratectr(grp, instance, name)), on_err :=
"-1"));
}
function f_ctrl_get_exp_ratectr_abs(IPA_CTRL_PT pt, CtrlVariable grp, integer instance,
@@ -231,6 +235,18 @@
return vals;
}
+ function f_counter_name_vals_make(CounterNameVals counternames, integer val)
+ return CounterNameVals {
+ var CounterNameVals vals;
+ for (var integer i := 0; i < lengthof(counternames); i := i + 1) {
+ vals[i] := {
+ name := counternames[i].name,
+ val := val
+ };
+ }
+ return vals;
+ }
+
/* Retrieve the first N instances' rate counter values of the given names */
function f_counter_name_vals_get_n(IPA_CTRL_PT pt, charstring instance_name :=
"msc",
integer instance_count, CounterNameVals counternames,
@@ -238,7 +254,13 @@
return CounterNameValsList {
var CounterNameValsList valslist;
for (var integer instance_nr := start_idx; instance_nr < start_idx + instance_count;
instance_nr := instance_nr + 1) {
- valslist[instance_nr] := f_counter_name_vals_get(pt, instance_name, instance_nr,
counternames);
+ var CounterNameVals vals := f_counter_name_vals_get(pt, instance_name, instance_nr,
counternames);
+ if (not ispresent(vals)) {
+ /* If that instance is not available on the CTRL interface, set all counters for
this
+ * instance to -1. */
+ vals := f_counter_name_vals_make(counternames, -1);
+ }
+ valslist[instance_nr] := vals;
}
log("retrieved rate counters: ", instance_name, ": ", valslist);
return valslist;
@@ -260,6 +282,22 @@
}
}
+ /* In a list of one instance's counters, set a specifically named counter to a
specific value. */
+ function f_counter_name_vals_set(inout CounterNameVals vals, charstring countername,
integer val := 1)
+ {
+ for (var integer i := 0; i < lengthof(vals); i := i + 1) {
+ if (vals[i].name == countername) {
+ vals[i].val := val;
+ return;
+ }
+ }
+ /* name not found, append */
+ vals[lengthof(vals)] := {
+ name := countername,
+ val := val
+ }
+ }
+
/* In a list of several instances' counters, increment a specific instance's
specifically named counter. */
function f_counter_name_vals_list_add(inout CounterNameValsList vals, integer
instance_nr,
charstring countername, integer val := 1)
@@ -267,6 +305,14 @@
f_counter_name_vals_add(vals[instance_nr], countername, val);
}
+ /* In a list of several instances' counters, set a specific instance's
specifically named counter to a specific
+ * value. */
+ function f_counter_name_vals_list_set(inout CounterNameValsList vals, integer
instance_nr,
+ charstring countername, integer val := 0)
+ {
+ f_counter_name_vals_set(vals[instance_nr], countername, val);
+ }
+
/* For a specific instance, call f_counter_name_vals_get() and compare with expected
counter values.
* Set the test verdict accordingly. */
function f_counter_name_vals_expect(IPA_CTRL_PT pt, charstring instance_name, integer
instance_nr,
--
To view, visit
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/37077?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: Ibec009203d38f65714561b7c28edbdbd8b34e704
Gerrit-Change-Number: 37077
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-MessageType: newchange