BSC_Tests: add TC_chan_alloc_algo_ass_dynamic

This test case verifies the new channel allocation mode, which
is expected to switch between ascending and descending modes
dynamically based on the following two configurable parameters:

* Uplink RxLev threshold (and min number of samples),
* C0 (BCCH carrier) channel load threshold.

The test case scenario includes:

Case a) Unknown Uplink RxLev => fall-back to ascending.
Case b) Not enough RxLev samples => use ascending.
Case c) Uplink RxLev below the threshold => use ascending.
Case d) Uplink RxLev above the threshold => use descending.
Case e) Uplink RxLev above the threshold, but C0 load is not.

Change-Id: Ia522f37c1c001b3a36f5145b8875fbb88311c2e5
Related: SYS#5460
diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn
index 7070c9f..f3e15ef 100644
--- a/bsc/BSC_Tests.ttcn
+++ b/bsc/BSC_Tests.ttcn
@@ -11638,6 +11638,83 @@
 	f_shutdown_helper();
 }
 
+testcase TC_chan_alloc_algo_ass_dynamic() runs on test_CT {
+	const BtsTrxIdx TRX0 := {2, 0};
+	const BtsTrxIdx TRX3 := {2, 3};
+
+	/* We need to access BTS2, which has 4 TRXs */
+	f_init(nr_bts := 3);
+
+	/* HACK: work around "Couldn't find Expect for CRCX" */
+	vc_MGCP.stop;
+
+	f_vty_enter_cfg_bts(BSCVTY, 2);
+	f_vty_transceive(BSCVTY, "channel allocator mode assignment dynamic");
+	f_vty_transceive(BSCVTY, "channel allocator dynamic-param ul-rxlev thresh 50 avg-num 2");
+	f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 0");
+	f_vty_transceive(BSCVTY, "end");
+
+	var DchanTuple dt;
+
+	f_logp(BSCVTY, "Case a) Unknown Uplink RxLev, fall-back to ascending");
+	dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
+	f_TC_chan_alloc_algo(dt, TRX0);
+	f_perform_clear_test_ct(dt);
+
+	f_logp(BSCVTY, "Case b) Not enough RxLev samples, use ascending");
+	dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
+	f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
+				       ts_RSL_IE_UplinkMeas(30, 0),
+				       ts_RSL_IE_BS_Power(0)), TRX0);
+	f_TC_chan_alloc_algo(dt, TRX0);
+	f_perform_clear_test_ct(dt);
+
+	f_logp(BSCVTY, "Case c) Uplink RxLev below the threshold, use ascending");
+	dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
+	f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
+				       ts_RSL_IE_UplinkMeas(45, 0),
+				       ts_RSL_IE_BS_Power(0)), TRX0);
+	f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
+				       ts_RSL_IE_UplinkMeas(48, 0),
+				       ts_RSL_IE_BS_Power(0)), TRX0);
+	f_TC_chan_alloc_algo(dt, TRX0);
+	f_perform_clear_test_ct(dt);
+
+	f_logp(BSCVTY, "Case d) Uplink RxLev above the threshold, use descending");
+	dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
+	f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
+				       ts_RSL_IE_UplinkMeas(50, 0),
+				       ts_RSL_IE_BS_Power(0)), TRX0);
+	f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
+				       ts_RSL_IE_UplinkMeas(58, 0),
+				       ts_RSL_IE_BS_Power(0)), TRX0);
+	f_TC_chan_alloc_algo(dt, TRX3);
+	f_perform_clear_test_ct(dt);
+
+	f_vty_enter_cfg_bts(BSCVTY, 2);
+	f_vty_transceive(BSCVTY, "channel allocator dynamic-param c0-chan-load thresh 90");
+	f_vty_transceive(BSCVTY, "end");
+
+	f_logp(BSCVTY, "Case e) Uplink RxLev above the threshold, but C0 load is not");
+	dt := f_est_dchan('23'O, 23, '00000000'O, TRX0);
+	f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 0,
+				       ts_RSL_IE_UplinkMeas(50, 0),
+				       ts_RSL_IE_BS_Power(0)), TRX0);
+	f_ipa_tx(ts_RSL_MEAS_RES_EMPTY(dt.rsl_chan_nr, 1,
+				       ts_RSL_IE_UplinkMeas(58, 0),
+				       ts_RSL_IE_BS_Power(0)), TRX0);
+	f_TC_chan_alloc_algo(dt, TRX0);
+	f_perform_clear_test_ct(dt);
+
+	f_vty_enter_cfg_bts(BSCVTY, 2);
+	f_vty_transceive(BSCVTY, "channel allocator ascending");
+	f_vty_transceive(BSCVTY, "end");
+
+	/* At this point some TCH/F channels are BORKEN, but they will be
+	 * resurrected upon the A-bis/OML link re-establishment. */
+	f_shutdown_helper();
+}
+
 control {
 	/* CTRL interface testing */
 	execute( TC_ctrl_msc_connection_status() );
@@ -11967,6 +12044,7 @@
 	/* Channel allocator */
 	execute( TC_chan_alloc_algo_ascending() );
 	execute( TC_chan_alloc_algo_descending() );
+	execute( TC_chan_alloc_algo_ass_dynamic() );
 
 	/* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
 	 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */