<p>neels <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/25969">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  neels: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">bsc: add TC_ratectr_all_available_allocated and _dyn<br><br>Test new rate counters all_allocated:{sdcch,tch,static_sdcch,static_tch}<br><br>Related: SYS#4878<br>Depends: I2fa14531f16d3f07085620f1c50eb839c420da6a (osmo-bsc)<br>Change-Id: Ib3997a827c9cc43d1361bb0cf3bfab9f6d91bf82<br>---<br>M bsc/BSC_Tests.ttcn<br>M library/Osmocom_CTRL_Functions.ttcn<br>2 files changed, 234 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn</span><br><span>index 833b6f9..6040a96 100644</span><br><span>--- a/bsc/BSC_Tests.ttcn</span><br><span>+++ b/bsc/BSC_Tests.ttcn</span><br><span>@@ -1642,6 +1642,8 @@</span><br><span>       RslChannelNr rsl_chan_nr</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+type record of DchanTuple DchanTuples;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Send CHAN RQD and wait for allocation; acknowledge it */</span><br><span> private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)</span><br><span> runs on test_CT return RslChannelNr {</span><br><span>@@ -10393,6 +10395,156 @@</span><br><span>       f_shutdown_helper();</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+const CounterNameVals counternames_bsc_bts_all_available_allocated := {</span><br><span style="color: hsl(120, 100%, 40%);">+        { "all_allocated:sdcch", 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "all_allocated:static_sdcch", 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "all_allocated:tch", 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "all_allocated:static_tch", 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Make sure counters settle first */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_sleep(1.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Take a baseline of counters */</span><br><span style="color: hsl(120, 100%, 40%);">+     f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Elapse some time so that we see changes in counters, hopefully where expected */</span><br><span style="color: hsl(120, 100%, 40%);">+   f_sleep(2.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Get new counters */</span><br><span style="color: hsl(120, 100%, 40%);">+        var charstring_list all_changed := {};</span><br><span style="color: hsl(120, 100%, 40%);">+        all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);</span><br><span style="color: hsl(120, 100%, 40%);">+     all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Compare with expectations */</span><br><span style="color: hsl(120, 100%, 40%);">+       var charstring_list all_expect_changed := {};</span><br><span style="color: hsl(120, 100%, 40%);">+ for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+               all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_ratectr_all_available_allocated() runs on test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+       var ASP_RSL_Unitdata rsl_ud;</span><br><span style="color: hsl(120, 100%, 40%);">+  var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+        var integer chreq_total, chreq_nochan;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      f_init(1);</span><br><span style="color: hsl(120, 100%, 40%);">+    f_sleep(1.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Exhaust all dedicated SDCCH lchans.</span><br><span style="color: hsl(120, 100%, 40%);">+        /* GSM 44.018 Table 9.1.8.2:</span><br><span style="color: hsl(120, 100%, 40%);">+   * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").</span><br><span style="color: hsl(120, 100%, 40%);">+      */</span><br><span style="color: hsl(120, 100%, 40%);">+   for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+            f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc</span><br><span style="color: hsl(120, 100%, 40%);">+         * level.</span><br><span style="color: hsl(120, 100%, 40%);">+      * All SDCCH are now occupied. */</span><br><span style="color: hsl(120, 100%, 40%);">+     f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Also fill up all remaining (TCH) channels */</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+          f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* All TCH are now also occupied */</span><br><span style="color: hsl(120, 100%, 40%);">+   f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",</span><br><span style="color: hsl(120, 100%, 40%);">+                       "all_allocated:tch", "all_allocated:static_tch"});</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      f_shutdown_helper();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {</span><br><span style="color: hsl(120, 100%, 40%);">+        var ASP_RSL_Unitdata rsl_ud;</span><br><span style="color: hsl(120, 100%, 40%);">+  var integer i;</span><br><span style="color: hsl(120, 100%, 40%);">+        var integer chreq_total, chreq_nochan;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      f_init_vty();</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");</span><br><span style="color: hsl(120, 100%, 40%);">+       f_vty_transceive(BSCVTY, "drop bts connection 0 oml");</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      f_init(1, guard_timeout := 60.0);</span><br><span style="color: hsl(120, 100%, 40%);">+     f_sleep(1.0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* The dyn TS wants to activate PDCH mode, ACK that. */</span><br><span style="color: hsl(120, 100%, 40%);">+       var RslChannelNr chan_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+     chan_nr := valueof(t_RslChanNr_PDCH(2));</span><br><span style="color: hsl(120, 100%, 40%);">+      f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));</span><br><span style="color: hsl(120, 100%, 40%);">+    f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Exhaust all dedicated SDCCH lchans.</span><br><span style="color: hsl(120, 100%, 40%);">+        /* GSM 44.018 Table 9.1.8.2:</span><br><span style="color: hsl(120, 100%, 40%);">+   * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").</span><br><span style="color: hsl(120, 100%, 40%);">+      */</span><br><span style="color: hsl(120, 100%, 40%);">+   for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+            f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only</span><br><span style="color: hsl(120, 100%, 40%);">+  * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */</span><br><span style="color: hsl(120, 100%, 40%);">+        f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.</span><br><span style="color: hsl(120, 100%, 40%);">+       * Will release them later, so remember all the DchanTuples. */</span><br><span style="color: hsl(120, 100%, 40%);">+       var DchanTuples dyn_sddch := {};</span><br><span style="color: hsl(120, 100%, 40%);">+      dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Also occupy the seven other SDCCH of the dyn TS */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 0; i < 7; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+            dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */</span><br><span style="color: hsl(120, 100%, 40%);">+      f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i := 0; i < 5; i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+            f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* All TCH lchans are now also occupied, both static and dynamic */</span><br><span style="color: hsl(120, 100%, 40%);">+   f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",</span><br><span style="color: hsl(120, 100%, 40%);">+                       "all_allocated:tch", "all_allocated:static_tch"});</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops</span><br><span style="color: hsl(120, 100%, 40%);">+         * incrementing. */</span><br><span style="color: hsl(120, 100%, 40%);">+   var BssmapCause cause := 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   var DchanTuple dt := dyn_sddch[0];</span><br><span style="color: hsl(120, 100%, 40%);">+    BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));</span><br><span style="color: hsl(120, 100%, 40%);">+        f_exp_chan_rel_and_clear(dt, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic</span><br><span style="color: hsl(120, 100%, 40%);">+         * count as occupied, so those still both increment. */</span><br><span style="color: hsl(120, 100%, 40%);">+       f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",</span><br><span style="color: hsl(120, 100%, 40%);">+                        "all_allocated:tch", "all_allocated:static_tch"});</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i := 1; i < lengthof(dyn_sddch); i := i+1) {</span><br><span style="color: hsl(120, 100%, 40%);">+          dt := dyn_sddch[i];</span><br><span style="color: hsl(120, 100%, 40%);">+           BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));</span><br><span style="color: hsl(120, 100%, 40%);">+                f_exp_chan_rel_and_clear(dt, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */</span><br><span style="color: hsl(120, 100%, 40%);">+   chan_nr := valueof(t_RslChanNr_PDCH(2));</span><br><span style="color: hsl(120, 100%, 40%);">+      f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));</span><br><span style="color: hsl(120, 100%, 40%);">+    f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */</span><br><span style="color: hsl(120, 100%, 40%);">+     f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* clean up config */</span><br><span style="color: hsl(120, 100%, 40%);">+ f_ts_reset_chcomb(0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       f_shutdown_helper();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> control {</span><br><span>       /* CTRL interface testing */</span><br><span>         execute( TC_ctrl_msc_connection_status() );</span><br><span>@@ -10702,6 +10854,9 @@</span><br><span> </span><br><span>    execute( TC_ctrl_trx_rf_locked() );</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       execute( TC_ratectr_all_available_allocated() );</span><br><span style="color: hsl(120, 100%, 40%);">+      execute( TC_ratectr_all_available_allocated_dyn() );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       execute( TC_lost_sdcch_during_assignment() );</span><br><span> }</span><br><span> </span><br><span>diff --git a/library/Osmocom_CTRL_Functions.ttcn b/library/Osmocom_CTRL_Functions.ttcn</span><br><span>index 8d5607b..2c90de4 100644</span><br><span>--- a/library/Osmocom_CTRL_Functions.ttcn</span><br><span>+++ b/library/Osmocom_CTRL_Functions.ttcn</span><br><span>@@ -23,6 +23,8 @@</span><br><span>  import from Osmocom_CTRL_Types all;</span><br><span>  import from IPA_Emulation all;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    type record of charstring charstring_list;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         private function f_gen_rand_id() return CtrlId {</span><br><span>             return int2str(float2int(rnd()*999999999.0));</span><br><span>        }</span><br><span>@@ -289,4 +291,81 @@</span><br><span>             }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* For a specific instance, call f_counter_name_vals_get() and indentify counters that have changed with respect</span><br><span style="color: hsl(120, 100%, 40%);">+       * to 'vals'. Return list of the changed counter names in the order they appear in 'vals'. */</span><br><span style="color: hsl(120, 100%, 40%);">+ function f_counter_name_vals_get_changed(IPA_CTRL_PT pt, charstring instance_name, integer instance_nr,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                CounterNameVals vals)</span><br><span style="color: hsl(120, 100%, 40%);">+        return charstring_list {</span><br><span style="color: hsl(120, 100%, 40%);">+              var charstring_list changed := {};</span><br><span style="color: hsl(120, 100%, 40%);">+            var CounterNameVals last := f_counter_name_vals_get(pt, instance_name, instance_nr, vals);</span><br><span style="color: hsl(120, 100%, 40%);">+            for (var integer i := 0; i < lengthof(vals); i := i + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (last[i].name != vals[i].name) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           setverdict(fail, "Internal error");</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (last[i].val != vals[i].val) {</span><br><span style="color: hsl(120, 100%, 40%);">+                             changed := changed & { instance_name & "." & int2str(instance_nr) & "." & vals[i].name };</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             return changed;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* For N instances, call f_counter_name_vals_get() and indentify counters that have changed with respect</span><br><span style="color: hsl(120, 100%, 40%);">+       * to 'vals'. Return list of the changed counter names in the order they appear in 'vals'. */</span><br><span style="color: hsl(120, 100%, 40%);">+ function f_counter_name_vals_get_changed_n(IPA_CTRL_PT pt, charstring instance_name, CounterNameValsList valslist)</span><br><span style="color: hsl(120, 100%, 40%);">+    return charstring_list {</span><br><span style="color: hsl(120, 100%, 40%);">+              var charstring_list changed := {};</span><br><span style="color: hsl(120, 100%, 40%);">+            for (var integer instance_nr := 0; instance_nr < lengthof(valslist); instance_nr := instance_nr + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     changed := changed & f_counter_name_vals_get_changed(pt, instance_name, instance_nr, valslist[instance_nr]);</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             return changed;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   function f_counter_name_vals_expect_changed(IPA_CTRL_PT pt, charstring instance_name, CounterNameValsList valslist,</span><br><span style="color: hsl(120, 100%, 40%);">+                                               charstring_list expect_changed) {</span><br><span style="color: hsl(120, 100%, 40%);">+         var charstring_list changed := f_counter_name_vals_get_changed_n(pt, instance_name, valslist);</span><br><span style="color: hsl(120, 100%, 40%);">+                f_counter_name_vals_expect_changed_list(changed, expect_changed);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   function f_counter_name_vals_expect_changed_list(charstring_list got_list, charstring_list expect_list) {</span><br><span style="color: hsl(120, 100%, 40%);">+             var charstring unexpected_change := "";</span><br><span style="color: hsl(120, 100%, 40%);">+             for (var integer i := 0; i < lengthof(got_list); i := i + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     var boolean found := false;</span><br><span style="color: hsl(120, 100%, 40%);">+                   for (var integer j := 0; j < lengthof(expect_list); j := j + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (got_list[i] == expect_list[j]) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                  found := true;</span><br><span style="color: hsl(120, 100%, 40%);">+                                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                                }</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (not found) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              unexpected_change := unexpected_change & " " & got_list[i];</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             var charstring missing_change := "";</span><br><span style="color: hsl(120, 100%, 40%);">+                for (var integer i := 0; i < lengthof(expect_list); i := i + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  var boolean found := false;</span><br><span style="color: hsl(120, 100%, 40%);">+                   for (var integer j := 0; j < lengthof(got_list); j := j + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (expect_list[i] == got_list[j]) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                  found := true;</span><br><span style="color: hsl(120, 100%, 40%);">+                                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                                }</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (not found) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              missing_change := missing_change & " " & expect_list[i];</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             var charstring diff := "";</span><br><span style="color: hsl(120, 100%, 40%);">+          if (lengthof(unexpected_change) > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     diff := diff & " Unexpected changes in" & unexpected_change & ";";</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (lengthof(missing_change) > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        diff := diff & " Missing changes in" & missing_change & ";";</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (lengthof(diff) > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  log("ERROR\nExpected: ", expect_list, "\nGot: ", got_list);</span><br><span style="color: hsl(120, 100%, 40%);">+                       setverdict(fail, "Rate counters did not change as expected:" & diff);</span><br><span style="color: hsl(120, 100%, 40%);">+           } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      setverdict(pass);</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/25969">change 25969</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/25969"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-ttcn3-hacks </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ib3997a827c9cc43d1361bb0cf3bfab9f6d91bf82 </div>
<div style="display:none"> Gerrit-Change-Number: 25969 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>