neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-gsm-tester/+/21523 )
Change subject: add handover_2G suite, with handover.py test ...................................................................... add handover_2G suite, with handover.py test Via VTY, handover two lchans of a voice call from bts0 to bts1 and back. New scenarios/bts1-* allow selecting various types for bts1, complementing the already existing files for selecting bts0. Change-Id: I0b2671304165a1aaae2b386af46fbd8b098e3bd8 --- M src/osmo_gsm_tester/obj/bsc_osmo.py M src/osmo_gsm_tester/testenv.py A sysmocom/handover-suites.conf A sysmocom/scenarios/bts1-nanobts.conf A sysmocom/scenarios/bts1-oc2g.conf A sysmocom/scenarios/bts1-octphy.conf A sysmocom/scenarios/bts1-sysmo.conf A sysmocom/scenarios/bts1-trx-b200.conf A sysmocom/scenarios/bts1-trx-lms-limenet-micro.conf A sysmocom/scenarios/bts1-trx-lms.conf A sysmocom/scenarios/bts1-trx-sysmocell5000.conf A sysmocom/scenarios/bts1-trx-umtrx.conf A sysmocom/suites/handover_2G/handover.py A sysmocom/suites/handover_2G/suite.conf 14 files changed, 315 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/23/21523/1 diff --git a/src/osmo_gsm_tester/obj/bsc_osmo.py b/src/osmo_gsm_tester/obj/bsc_osmo.py index 62026e6..1be3277 100644 --- a/src/osmo_gsm_tester/obj/bsc_osmo.py +++ b/src/osmo_gsm_tester/obj/bsc_osmo.py @@ -154,6 +154,9 @@ def vty(self): return OsmoBscVty(self) + def ctrl(self): + return OsmoBscCtrl(self).ctrl() + def get_active_lchans(self): lchan_summary = self.vty().cmd('show lchan summary') diff --git a/src/osmo_gsm_tester/testenv.py b/src/osmo_gsm_tester/testenv.py index 651183c..c7e0f65 100644 --- a/src/osmo_gsm_tester/testenv.py +++ b/src/osmo_gsm_tester/testenv.py @@ -31,6 +31,7 @@ from .core import resource from .core.event_loop import MainLoop +test = None suite = None log = None dbg = None diff --git a/sysmocom/handover-suites.conf b/sysmocom/handover-suites.conf new file mode 100644 index 0000000..623bbfb --- /dev/null +++ b/sysmocom/handover-suites.conf @@ -0,0 +1,36 @@ +- handover_2G:nanobts+bts1-oc2g +- handover_2G:nanobts+bts1-octphy +- handover_2G:nanobts+bts1-trx-lms +- handover_2G:nanobts+bts1-trx-lms-limenet-micro +- handover_2G:nanobts+bts1-trx-sysmocell5000 +- handover_2G:nanobts+bts1-sysmo +- handover_2G:nanobts+bts1-trx-b200 +- handover_2G:nanobts+bts1-trx-umtrx +- handover_2G:oc2g+bts1-octphy +- handover_2G:oc2g+bts1-trx-lms +- handover_2G:oc2g+bts1-trx-lms-limenet-micro +- handover_2G:oc2g+bts1-trx-sysmocell5000 +- handover_2G:oc2g+bts1-sysmo +- handover_2G:oc2g+bts1-trx-b200 +- handover_2G:oc2g+bts1-trx-umtrx +- handover_2G:octphy+bts1-trx-lms +- handover_2G:octphy+bts1-trx-lms-limenet-micro +- handover_2G:octphy+bts1-trx-sysmocell5000 +- handover_2G:octphy+bts1-sysmo +- handover_2G:octphy+bts1-trx-b200 +- handover_2G:octphy+bts1-trx-umtrx +- handover_2G:trx-lms+bts1-trx-lms-limenet-micro +- handover_2G:trx-lms+bts1-trx-sysmocell5000 +- handover_2G:trx-lms+bts1-sysmo +- handover_2G:trx-lms+bts1-trx-b200 +- handover_2G:trx-lms+bts1-trx-umtrx +- handover_2G:trx-lms-limenet-micro+bts1-trx-sysmocell5000 +- handover_2G:trx-lms-limenet-micro+bts1-sysmo +- handover_2G:trx-lms-limenet-micro+bts1-trx-b200 +- handover_2G:trx-lms-limenet-micro+bts1-trx-umtrx +- handover_2G:trx-sysmocell5000+bts1-sysmo +- handover_2G:trx-sysmocell5000+bts1-trx-b200 +- handover_2G:trx-sysmocell5000+bts1-trx-umtrx +- handover_2G:sysmo+bts1-trx-b200 +- handover_2G:sysmo+bts1-trx-umtrx +- handover_2G:trx-b200+bts1-trx-umtrx diff --git a/sysmocom/scenarios/bts1-nanobts.conf b/sysmocom/scenarios/bts1-nanobts.conf new file mode 100644 index 0000000..2425b7f --- /dev/null +++ b/sysmocom/scenarios/bts1-nanobts.conf @@ -0,0 +1,4 @@ +resources: + bts: + - {} + - type: nanobts diff --git a/sysmocom/scenarios/bts1-oc2g.conf b/sysmocom/scenarios/bts1-oc2g.conf new file mode 100644 index 0000000..ff45d8e --- /dev/null +++ b/sysmocom/scenarios/bts1-oc2g.conf @@ -0,0 +1,4 @@ +resources: + bts: + - {} + - type: osmo-bts-oc2g diff --git a/sysmocom/scenarios/bts1-octphy.conf b/sysmocom/scenarios/bts1-octphy.conf new file mode 100644 index 0000000..2eb51d1 --- /dev/null +++ b/sysmocom/scenarios/bts1-octphy.conf @@ -0,0 +1,4 @@ +resources: + bts: + - {} + - type: osmo-bts-octphy diff --git a/sysmocom/scenarios/bts1-sysmo.conf b/sysmocom/scenarios/bts1-sysmo.conf new file mode 100644 index 0000000..fa466a8 --- /dev/null +++ b/sysmocom/scenarios/bts1-sysmo.conf @@ -0,0 +1,4 @@ +resources: + bts: + - {} + - type: osmo-bts-sysmo diff --git a/sysmocom/scenarios/bts1-trx-b200.conf b/sysmocom/scenarios/bts1-trx-b200.conf new file mode 100644 index 0000000..9927b88 --- /dev/null +++ b/sysmocom/scenarios/bts1-trx-b200.conf @@ -0,0 +1,5 @@ +resources: + bts: + - {} + - label: Ettus B200 + type: osmo-bts-trx diff --git a/sysmocom/scenarios/bts1-trx-lms-limenet-micro.conf b/sysmocom/scenarios/bts1-trx-lms-limenet-micro.conf new file mode 100644 index 0000000..e0536ec --- /dev/null +++ b/sysmocom/scenarios/bts1-trx-lms-limenet-micro.conf @@ -0,0 +1,5 @@ +resources: + bts: + - {} + - label: LimeNET-Micro + type: osmo-bts-trx diff --git a/sysmocom/scenarios/bts1-trx-lms.conf b/sysmocom/scenarios/bts1-trx-lms.conf new file mode 100644 index 0000000..df644c0 --- /dev/null +++ b/sysmocom/scenarios/bts1-trx-lms.conf @@ -0,0 +1,5 @@ +resources: + bts: + - {} + - label: LimeSDR-USB + type: osmo-bts-trx diff --git a/sysmocom/scenarios/bts1-trx-sysmocell5000.conf b/sysmocom/scenarios/bts1-trx-sysmocell5000.conf new file mode 100644 index 0000000..d5d3069 --- /dev/null +++ b/sysmocom/scenarios/bts1-trx-sysmocell5000.conf @@ -0,0 +1,5 @@ +resources: + bts: + - {} + - label: sysmoCell 5000 + type: osmo-bts-trx diff --git a/sysmocom/scenarios/bts1-trx-umtrx.conf b/sysmocom/scenarios/bts1-trx-umtrx.conf new file mode 100644 index 0000000..e8504bf --- /dev/null +++ b/sysmocom/scenarios/bts1-trx-umtrx.conf @@ -0,0 +1,5 @@ +resources: + bts: + - {} + - label: UmTRX + type: osmo-bts-trx diff --git a/sysmocom/suites/handover_2G/handover.py b/sysmocom/suites/handover_2G/handover.py new file mode 100755 index 0000000..f5476d9 --- /dev/null +++ b/sysmocom/suites/handover_2G/handover.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python3 +from osmo_gsm_tester.testenv import * +from osmo_gsm_tester.obj.osmo_ctrl import * + +hlr = tenv.hlr() +bts0 = tenv.bts() +bts1 = tenv.bts() +mgw_msc = tenv.mgw() +mgw_bsc = tenv.mgw() +stp = tenv.stp() +msc = tenv.msc(hlr, mgw_msc, stp) +bsc = tenv.bsc(msc, mgw_bsc, stp) +ms_mo = tenv.modem() +ms_mt = tenv.modem() + +hlr.start() +stp.start() +msc.start() +mgw_msc.start() +mgw_bsc.start() +bsc.bts_add(bts0) +bsc.bts_add(bts1) +bsc.start() + +# prevent handovers from measurement reports, enable handover so that +# triggering handover from VTY works. +bsc.vty().cmds( + 'enable', + 'configure terminal', + 'network', + 'handover algorithm 2', + 'handover2 min rxlev -110', + 'handover2 min rxqual 7', + 'handover2 power budget hysteresis 999', + 'handover 1') + +# first start only the first BTS, to make sure both modems subscribe there +with test.report_fragment('01_bts0_started'): + bts0.start() + wait(bsc.bts_is_connected, bts0) + +hlr.subscriber_add(ms_mo) +hlr.subscriber_add(ms_mt) + +ms_mo.connect(msc.mcc_mnc()) +ms_mt.connect(msc.mcc_mnc()) + +ms_mo.log_info() +ms_mt.log_info() + +print('waiting for modems to attach...') + +with test.report_fragment('02.1_ms0_attach'): + wait(ms_mo.is_registered, msc.mcc_mnc()) + +with test.report_fragment('02.2_ms1_attach'): + wait(ms_mt.is_registered, msc.mcc_mnc()) + +with test.report_fragment('02.3_subscribed_in_msc'): + wait(msc.subscriber_attached, ms_mo, ms_mt) + +assert len(ms_mo.call_id_list()) == 0 and len(ms_mt.call_id_list()) == 0 +mo_cid = ms_mo.call_dial(ms_mt) +mt_cid = ms_mt.call_wait_incoming(ms_mo) +print('dial success') + +with test.report_fragment('03_call_established'): + assert not ms_mo.call_is_active(mo_cid) and not ms_mt.call_is_active(mt_cid) + ms_mt.call_answer(mt_cid) + wait(ms_mo.call_is_active, mo_cid) + wait(ms_mt.call_is_active, mt_cid) + print('answer success, call established and ongoing') + + assert bsc.active_lchans_match( + expected=('0-0-2-0 TCH/F ESTABLISHED', + '0-0-3-0 TCH/F ESTABLISHED')) + +# call is connected; start up the second BTS so that we can trigger a handover to it +with test.report_fragment('04.1_bts1_started'): + bts1.start() + wait(bsc.bts_is_connected, bts1) + +print('wait a bit for modems to see bts1') +sleep(10.0) + +print('starting the second BTS probably took a while, check on the ongoing call') +assert bsc.active_lchans_match( + expected=('0-0-2-0 TCH/F ESTABLISHED', + '0-0-3-0 TCH/F ESTABLISHED')) + +with bsc.ctrl() as bsc_ctrl: + counter_names = ( + 'handover:completed', + 'handover:stopped', + 'handover:no_channel', + 'handover:timeout', + 'handover:failed', + 'handover:error', + ) + counters = RateCounters('bsc', counter_names, from_ctrl=bsc_ctrl) + counters.add(RateCounters('bts', counter_names, instances=(0, 1))) + + def do_handover(initial_lchans, target_lchan, vty_cmd, final_lchans, attempts=5): + worked = False + while (attempts > 0) and (not worked): + # make sure the call is still active as expected + assert bsc.active_lchans_match(**initial_lchans) + # make sure the handover target lchan is unused (maybe waiting after previous error) + wait(bsc.active_lchans_match, **target_lchan, timeout=20) + + counters.read() + log_mark = bsc.process.get_output_mark('stderr') + + print('trigger handover: %s' % vty_cmd) + bsc.vty().cmds('enable', vty_cmd) + + print('wait for handover counters to change...') + wait_no_raise(counters.changed, timeout=20) + print(counters.diff.str(skip_zero_vals=True)) + + print('\n'+'\n'.join(bsc.process.grep_output('stderr', r'\bhandover\(|\bDCHAN\b', log_mark))) + + worked = bsc.active_lchans_match(**final_lchans) + if not worked and attempts > 0: + attempts -= 1 + print('did not work, try again... (attempts left: %d)' % attempts) + return worked + + + with test.report_fragment('05.1_handover'): + assert do_handover( + initial_lchans=dict( + expected=('0-0-2-0 TCH/F ESTABLISHED', + '0-0-3-0 TCH/F ESTABLISHED'), + ), + target_lchan=dict( + not_expected=('1-0-2-0',), + ), + vty_cmd='bts 0 trx 0 timeslot 2 sub-slot 0 handover 1', + final_lchans=dict( + expected=('0-0-3-0 TCH/F ESTABLISHED', + '1-0-2-0 TCH/F ESTABLISHED',), + not_expected=('0-0-2-0 TCH/F ESTABLISHED',), + ), + ) + + with test.report_fragment('05.2_handover'): + assert do_handover( + initial_lchans=dict( + expected=('0-0-3-0 TCH/F ESTABLISHED', + '1-0-2-0 TCH/F ESTABLISHED'), + ), + target_lchan=dict( + not_expected=('1-0-3-0',), + ), + vty_cmd='bts 0 trx 0 timeslot 3 sub-slot 0 handover 1', + final_lchans=dict( + expected=('1-0-2-0 TCH/F ESTABLISHED', + '1-0-3-0 TCH/F ESTABLISHED',), + not_expected=('0-0-2-0 TCH/F ESTABLISHED', + '0-0-3-0 TCH/F ESTABLISHED',), + ), + ) + + with test.report_fragment('06_call_stable'): + print('expect the call to continue for a while, to ensure the new lchan is functional') + for i in range(5): + sleep(5) + assert bsc.active_lchans_match( + expected=('1-0-2-0 TCH/F ESTABLISHED', + '1-0-3-0 TCH/F ESTABLISHED',)) + print('call is still fine') + + print('handover back (test the other BTS model)') + + with test.report_fragment('07.1_handover'): + assert do_handover( + initial_lchans=dict( + expected=('1-0-2-0 TCH/F ESTABLISHED', + '1-0-3-0 TCH/F ESTABLISHED'), + ), + target_lchan=dict( + not_expected=('0-0-2-0',), + ), + vty_cmd='bts 1 trx 0 timeslot 3 sub-slot 0 handover 0', + final_lchans=dict( + expected=('0-0-2-0 TCH/F ESTABLISHED', + '1-0-2-0 TCH/F ESTABLISHED',), + not_expected=('1-0-3-0 TCH/F ESTABLISHED',), + ), + ) + + with test.report_fragment('07.2_handover'): + assert do_handover( + initial_lchans=dict( + expected=('0-0-2-0 TCH/F ESTABLISHED', + '1-0-2-0 TCH/F ESTABLISHED'), + ), + target_lchan=dict( + not_expected=('0-0-3-0',), + ), + vty_cmd='bts 1 trx 0 timeslot 2 sub-slot 0 handover 0', + final_lchans=dict( + expected=('0-0-2-0 TCH/F ESTABLISHED', + '0-0-3-0 TCH/F ESTABLISHED',), + not_expected=('1-0-2-0 TCH/F ESTABLISHED', + '1-0-3-0 TCH/F ESTABLISHED',), + ), + ) + + with test.report_fragment('08_call_stable'): + print('expect the call to continue for a while, to ensure the new lchan is functional') + for i in range(5): + sleep(5) + assert bsc.active_lchans_match( + expected=('0-0-2-0 TCH/F ESTABLISHED', + '0-0-3-0 TCH/F ESTABLISHED',)) + print('call is still fine') + + assert ms_mo.call_is_active(mo_cid) and ms_mt.call_is_active(mt_cid) + ms_mt.call_hangup(mt_cid) + wait(lambda: len(ms_mo.call_id_list()) == 0 and len(ms_mt.call_id_list()) == 0) + print('hangup success') + +# vim: tabstop=4 shiftwidth=4 expandtab diff --git a/sysmocom/suites/handover_2G/suite.conf b/sysmocom/suites/handover_2G/suite.conf new file mode 100644 index 0000000..00d3fca --- /dev/null +++ b/sysmocom/suites/handover_2G/suite.conf @@ -0,0 +1,9 @@ +resources: + ip_address: + - times: 6 # msc, bsc, hlr, stp, mgw*2 + bts: + - times: 2 + modem: + - times: 2 + features: + - voice -- To view, visit https://gerrit.osmocom.org/c/osmo-gsm-tester/+/21523 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Change-Id: I0b2671304165a1aaae2b386af46fbd8b098e3bd8 Gerrit-Change-Number: 21523 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofm...@sysmocom.de> Gerrit-MessageType: newchange