Move object subclass instance allocation logic out of suite.py/resource.py

This way we get rid of object related content in resource.py and we can
finally move it to core/ in next commit.

Change-Id: Ia5b861115ae3ae1b90149863c4265dcc730b8cd4
This commit is contained in:
Pau Espin 2020-05-04 17:16:39 +02:00
parent ea8c3d4b12
commit 1ee5ec5db2
6 changed files with 120 additions and 90 deletions

View File

@ -162,6 +162,34 @@ class Bts(log.Origin, metaclass=ABCMeta):
'Nothing to do by default. Subclass can override if required.'
pass
def get_instance_by_type(suite_run, conf):
"""Allocate a BTS child class based on type. Opts are passed to the newly created object."""
bts_type = conf.get('type')
if bts_type is None:
raise RuntimeError('BTS type is not defined!')
if bts_type == 'osmo-bts-sysmo':
from .bts_sysmo import SysmoBts
bts_class = SysmoBts
elif bts_type == 'osmo-bts-trx':
from .bts_osmotrx import OsmoBtsTrx
bts_class = OsmoBtsTrx
elif bts_type == 'osmo-bts-oc2g':
from .bts_oc2g import OsmoBtsOC2G
bts_class = OsmoBtsOC2G
elif bts_type == 'osmo-bts-octphy':
from .bts_octphy import OsmoBtsOctphy
bts_class = OsmoBtsOctphy
elif bts_type == 'osmo-bts-virtual':
from .bts_osmovirtual import OsmoBtsVirtual
bts_class = OsmoBtsVirtual
elif bts_type == 'nanobts':
from .bts_nanobts import NanoBts
bts_class = NanoBts
else:
raise log.Error('BTS type not supported:', bts_type)
return bts_class(suite_run, conf)
###################
# PUBLIC (test API included)
###################

View File

@ -192,6 +192,22 @@ class eNodeB(log.Origin, metaclass=ABCMeta):
return rf_dev_args
def get_instance_by_type(suite_run, conf):
"""Allocate a ENB child class based on type. Opts are passed to the newly created object."""
enb_type = conf.get('type')
if enb_type is None:
raise RuntimeError('ENB type is not defined!')
if enb_type == 'amarisoftenb':
from .enb_amarisoft import AmarisoftENB
enb_class = AmarisoftENB
elif enb_type == 'srsenb':
from .enb_srs import srsENB
enb_class = srsENB
else:
raise log.Error('ENB type not supported:', enb_type)
return enb_class(suite_run, conf)
###################
# PUBLIC (test API included)
###################

View File

@ -57,6 +57,25 @@ class EPC(log.Origin, metaclass=ABCMeta):
'Nothing to do by default. Subclass can override if required.'
pass
def get_instance_by_type(suite_run, run_node):
"""Allocate a EPC child class based on type. Opts are passed to the newly created object."""
values = dict(epc=config.get_defaults('epc'))
config.overlay(values, dict(epc=suite_run.config().get('epc', {})))
epc_type = values['epc'].get('type', None)
if epc_type is None:
raise RuntimeError('EPC type is not defined!')
if epc_type == 'amarisoftepc':
from .epc_amarisoft import AmarisoftEPC
epc_class = AmarisoftEPC
elif epc_type == 'srsepc':
from .epc_srs import srsEPC
epc_class = srsEPC
else:
raise log.Error('EPC type not supported:', epc_type)
return epc_class(suite_run, run_node)
###################
# PUBLIC (test API included)
###################

View File

@ -38,11 +38,48 @@ def on_register_schemas():
class MS(log.Origin, metaclass=ABCMeta):
"""Base for everything about mobile/modem and SIMs."""
##############
# PROTECTED
##############
def __init__(self, name, conf):
super().__init__(log.C_TST, name)
self._conf = conf
self.msisdn = None
########################
# PUBLIC - INTERNAL API
########################
@abstractmethod
def cleanup(self):
"""Cleans up resources allocated."""
pass
def get_instance_by_type(suite_run, conf):
"""Allocate a MS child class based on type. Opts are passed to the newly created object."""
ms_type = conf.get('type')
if ms_type is None:
# Map None to ofono for forward compability
ms_type = 'ofono'
if ms_type == 'ofono':
from .ms_ofono import Modem
ms_class = Modem
elif ms_type == 'osmo-mobile':
from .ms_osmo_mobile import MSOsmoMobile
ms_class = MSOsmoMobile
elif ms_type == 'srsue':
from .ms_srs import srsUE
ms_class = srsUE
elif ms_type == 'amarisoftue':
from .ms_amarisoft import AmarisoftUE
ms_class = AmarisoftUE
else:
raise log.Error('MS type not supported:', ms_type)
return ms_class(suite_run, conf)
###################
# PUBLIC (test API included)
###################
def imsi(self):
return self._conf.get('imsi')
@ -60,8 +97,3 @@ class MS(log.Origin, metaclass=ABCMeta):
def msisdn(self):
return self.msisdn
@abstractmethod
def cleanup(self):
"""Cleans up resources allocated."""
pass

View File

