bsc: add TC_ratectr_all_available_allocated and _dyn

Test new rate counters all_allocated:{sdcch,tch,static_sdcch,static_tch}

Related: SYS#4878
Depends: I2fa14531f16d3f07085620f1c50eb839c420da6a (osmo-bsc)
Change-Id: Ib3997a827c9cc43d1361bb0cf3bfab9f6d91bf82
This commit is contained in:
Neels Hofmeyr 2021-10-26 22:04:53 +02:00 committed by neels
parent 3b868cb1aa
commit bd94fe7236
2 changed files with 234 additions and 0 deletions

View File

@ -1642,6 +1642,8 @@ type record DchanTuple {
RslChannelNr rsl_chan_nr
}
type record of DchanTuple DchanTuples;
/* Send CHAN RQD and wait for allocation; acknowledge it */
private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
runs on test_CT return RslChannelNr {
@ -10393,6 +10395,156 @@ testcase TC_lost_sdcch_during_assignment() runs on test_CT {
f_shutdown_helper();
}
const CounterNameVals counternames_bsc_bts_all_available_allocated := {
{ "all_allocated:sdcch", 0 },
{ "all_allocated:static_sdcch", 0 },
{ "all_allocated:tch", 0 },
{ "all_allocated:static_tch", 0 }
}
private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
{
/* Make sure counters settle first */
f_sleep(1.0);
/* Take a baseline of counters */
f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
/* Elapse some time so that we see changes in counters, hopefully where expected */
f_sleep(2.0);
/* Get new counters */
var charstring_list all_changed := {};
all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
/* Compare with expectations */
var charstring_list all_expect_changed := {};
for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
}
f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
}
testcase TC_ratectr_all_available_allocated() runs on test_CT {
var ASP_RSL_Unitdata rsl_ud;
var integer i;
var integer chreq_total, chreq_nochan;
f_init(1);
f_sleep(1.0);
/* Exhaust all dedicated SDCCH lchans.
/* GSM 44.018 Table 9.1.8.2:
* RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
*/
for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
}
/* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
* level.
* All SDCCH are now occupied. */
f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
/* Also fill up all remaining (TCH) channels */
for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
}
/* All TCH are now also occupied */
f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
"all_allocated:tch", "all_allocated:static_tch"});
f_shutdown_helper();
}
testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
var ASP_RSL_Unitdata rsl_ud;
var integer i;
var integer chreq_total, chreq_nochan;
f_init_vty();
f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
/* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
f_init(1, guard_timeout := 60.0);
f_sleep(1.0);
/* The dyn TS wants to activate PDCH mode, ACK that. */
var RslChannelNr chan_nr;
chan_nr := valueof(t_RslChanNr_PDCH(2));
f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
/* Exhaust all dedicated SDCCH lchans.
/* GSM 44.018 Table 9.1.8.2:
* RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
*/
for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
}
/* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
* all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
/* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
* Will release them later, so remember all the DchanTuples. */
var DchanTuples dyn_sddch := {};
dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
/* Also occupy the seven other SDCCH of the dyn TS */
for (i := 0; i < 7; i := i+1) {
dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
}
/* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
/* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
for (i := 0; i < 5; i := i+1) {
f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);
}
/* All TCH lchans are now also occupied, both static and dynamic */
f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
"all_allocated:tch", "all_allocated:static_tch"});
/* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
* incrementing. */
var BssmapCause cause := 0;
var DchanTuple dt := dyn_sddch[0];
BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
f_exp_chan_rel_and_clear(dt, 0);
/* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
* count as occupied, so those still both increment. */
f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
"all_allocated:tch", "all_allocated:static_tch"});
/* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
dt := dyn_sddch[i];
BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
f_exp_chan_rel_and_clear(dt, 0);
}
/* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
chan_nr := valueof(t_RslChanNr_PDCH(2));
f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
/* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
/* clean up config */
f_ts_reset_chcomb(0);
f_shutdown_helper();
}
control {
/* CTRL interface testing */
execute( TC_ctrl_msc_connection_status() );
@ -10702,6 +10854,9 @@ control {
execute( TC_ctrl_trx_rf_locked() );
execute( TC_ratectr_all_available_allocated() );
execute( TC_ratectr_all_available_allocated_dyn() );
execute( TC_lost_sdcch_during_assignment() );
}

View File

@ -23,6 +23,8 @@ module Osmocom_CTRL_Functions {
import from Osmocom_CTRL_Types all;
import from IPA_Emulation all;
type record of charstring charstring_list;
private function f_gen_rand_id() return CtrlId {
return int2str(float2int(rnd()*999999999.0));
}
@ -289,4 +291,81 @@ module Osmocom_CTRL_Functions {
}
}
/* For a specific instance, call f_counter_name_vals_get() and indentify counters that have changed with respect
* to 'vals'. Return list of the changed counter names in the order they appear in 'vals'. */
function f_counter_name_vals_get_changed(IPA_CTRL_PT pt, charstring instance_name, integer instance_nr,
CounterNameVals vals)
return charstring_list {
var charstring_list changed := {};
var CounterNameVals last := f_counter_name_vals_get(pt, instance_name, instance_nr, vals);
for (var integer i := 0; i < lengthof(vals); i := i + 1) {
if (last[i].name != vals[i].name) {
setverdict(fail, "Internal error");
}
if (last[i].val != vals[i].val) {
changed := changed & { instance_name & "." & int2str(instance_nr) & "." & vals[i].name };
}
}
return changed;
}
/* For N instances, call f_counter_name_vals_get() and indentify counters that have changed with respect
* to 'vals'. Return list of the changed counter names in the order they appear in 'vals'. */
function f_counter_name_vals_get_changed_n(IPA_CTRL_PT pt, charstring instance_name, CounterNameValsList valslist)
return charstring_list {
var charstring_list changed := {};
for (var integer instance_nr := 0; instance_nr < lengthof(valslist); instance_nr := instance_nr + 1) {
changed := changed & f_counter_name_vals_get_changed(pt, instance_name, instance_nr, valslist[instance_nr]);
}
return changed;
}
function f_counter_name_vals_expect_changed(IPA_CTRL_PT pt, charstring instance_name, CounterNameValsList valslist,
charstring_list expect_changed) {
var charstring_list changed := f_counter_name_vals_get_changed_n(pt, instance_name, valslist);
f_counter_name_vals_expect_changed_list(changed, expect_changed);
}
function f_counter_name_vals_expect_changed_list(charstring_list got_list, charstring_list expect_list) {
var charstring unexpected_change := "";
for (var integer i := 0; i < lengthof(got_list); i := i + 1) {
var boolean found := false;
for (var integer j := 0; j < lengthof(expect_list); j := j + 1) {
if (got_list[i] == expect_list[j]) {
found := true;
break;
}
}
if (not found) {
unexpected_change := unexpected_change & " " & got_list[i];
}
}
var charstring missing_change := "";
for (var integer i := 0; i < lengthof(expect_list); i := i + 1) {
var boolean found := false;
for (var integer j := 0; j < lengthof(got_list); j := j + 1) {
if (expect_list[i] == got_list[j]) {
found := true;
break;
}
}
if (not found) {
missing_change := missing_change & " " & expect_list[i];
}
}
var charstring diff := "";
if (lengthof(unexpected_change) > 0) {
diff := diff & " Unexpected changes in" & unexpected_change & ";";
}
if (lengthof(missing_change) > 0) {
diff := diff & " Missing changes in" & missing_change & ";";
}
if (lengthof(diff) > 0) {
log("ERROR\nExpected: ", expect_list, "\nGot: ", got_list);
setverdict(fail, "Rate counters did not change as expected:" & diff);
} else {
setverdict(pass);
}
}
}