suites: 4g: Parametrize handover.py test

Change-Id: I7de5acdaa6b905e52655786758bd51490add1d2b
diff --git a/sysmocom/scenarios/suite-4g@.conf b/sysmocom/scenarios/suite-4g@.conf
new file mode 100644
index 0000000..6c36e4c
--- /dev/null
+++ b/sysmocom/scenarios/suite-4g@.conf
@@ -0,0 +1,6 @@
+config:
+  suite:
+    4g:
+      handover:
+        duration: ${param1}
+        threshold: ${param2}
diff --git a/sysmocom/suites/4g/handover.py b/sysmocom/suites/4g/handover.py
index 25b424b..a503465 100755
--- a/sysmocom/suites/4g/handover.py
+++ b/sysmocom/suites/4g/handover.py
@@ -1,10 +1,32 @@
 #!/usr/bin/env python3
 from osmo_gsm_tester.testenv import *
 
-epc = suite.epc()
-enb = suite.enb()
-ue = suite.modem()
-iperf3srv = suite.iperf3srv({'addr': epc.tun_addr()})
+import time
+
+test_config = tenv.config_test_specific()
+duration = int(test_config.get('duration', 0)) # 0 = one HO loop
+threshold = int(test_config.get('threshold', 2))
+
+import pprint
+print("TEST_CONFIG:\n" + pprint.pformat(test_config))
+
+# attenuation from 0 to 10, then back to 0
+cell1_att_li = list(range(0, 11, 1)) + list(range(9, -1, -1))
+# attenuation from 10 to 0, then back to 10
+cell2_att_li = list(range(10, 0, -1)) + list(range(0, 11, 1))
+
+def do_one_ho_loop(rfemu_cell1, rfemu_cell2):
+    step = 0
+    while step < len(cell1_att_li):
+        rfemu_cell1.set_attenuation(cell1_att_li[step])
+        rfemu_cell2.set_attenuation(cell2_att_li[step])
+        step += 1
+        sleep(1)
+
+epc = tenv.epc()
+enb = tenv.enb()
+ue = tenv.modem()
+iperf3srv = tenv.iperf3srv({'addr': epc.tun_addr()})
 iperf3srv.set_run_node(epc.run_node())
 iperf3cli = iperf3srv.create_client()
 iperf3cli.set_run_node(ue.run_node())
@@ -21,7 +43,7 @@
 ue.connect(enb)
 
 iperf3srv.start()
-proc = iperf3cli.prepare_test_proc(False, ue.netns(), 30)
+proc = iperf3cli.prepare_test_proc(False, ue.netns(), duration + 30)
 
 print('waiting for UE to attach...')
 wait(ue.is_connected, None)
@@ -30,22 +52,17 @@
 rfemu_cell1 = enb.get_rfemu(0)
 rfemu_cell2 = enb.get_rfemu(1)
 
-# attenuation from 0 to 10, then back to 0
-cell1_att_li = list(range(0, 11, 1)) + list(range(9, -1, -1))
-# attenuation from 10 to 0, then back to 10
-cell2_att_li = list(range(10, 0, -1)) + list(range(0, 11, 1))
-
+print('Iterating for %d seconds to produce at least %d handovers...' % (duration, threshold))
 try:
     proc.launch()
-    step = 0
-    while step < len(cell1_att_li):
-        rfemu_cell1.set_attenuation(cell1_att_li[step])
-        rfemu_cell2.set_attenuation(cell2_att_li[step])
-        step += 1
-        sleep(1)
+    t_end = time.time() + duration
+    if duration == 0:
+        t_end += 1 # allow loop to run once
+    while time.time() < t_end:
+        do_one_ho_loop(rfemu_cell1, rfemu_cell2)
     num_handovers = ue.get_counter('handover_success')
-    if num_handovers != 2:
-        raise Exception('Wrong number of handovers %d vs expected 2' % num_handovers)
+    if num_handovers < threshold:
+        raise Exception('Wrong number of handovers %d < threshold %d during %d seconds' % (num_handovers, threshold, duration))
 except Exception as e:
     try:
         proc.terminate() # make sure we always terminate the process
@@ -53,7 +70,7 @@
             print("Exception while terminating process %r" % repr(process))
     raise e
 
-rest_str = 'Got %d successful handovers' % num_handovers
+rest_str = 'Got %d successful handovers (>= %d) during %d seconds' % (num_handovers, threshold, duration)
 print(res_str)
 test.set_report_stdout(res_str)
 proc.terminate()
diff --git a/sysmocom/suites/4g/suite.conf b/sysmocom/suites/4g/suite.conf
index e439e99..fbd81b6 100644
--- a/sysmocom/suites/4g/suite.conf
+++ b/sysmocom/suites/4g/suite.conf
@@ -8,5 +8,10 @@
     features:
     - 4g
 
+schema:
+  handover:
+        duration: 'duration'
+        threshold: 'uint'
+
 defaults:
   timeout: 180s