@ -26,10 +26,6 @@ from .core import log
from .core import config
from .core import util
from .core import schema
from .obj import bts_sysmo, bts_osmotrx, bts_osmovirtual, bts_octphy, bts_nanobts, bts_oc2g
from .obj import ms_ofono
from .obj import ms_osmo_mobile
from .obj import ms_srs, ms_amarisoft, enb_srs, enb_amarisoft, epc_srs, epc_amarisoft
from .core.util import is_dict, is_list
@ -47,38 +43,6 @@ R_MODEM = 'modem'
R_OSMOCON = 'osmocon_phone'
R_ENB = 'enb'
KNOWN_BTS_TYPES = {
'osmo-bts-sysmo': bts_sysmo.SysmoBts,
'osmo-bts-trx': bts_osmotrx.OsmoBtsTrx,
'osmo-bts-oc2g': bts_oc2g.OsmoBtsOC2G,
'osmo-bts-octphy': bts_octphy.OsmoBtsOctphy,
'osmo-bts-virtual': bts_osmovirtual.OsmoBtsVirtual,
'nanobts': bts_nanobts.NanoBts,
}
KNOWN_ENB_TYPES = {
'srsenb': enb_srs.srsENB,
'amarisoftenb': enb_amarisoft.AmarisoftENB,
}
KNOWN_EPC_TYPES = {
'srsepc': epc_srs.srsEPC,
'amarisoftepc': epc_amarisoft.AmarisoftEPC,
}
KNOWN_MS_TYPES = {
# Map None to ofono for forward compability
None: ms_ofono.Modem,
'ofono': ms_ofono.Modem,
'osmo-mobile': ms_osmo_mobile.MSOsmoMobile,
'srsue': ms_srs.srsUE,
'amarisoftue': ms_amarisoft.AmarisoftUE,
}
def register_bts_type(name, clazz):
KNOWN_BTS_TYPES[name] = clazz
class ResourcesPool(log.Origin):
_remember_to_free = None
_registered_exit_handler = False

View File

@ -25,6 +25,10 @@ from .core import config, log, util, process, schema
from .core.event_loop import MainLoop
from .obj import nitb_osmo, hlr_osmo, mgcpgw_osmo, mgw_osmo, msc_osmo, bsc_osmo, stp_osmo, ggsn_osmo, sgsn_osmo, esme, osmocon, ms_driver, iperf3
from .obj import run_node
from .obj import epc
from .obj import enb
from .obj import bts
from .obj import ms
from . import resource, test
class Timeout(Exception):
@ -324,24 +328,19 @@ class SuiteRun(log.Origin):
return ms
def bts(self, specifics=None):
bts = bts_obj(self, self.reserved_resources.get(resource.R_BTS, specifics=specifics))
bts.set_lac(self.lac())
bts.set_rac(self.rac())
bts.set_cellid(self.cellid())
bts.set_bvci(self.bvci())
self.register_for_cleanup(bts)
return bts
bts_obj = bts.Bts.get_instance_by_type(self, self.reserved_resources.get(resource.R_BTS, specifics=specifics))
bts_obj.set_lac(self.lac())
bts_obj.set_rac(self.rac())
bts_obj.set_cellid(self.cellid())
bts_obj.set_bvci(self.bvci())
self.register_for_cleanup(bts_obj)
return bts_obj
def modem(self, specifics=None):
conf = self.reserved_resources.get(resource.R_MODEM, specifics=specifics)
ms_type = conf.get('type')
ms_class = resource.KNOWN_MS_TYPES.get(ms_type)
if ms_class is None:
raise RuntimeError('No such Modem type is defined: %r' % ms_type)
self.dbg('create Modem object', conf=conf)
ms = ms_class(self, conf)
self.register_for_cleanup(ms)
return ms
ms_obj = ms.MS.get_instance_by_type(self, conf)
self.register_for_cleanup(ms_obj)
return ms_obj
def modems(self, count):
l = []
@ -367,16 +366,16 @@ class SuiteRun(log.Origin):
return run_node.RunNode.from_conf(self.reserved_resources.get(resource.R_RUN_NODE, specifics=specifics))
def enb(self, specifics=None):
enb = enb_obj(self, self.reserved_resources.get(resource.R_ENB, specifics=specifics))
self.register_for_cleanup(enb)
return enb
enb_obj = enb.eNodeB.get_instance_by_type(self, self.reserved_resources.get(resource.R_ENB, specifics=specifics))
self.register_for_cleanup(enb_obj)
return enb_obj
def epc(self, run_node=None):
if run_node is None:
run_node = self.run_node()
epc = epc_obj(self, run_node)
self.register_for_cleanup(epc)
return epc
epc_obj = epc.EPC.get_instance_by_type(self, run_node)
self.register_for_cleanup(epc_obj)
return epc_obj
def osmocon(self, specifics=None):
conf = self.reserved_resources.get(resource.R_OSMOCON, specifics=specifics)
@ -489,32 +488,4 @@ def load_suite_scenario_str(suite_scenario_str):
scenarios = [config.get_scenario(scenario_name, schema.get_all_schema()) for scenario_name in scenario_names]
return (suite_scenario_str, suite, scenarios)
def bts_obj(suite_run, conf):
bts_type = conf.get('type')
log.dbg('create BTS object', type=bts_type)
bts_class = resource.KNOWN_BTS_TYPES.get(bts_type)
if bts_class is None:
raise RuntimeError('No such BTS type is defined: %r' % bts_type)
return bts_class(suite_run, conf)
def enb_obj(suite_run, conf):
enb_type = conf.get('type')
log.dbg('create ENB object', type=enb_type)
enb_class = resource.KNOWN_ENB_TYPES.get(enb_type)
if enb_class is None:
raise RuntimeError('No such ENB type is defined: %r' % enb_type)
return enb_class(suite_run, conf)
def epc_obj(suite_run, run_node):
values = dict(epc=config.get_defaults('epc'))
config.overlay(values, dict(epc=suite_run.config().get('epc', {})))
epc_type = values['epc'].get('type', None)
if epc_type is None:
raise RuntimeError('EPC type is not defined!')
log.dbg('create EPC object', type=epc_type)
epc_class = resource.KNOWN_EPC_TYPES.get(epc_type)
if epc_class is None:
raise RuntimeError('No such EPC type is defined: %r' % epc_type)
return epc_class(suite_run, run_node)
# vim: expandtab tabstop=4 shiftwidth=4