diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2018-07-27 16:24:29 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2018-07-27 16:24:31 +0200 |
commit | f6a07122823f8a0b01b40705d103199277925169 (patch) | |
tree | 20082a790f223036e8d93a74a168540783621496 | |
parent | 698ad4ce5050c1ee50c086a699ad98c730a8e115 (diff) |
nanobts: Support multiTRX
num_trx is left for now by default to 1, but it has been tested to work
properly (current tests pass and both trx are configured) with
num_trx=2.
Change-Id: Ib3962f824a804e2aa582601475a8514c6cb0d8e7
-rw-r--r-- | example/defaults.conf | 3 | ||||
-rw-r--r-- | example/resources.conf.prod | 28 | ||||
-rw-r--r-- | example/resources.conf.rnd | 11 | ||||
-rw-r--r-- | src/osmo_gsm_tester/bts_nanobts.py | 136 | ||||
-rw-r--r-- | src/osmo_gsm_tester/resource.py | 7 |
5 files changed, 109 insertions, 76 deletions
diff --git a/example/defaults.conf b/example/defaults.conf index 1e84200..f7bd1b1 100644 --- a/example/defaults.conf +++ b/example/defaults.conf @@ -58,3 +58,6 @@ bsc_bts: osmo_bts_octphy: max_trx: 2 + +nanobts: + max_trx: 2 diff --git a/example/resources.conf.prod b/example/resources.conf.prod index 6481254..6023fc4 100644 --- a/example/resources.conf.prod +++ b/example/resources.conf.prod @@ -47,22 +47,30 @@ bts: - label: NanoBTS-ONW-1900 type: nanobts ipa_unit_id: 9 - addr: 10.42.42.120 band: GSM-1900 - power_supply: - type: 'sispm' - device: '01:01:4d:98:24' - port: '1' + trx_list: + - addr: 10.42.42.120 + power_supply: + type: 'sispm' + device: '01:01:4d:98:24' + port: '1' - label: NanoBTS-ONW-900 type: nanobts ipa_unit_id: 10 - addr: 10.42.42.121 band: GSM-900 - power_supply: - type: 'sispm' - device: '01:01:4d:98:24' - port: '2' + num_trx: 1 + trx_list: + - addr: 10.42.42.121 + power_supply: + type: 'sispm' + device: '01:01:4d:98:24' + port: '2' + - addr: 10.42.42.122 + power_supply: + type: 'sispm' + device: '01:01:4d:98:24' + port: '3' arfcn: - arfcn: 512 diff --git a/example/resources.conf.rnd b/example/resources.conf.rnd index 05fce87..4e5c173 100644 --- a/example/resources.conf.rnd +++ b/example/resources.conf.rnd @@ -30,12 +30,13 @@ bts: - label: NanoBTS-ONW-1900 type: nanobts ipa_unit_id: 9 - addr: 10.42.42.120 band: GSM-1900 - power_supply: - type: 'sispm' - device: '01:01:55:2e:b6' - port: '1' + trx_list: + - addr: 10.42.42.120 + power_supply: + type: 'sispm' + device: '01:01:55:2e:b6' + port: '1' arfcn: - arfcn: 512 diff --git a/src/osmo_gsm_tester/bts_nanobts.py b/src/osmo_gsm_tester/bts_nanobts.py index 29a8ac5..7f0151f 100644 --- a/src/osmo_gsm_tester/bts_nanobts.py +++ b/src/osmo_gsm_tester/bts_nanobts.py @@ -28,28 +28,37 @@ from .event_loop import MainLoop class NanoBts(bts.Bts): - pwsup = None + pwsup_list = [] _pcu = None ############## # PROTECTED ############## def __init__(self, suite_run, conf): - if conf.get('addr') is None: - raise log.Error('No attribute addr provided in conf!') - super().__init__(suite_run, conf, 'nanobts_%s' % conf.get('addr'), 'nanobts') + super().__init__(suite_run, conf, 'nanobts_%s' % conf.get('label', 'nolabel'), 'nanobts') def _configure(self): if self.bsc is None: raise log.Error('BTS needs to be added to a BSC or NITB before it can be configured') - pwsup_opt = self.conf.get('power_supply', {}) - if not pwsup_opt: - raise log.Error('No power_supply attribute provided in conf!') - pwsup_type = pwsup_opt.get('type') - if not pwsup_type: - raise log.Error('No type attribute provided in power_supply conf!') - - self.pwsup = powersupply.get_instance_by_type(pwsup_type, pwsup_opt) + for trx_i in range(self.num_trx()): + pwsup_opt = self.conf.get('trx_list')[trx_i].get('power_supply', {}) + if not pwsup_opt: + raise log.Error('No power_supply attribute provided in conf for TRX %d!' % trx_i) + pwsup_type = pwsup_opt.get('type') + if not pwsup_type: + raise log.Error('No type attribute provided in power_supply conf for TRX %d!' % trx_i) + self.pwsup_list.append(powersupply.get_instance_by_type(pwsup_type, pwsup_opt)) + + + def get_pcap_filter_all_trx_ip(self): + ret = "(" + for trx_i in range(self.num_trx()): + if trx_i != 0: + ret = ret + " or " + bts_trx_ip = self.conf.get('trx_list')[trx_i].get('addr') + ret = ret + "host " + bts_trx_ip + ret = ret + ")" + return ret ######################## # PUBLIC - INTERNAL API @@ -61,9 +70,11 @@ class NanoBts(bts.Bts): band = values.get('band') trx_list = values.get('trx_list') if band == 'GSM-1900': - config.overlay(trx_list[0], { 'arfcn' : '531' }) + for trx_i in range(len(trx_list)): + config.overlay(trx_list[trx_i], { 'arfcn' : str(531 + trx_i * 2) }) elif band == 'GSM-900': - config.overlay(trx_list[0], { 'arfcn' : '50' }) + for trx_i in range(len(trx_list)): + config.overlay(trx_list[trx_i], { 'arfcn' : str(50 + trx_i * 2) }) config.overlay(values, { 'osmobsc_bts_type': 'nanobts' }) @@ -72,9 +83,10 @@ class NanoBts(bts.Bts): def cleanup(self): - if self.pwsup: - self.dbg('Powering off NanoBTS') - self.pwsup.power_set(False) + for pwsup in self.pwsup_list: + self.dbg('Powering off NanoBTS TRX') + pwsup.power_set(False) + self.pwsup_list = [] ################### # PUBLIC (test API included) @@ -87,44 +99,50 @@ class NanoBts(bts.Bts): self._configure() unitid = int(self.conf.get('ipa_unit_id')) - bts_ip = self.remote_addr() - # This fine for now, however concurrent tests using Nanobts may run into "address already in use" since dst is broadcast. - # Once concurrency is needed, a new config attr should be added to have an extra static IP assigned on the main-unit to each Nanobts resource. - local_bind_ip =util.dst_ip_get_local_bind(bts_ip) - # Make sure nanoBTS is powered and in a clean state: - self.pwsup.power_cycle(1.0) + # Make sure all nanoBTS TRX are powered and in a clean state: + for pwsup in self.pwsup_list: + self.dbg('Powering cycling NanoBTS TRX') + pwsup.power_cycle(1.0) pcap_recorder.PcapRecorder(self.suite_run, self.run_dir.new_dir('pcap'), None, - 'host %s and port not 22' % self.remote_addr()) - - self.log('Finding nanobts %s, binding on %s...' % (bts_ip, local_bind_ip)) - ipfind = AbisIpFind(self.suite_run, self.run_dir, local_bind_ip, 'preconf') - ipfind.start() - ipfind.wait_bts_ready(bts_ip) - running_unitid = ipfind.get_unitid_by_ip(bts_ip) - self.log('Found nanobts %s with unit_id %d' % (bts_ip, running_unitid)) - ipfind.stop() - - ipconfig = IpAccessConfig(self.suite_run, self.run_dir, bts_ip) - if running_unitid != unitid: - if not ipconfig.set_unit_id(unitid, False): - raise log.Error('Failed configuring unit id %d' % unitid) - # Apply OML IP and restart nanoBTS as it is required to apply the changes. - if not ipconfig.set_oml_ip(self.bsc.addr(), True): - raise log.Error('Failed configuring OML IP %s' % bts_ip) - - # Let some time for BTS to restart. It takes much more than 20 secs, and - # this way we make sure we don't catch responses in abisip-find prior to - # BTS restarting. - MainLoop.sleep(self, 20) - - self.log('Starting to connect to', self.bsc) - ipfind = AbisIpFind(self.suite_run, self.run_dir, local_bind_ip, 'postconf') - ipfind.start() - ipfind.wait_bts_ready(bts_ip) - self.log('nanoBTS configured and running') - ipfind.stop() + '%s and port not 22' % self.get_pcap_filter_all_trx_ip()) + + + # TODO: If setting N TRX, we should set up them in parallel instead of waiting for each one. + for trx_i in range(self.num_trx()): + bts_trx_ip = self.conf.get('trx_list')[trx_i].get('addr') + # This fine for now, however concurrent tests using Nanobts may run into "address already in use" since dst is broadcast. + # Once concurrency is needed, a new config attr should be added to have an extra static IP assigned on the main-unit to each Nanobts resource. + local_bind_ip = util.dst_ip_get_local_bind(bts_trx_ip) + + self.log('Finding nanobts %s, binding on %s...' % (bts_trx_ip, local_bind_ip)) + ipfind = AbisIpFind(self.suite_run, self.run_dir, local_bind_ip, 'preconf') + ipfind.start() + ipfind.wait_bts_ready(bts_trx_ip) + running_unitid, running_trx = ipfind.get_unitid_by_ip(bts_trx_ip) + self.log('Found nanobts %s with unit_id %d trx %d' % (bts_trx_ip, running_unitid, running_trx)) + ipfind.stop() + + ipconfig = IpAccessConfig(self.suite_run, self.run_dir, bts_trx_ip) + if running_unitid != unitid or running_trx != trx_i: + if not ipconfig.set_unit_id(unitid, trx_i, False): + raise log.Error('Failed configuring unit id %d trx %d' % (unitid, trx_i)) + # Apply OML IP and restart nanoBTS as it is required to apply the changes. + if not ipconfig.set_oml_ip(self.bsc.addr(), True): + raise log.Error('Failed configuring OML IP %s' % bts_trx_ip) + + # Let some time for BTS to restart. It takes much more than 20 secs, and + # this way we make sure we don't catch responses in abisip-find prior to + # BTS restarting. + MainLoop.sleep(self, 20) + + self.log('Starting to connect id %d trx %d to' % (unitid, trx_i), self.bsc) + ipfind = AbisIpFind(self.suite_run, self.run_dir, local_bind_ip, 'postconf') + ipfind.start() + ipfind.wait_bts_ready(bts_trx_ip) + self.log('nanoBTS id %d trx %d configured and running' % (unitid, trx_i)) + ipfind.stop() MainLoop.wait(self, self.bsc.bts_is_connected, self, timeout=600) self.log('nanoBTS connected to BSC') @@ -161,7 +179,7 @@ class AbisIpFind(log.Origin): proc = None BIN_ABISIP_FIND = 'abisip-find' - BTS_UNIT_ID_RE = re.compile("Unit_ID='(?P<unit_id>\d+)/\d+/\d+'") + BTS_UNIT_ID_RE = re.compile("Unit_ID='(?P<unit_id>\d+)/\d+/(?P<trx_id>\d+)'") def __init__(self, suite_run, parent_run_dir, bind_ip, name_suffix): super().__init__(log.C_RUN, AbisIpFind.BIN_ABISIP_FIND + '-' + name_suffix) @@ -207,7 +225,8 @@ class AbisIpFind(log.Origin): res = AbisIpFind.BTS_UNIT_ID_RE.search(line) if res: unit_id = int(res.group('unit_id')) - return unit_id + trx_id = int(res.group('trx_id')) + return (unit_id, trx_id) raise log.Error('abisip-find unit_id field for nanobts %s not found in %s' %(ipaddr, line)) def bts_ready(self, ipaddr): @@ -261,13 +280,14 @@ class IpAccessConfig(log.Origin): raise e return self.proc.result - def set_unit_id(self, unitid, restart=False): + def set_unit_id(self, unitid, trx_num, restart=False): + uid_str = '%d/0/%d' % (unitid, trx_num) if restart: - retcode = self.run('unitid', '--restart', '--unit-id', '%d/0/0' % unitid, self.bts_ip) + retcode = self.run('unitid', '--restart', '--unit-id', '%s' % uid_str, self.bts_ip) else: - retcode = self.run('unitid', '--unit-id', '%d/0/0' % unitid, self.bts_ip) + retcode = self.run('unitid', '--unit-id', '%s' % uid_str, self.bts_ip) if retcode != 0: - log.err('ipaccess-config --unit-id %d/0/0 returned error code %d' % (unitid, retcode)) + log.err('ipaccess-config --unit-id %s returned error code %d' % (uid_str, retcode)) return retcode == 0 def set_oml_ip(self, omlip, restart=False): diff --git a/src/osmo_gsm_tester/resource.py b/src/osmo_gsm_tester/resource.py index 28c4117..dca8090 100644 --- a/src/osmo_gsm_tester/resource.py +++ b/src/osmo_gsm_tester/resource.py @@ -57,17 +57,18 @@ RESOURCES_SCHEMA = { 'bts[].trx_remote_ip': schema.IPV4, 'bts[].launch_trx': schema.BOOL_STR, 'bts[].direct_pcu': schema.BOOL_STR, - 'bts[].power_supply.type': schema.STR, - 'bts[].power_supply.device': schema.STR, - 'bts[].power_supply.port': schema.STR, 'bts[].ciphers[]': schema.CIPHER, 'bts[].num_trx': schema.UINT, 'bts[].max_trx': schema.UINT, + 'bts[].trx_list[].addr': schema.IPV4, 'bts[].trx_list[].hw_addr': schema.HWADDR, 'bts[].trx_list[].net_device': schema.STR, 'bts[].trx_list[].nominal_power': schema.UINT, 'bts[].trx_list[].max_power_red': schema.UINT, 'bts[].trx_list[].timeslot_list[].phys_chan_config': schema.PHY_CHAN, + 'bts[].trx_list[].power_supply.type': schema.STR, + 'bts[].trx_list[].power_supply.device': schema.STR, + 'bts[].trx_list[].power_supply.port': schema.STR, 'arfcn[].arfcn': schema.INT, 'arfcn[].band': schema.BAND, 'modem[].label': schema.STR, |