fix octphy, fix conf, improve logging
Clearly separate the kinds of BTS hardware the GSM tester knows ('type') from the NITB's bts/type config item ('osmobsc_bts_type' -- not 'osmonitb_...' to stay in tune with future developments: it is the libbsc that needs this). For BTS hardware kinds, use the full name of the binary for osmo driven models: osmo-bts-sysmo, osmo-bts-trx, osmo-bts-octphy. Change-Id: I1aa9b48e74013a93f9db1a34730f17717fb3b36c
This commit is contained in:
parent
17c139ef4c
commit
44af3415a5
|
@ -11,6 +11,7 @@ nitb_bts:
|
|||
location_area_code: 23
|
||||
base_station_id_code: 63
|
||||
stream_id: 255
|
||||
osmobsc_bts_type: sysmobts
|
||||
trx_list:
|
||||
- max_power_red: 22
|
||||
arfcn: 868
|
||||
|
|
|
@ -7,22 +7,22 @@ nitb_iface:
|
|||
|
||||
bts:
|
||||
- label: sysmoBTS 1002
|
||||
type: sysmo
|
||||
type: osmo-bts-sysmo
|
||||
ipa_unit_id: 1
|
||||
addr: 10.42.42.114
|
||||
band: GSM-1800
|
||||
|
||||
- label: octBTS 3000
|
||||
type: oct
|
||||
type: osmo-bts-octphy
|
||||
ipa_unit_id: 5
|
||||
addr: 10.42.42.115
|
||||
band: GSM-1800
|
||||
trx:
|
||||
trx_list:
|
||||
- hw_addr: 00:0c:90:32:b5:8a
|
||||
net_device: eth0.2342
|
||||
|
||||
- label: Ettus B210
|
||||
type: osmotrx
|
||||
type: osmo-bts-trx
|
||||
ipa_unit_id: 6
|
||||
addr: 10.42.42.116
|
||||
band: GSM-1800
|
||||
|
@ -32,7 +32,7 @@ bts:
|
|||
ipa_unit_id: 1902
|
||||
addr: 10.42.42.190
|
||||
band: GSM-1900
|
||||
trx:
|
||||
trx_list:
|
||||
- hw_addr: 00:02:95:00:41:b3
|
||||
|
||||
arfcn:
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
resources:
|
||||
bts:
|
||||
- type: octphy
|
||||
- type: osmo-bts-octphy
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
resources:
|
||||
bts:
|
||||
- type: sysmo
|
||||
- type: osmo-bts-sysmo
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
resources:
|
||||
bts:
|
||||
- type: osmotrx
|
||||
- type: osmo-bts-trx
|
||||
|
|
|
@ -143,38 +143,50 @@ if __name__ == '__main__':
|
|||
trials = []
|
||||
for trial_package in args.trial_package:
|
||||
t = trial.Trial(trial_package)
|
||||
t.verify()
|
||||
trials.append(t)
|
||||
try:
|
||||
t.verify()
|
||||
trials.append(t)
|
||||
except:
|
||||
t.log_exn()
|
||||
|
||||
trials_passed = []
|
||||
trials_failed = []
|
||||
|
||||
for current_trial in trials:
|
||||
with current_trial:
|
||||
suites_passed = 0
|
||||
suites_failed = 0
|
||||
for suite_def, scenarios in suite_scenarios:
|
||||
suite_run = suite.SuiteRun(current_trial, suite_def, scenarios)
|
||||
result = suite_run.run_tests(test_names)
|
||||
if result.all_passed:
|
||||
suites_passed += 1
|
||||
suite_run.log('PASS')
|
||||
try:
|
||||
with current_trial:
|
||||
suites_passed = []
|
||||
suites_failed = []
|
||||
for suite_scenario_str, suite_def, scenarios in suite_scenarios:
|
||||
log.large_separator(current_trial.name(), suite_scenario_str)
|
||||
suite_run = suite.SuiteRun(current_trial, suite_scenario_str, suite_def, scenarios)
|
||||
result = suite_run.run_tests(test_names)
|
||||
if result.all_passed:
|
||||
suites_passed.append(suite_scenario_str)
|
||||
suite_run.log('PASS')
|
||||
else:
|
||||
suites_failed.append(suite_scenario_str)
|
||||
suite_run.err('FAIL')
|
||||
if not suites_failed:
|
||||
current_trial.log('PASS')
|
||||
trials_passed.append(current_trial.name())
|
||||
else:
|
||||
suites_failed += 1
|
||||
suite_run.err('FAIL')
|
||||
if not suites_failed:
|
||||
current_trial.log('PASS')
|
||||
trials_passed.append(current_trial.name())
|
||||
else:
|
||||
current_trial.err('FAIL')
|
||||
trials_failed.append(current_trial.name())
|
||||
current_trial.err('FAIL')
|
||||
trials_failed.append((current_trial.name(), suites_passed, suites_failed))
|
||||
except:
|
||||
current_trial.log_exn()
|
||||
|
||||
sys.stderr.flush()
|
||||
sys.stdout.flush()
|
||||
log.large_separator()
|
||||
if trials_passed:
|
||||
print('Trials passed:\n ' + ('\n '.join(trials_passed)))
|
||||
if trials_failed:
|
||||
print('Trials failed:\n ' + ('\n '.join(trials_failed)))
|
||||
print('Trials failed:')
|
||||
for trial_name, suites_passed, suites_failed in trials_failed:
|
||||
print(' %s (%d of %d suite runs failed)' % (trial_name, len(suites_failed), len(suites_failed) + len(suites_passed)))
|
||||
for suite in suites_failed:
|
||||
print(' FAIL:', suite)
|
||||
exit(1)
|
||||
|
||||
# vim: expandtab tabstop=4 shiftwidth=4
|
||||
|
|
|
@ -52,7 +52,7 @@ class OsmoBtsOctphy(log.Origin):
|
|||
raise RuntimeError('No lib/ in %r' % self.inst)
|
||||
self.env = { 'LD_LIBRARY_PATH': lib }
|
||||
|
||||
self.launch_process(OsmoBtsTrx.BIN_BTS_OCTPHY, '-r', '1', '-c', os.path.abspath(self.config_file))
|
||||
self.launch_process(OsmoBtsOctphy.BIN_BTS_OCTPHY, '-r', '1', '-c', os.path.abspath(self.config_file))
|
||||
self.suite_run.poll()
|
||||
|
||||
def launch_process(self, binary_name, *args):
|
||||
|
@ -87,8 +87,6 @@ class OsmoBtsOctphy(log.Origin):
|
|||
values = config.get_defaults('nitb_bts')
|
||||
config.overlay(values, config.get_defaults('osmo_bts_octphy'))
|
||||
config.overlay(values, self.conf)
|
||||
# using type 'sysmobts' for osmo-bts-octphy
|
||||
config.overlay(values, { 'type': 'sysmobts' })
|
||||
self.dbg(conf=values)
|
||||
return values
|
||||
|
||||
|
|
|
@ -92,8 +92,6 @@ class OsmoBtsTrx(log.Origin):
|
|||
values = config.get_defaults('nitb_bts')
|
||||
config.overlay(values, config.get_defaults('osmo_bts_trx'))
|
||||
config.overlay(values, self.conf)
|
||||
# using type 'sysmobts' for osmo-bts-trx
|
||||
config.overlay(values, { 'type': 'sysmobts' })
|
||||
self.dbg(conf=values)
|
||||
return values
|
||||
|
||||
|
|
|
@ -127,7 +127,6 @@ class SysmoBts(log.Origin):
|
|||
values = config.get_defaults('nitb_bts')
|
||||
config.overlay(values, config.get_defaults('osmo_bts_sysmo'))
|
||||
config.overlay(values, self.conf)
|
||||
config.overlay(values, { 'type': 'sysmobts' })
|
||||
self.dbg(conf=values)
|
||||
return values
|
||||
|
||||
|
|
|
@ -177,6 +177,12 @@ def get_defaults(for_kind):
|
|||
defaults = read_config_file('default.conf', if_missing_return={})
|
||||
return defaults.get(for_kind, {})
|
||||
|
||||
class Scenario(log.Origin, dict):
|
||||
def __init__(self, name, path):
|
||||
self.set_name(name)
|
||||
self.set_log_category(log.C_TST)
|
||||
self.path = path
|
||||
|
||||
def get_scenario(name, validation_schema=None):
|
||||
scenarios_dir = get_scenarios_dir()
|
||||
if not name.endswith('.conf'):
|
||||
|
@ -184,7 +190,9 @@ def get_scenario(name, validation_schema=None):
|
|||
path = scenarios_dir.child(name)
|
||||
if not os.path.isfile(path):
|
||||
raise RuntimeError('No such scenario file: %r' % path)
|
||||
return read(path, validation_schema=validation_schema)
|
||||
sc = Scenario(name, path)
|
||||
sc.update(read(path, validation_schema=validation_schema))
|
||||
return sc
|
||||
|
||||
def add(dest, src):
|
||||
if is_dict(dest):
|
||||
|
|
|
@ -186,6 +186,14 @@ class LogTarget:
|
|||
log_str = log_str + '\n'
|
||||
self.log_sink(log_str)
|
||||
|
||||
def large_separator(self, *msgs):
|
||||
msg = ' '.join(msgs)
|
||||
if not msg:
|
||||
msg = '------------------------------------------'
|
||||
self.log_sink('------------------------------------------\n'
|
||||
'%s\n'
|
||||
'------------------------------------------\n' % msg)
|
||||
|
||||
targets = [ LogTarget() ]
|
||||
|
||||
def level_str(level):
|
||||
|
@ -207,6 +215,10 @@ def _log_all_targets(origin, category, level, src, messages, named_items=None):
|
|||
for target in targets:
|
||||
target.log(origin, category, level, src, messages, named_items)
|
||||
|
||||
def large_separator(*msgs):
|
||||
for target in targets:
|
||||
target.large_separator(*msgs)
|
||||
|
||||
def get_src_from_caller(levels_up=1):
|
||||
caller = getframeinfo(stack()[levels_up][0])
|
||||
return '%s:%d' % (os.path.basename(caller.filename), caller.lineno)
|
||||
|
|
|
@ -29,7 +29,7 @@ from . import util
|
|||
from . import schema
|
||||
from . import ofono_client
|
||||
from . import osmo_nitb
|
||||
from . import bts_sysmo, bts_osmotrx
|
||||
from . import bts_sysmo, bts_osmotrx, bts_octphy
|
||||
|
||||
from .util import is_dict, is_list
|
||||
|
||||
|
@ -54,7 +54,8 @@ RESOURCES_SCHEMA = {
|
|||
'bts[].ipa_unit_id': schema.INT,
|
||||
'bts[].addr': schema.IPV4,
|
||||
'bts[].band': schema.BAND,
|
||||
'bts[].trx[].hw_addr': schema.HWADDR,
|
||||
'bts[].trx_list[].hw_addr': schema.HWADDR,
|
||||
'bts[].trx_list[].net_device': schema.STR,
|
||||
'arfcn[].arfcn': schema.INT,
|
||||
'arfcn[].band': schema.BAND,
|
||||
'modem[].label': schema.STR,
|
||||
|
@ -68,8 +69,9 @@ WANT_SCHEMA = util.dict_add(
|
|||
RESOURCES_SCHEMA)
|
||||
|
||||
KNOWN_BTS_TYPES = {
|
||||
'sysmo': bts_sysmo.SysmoBts,
|
||||
'osmotrx': bts_osmotrx.OsmoBtsTrx,
|
||||
'osmo-bts-sysmo': bts_sysmo.SysmoBts,
|
||||
'osmo-bts-trx': bts_osmotrx.OsmoBtsTrx,
|
||||
'osmo-bts-octphy': bts_octphy.OsmoBtsOctphy,
|
||||
}
|
||||
|
||||
def register_bts_type(name, clazz):
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import os
|
||||
import sys
|
||||
import time
|
||||
import copy
|
||||
from . import config, log, template, util, resource, schema, ofono_client, osmo_nitb
|
||||
from . import test
|
||||
|
||||
|
@ -56,7 +57,6 @@ class SuiteDefinition(log.Origin):
|
|||
SuiteDefinition.CONF_SCHEMA)
|
||||
self.load_tests()
|
||||
|
||||
|
||||
def load_tests(self):
|
||||
with self:
|
||||
self.tests = []
|
||||
|
@ -122,22 +122,27 @@ class SuiteRun(log.Origin):
|
|||
_config = None
|
||||
_processes = None
|
||||
|
||||
def __init__(self, current_trial, suite_definition, scenarios=[]):
|
||||
def __init__(self, current_trial, suite_scenario_str, suite_definition, scenarios=[]):
|
||||
self.trial = current_trial
|
||||
self.definition = suite_definition
|
||||
self.scenarios = scenarios
|
||||
self.set_name(suite_definition.name())
|
||||
self.set_name(suite_scenario_str)
|
||||
self.set_log_category(log.C_TST)
|
||||
self.resources_pool = resource.ResourcesPool()
|
||||
|
||||
def combined(self, conf_name):
|
||||
combination = self.definition.conf.get(conf_name) or {}
|
||||
for scenario in self.scenarios:
|
||||
c = scenario.get(conf_name)
|
||||
if c is None:
|
||||
continue
|
||||
config.combine(combination, c)
|
||||
return combination
|
||||
self.dbg(combining=conf_name)
|
||||
with log.Origin(combining_scenarios=conf_name):
|
||||
combination = copy.deepcopy(self.definition.conf.get(conf_name) or {})
|
||||
self.dbg(definition_conf=combination)
|
||||
for scenario in self.scenarios:
|
||||
with scenario:
|
||||
c = scenario.get(conf_name)
|
||||
self.dbg(scenario=scenario.name(), conf=c)
|
||||
if c is None:
|
||||
continue
|
||||
config.combine(combination, c)
|
||||
return combination
|
||||
|
||||
def resource_requirements(self):
|
||||
if self._resource_requirements is None:
|
||||
|
@ -183,6 +188,7 @@ class SuiteRun(log.Origin):
|
|||
self.reserved_resources = self.resources_pool.reserve(self, self.resource_requirements())
|
||||
|
||||
def run_tests(self, names=None):
|
||||
self.log('Suite run start')
|
||||
if not self.reserved_resources:
|
||||
self.reserve_resources()
|
||||
results = SuiteRun.Results()
|
||||
|
@ -281,7 +287,6 @@ class SuiteRun(log.Origin):
|
|||
self.log('prompt entered:', entered)
|
||||
return entered
|
||||
|
||||
|
||||
loaded_suite_definitions = {}
|
||||
|
||||
def load(suite_name):
|
||||
|
@ -319,7 +324,7 @@ def load_suite_scenario_str(suite_scenario_str):
|
|||
suite_name, scenario_names = parse_suite_scenario_str(suite_scenario_str)
|
||||
suite = load(suite_name)
|
||||
scenarios = [config.get_scenario(scenario_name) for scenario_name in scenario_names]
|
||||
return (suite, scenarios)
|
||||
return (suite_scenario_str, suite, scenarios)
|
||||
|
||||
def bts_obj(suite_run, conf):
|
||||
bts_type = conf.get('type')
|
||||
|
|
|
@ -20,13 +20,17 @@ log stderr
|
|||
line vty
|
||||
no login
|
||||
!
|
||||
phy 0
|
||||
octphy hw-addr ${osmo_bts_octphy.hw_addr}
|
||||
octphy net-device ${osmo_bts_octphy.net_device}
|
||||
%for trx in osmo_bts_octphy.trx_list:
|
||||
phy ${loop.index}
|
||||
octphy hw-addr ${trx.hw_addr}
|
||||
octphy net-device ${trx.net_device}
|
||||
instance 0
|
||||
%endfor
|
||||
bts 0
|
||||
band ${osmo_bts_octphy.band}
|
||||
ipa unit-id ${osmo_bts_octphy.ipa_unit_id} 0
|
||||
oml remote-ip ${osmo_bts_octphy.oml_remote_ip}
|
||||
trx 0
|
||||
phy 0 instance 0
|
||||
%for trx in osmo_bts_octphy.trx_list:
|
||||
trx ${loop.index}
|
||||
phy ${loop.index} instance 0
|
||||
%endfor
|
||||
|
|
|
@ -46,7 +46,7 @@ network
|
|||
timer t3141 0
|
||||
%for bts in nitb.net.bts_list:
|
||||
bts ${loop.index}
|
||||
type ${bts.type}
|
||||
type ${bts.osmobsc_bts_type}
|
||||
band ${bts.band}
|
||||
cell_identity 0
|
||||
location_area_code ${bts.location_area_code}
|
||||
|
|
|
@ -74,6 +74,7 @@ class DictProxy:
|
|||
return dict2obj(self.obj[key])
|
||||
|
||||
def __getattr__(self, key):
|
||||
'provide error information to know which template item was missing'
|
||||
try:
|
||||
return dict2obj(getattr(self.obj, key))
|
||||
except AttributeError:
|
||||
|
@ -82,19 +83,9 @@ class DictProxy:
|
|||
except KeyError:
|
||||
raise AttributeError(key)
|
||||
|
||||
class ListProxy:
|
||||
'allow nesting for DictProxy'
|
||||
def __init__(self, obj):
|
||||
self.obj = obj
|
||||
|
||||
def __getitem__(self, key):
|
||||
return dict2obj(self.obj[key])
|
||||
|
||||
def dict2obj(value):
|
||||
if isinstance(value, dict):
|
||||
if is_list(value) or is_dict(value):
|
||||
return DictProxy(value)
|
||||
if isinstance(value, (tuple, list)):
|
||||
return ListProxy(value)
|
||||
return value
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue