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
diff --git a/library/Osmocom_CTRL_Functions.ttcn b/library/Osmocom_CTRL_Functions.ttcn
index 8d5607b..2c90de4 100644
--- a/library/Osmocom_CTRL_Functions.ttcn
+++ b/library/Osmocom_CTRL_Functions.ttcn
@@ -23,6 +23,8 @@
 	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 @@
 		}
 	}
 
+	/* 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);
+		}
+	}
+
 }