From 44af3415a5b1d1e8348b81d983578f3cd8ac05f9 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 13 Apr 2017 03:11:59 +0200 Subject: 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 --- src/osmo-gsm-tester.py | 52 +++++++++++++--------- src/osmo_gsm_tester/bts_octphy.py | 4 +- src/osmo_gsm_tester/bts_osmotrx.py | 2 - src/osmo_gsm_tester/bts_sysmo.py | 1 - src/osmo_gsm_tester/config.py | 10 ++++- src/osmo_gsm_tester/log.py | 12 +++++ src/osmo_gsm_tester/resource.py | 10 +++-- src/osmo_gsm_tester/suite.py | 29 +++++++----- .../templates/osmo-bts-octphy.cfg.tmpl | 14 +++--- src/osmo_gsm_tester/templates/osmo-nitb.cfg.tmpl | 2 +- src/osmo_gsm_tester/util.py | 13 +----- 11 files changed, 89 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/osmo-gsm-tester.py b/src/osmo-gsm-tester.py index 0137f25..17b16b7 100755 --- a/src/osmo-gsm-tester.py +++ b/src/osmo-gsm-tester.py @@ -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 diff --git a/src/osmo_gsm_tester/bts_octphy.py b/src/osmo_gsm_tester/bts_octphy.py index 4396108..1f36a79 100644 --- a/src/osmo_gsm_tester/bts_octphy.py +++ b/src/osmo_gsm_tester/bts_octphy.py @@ -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 diff --git a/src/osmo_gsm_tester/bts_osmotrx.py b/src/osmo_gsm_tester/bts_osmotrx.py index 417fbf2..71cdd48 100644 --- a/src/osmo_gsm_tester/bts_osmotrx.py +++ b/src/osmo_gsm_tester/bts_osmotrx.py @@ -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 diff --git a/src/osmo_gsm_tester/bts_sysmo.py b/src/osmo_gsm_tester/bts_sysmo.py index 64fa7f4..dd396ff 100644 --- a/src/osmo_gsm_tester/bts_sysmo.py +++ b/src/osmo_gsm_tester/bts_sysmo.py @@ -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 diff --git a/src/osmo_gsm_tester/config.py b/src/osmo_gsm_tester/config.py index cbbfa6f..68bbd13 100644 --- a/src/osmo_gsm_tester/config.py +++ b/src/osmo_gsm_tester/config.py @@ -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): diff --git a/src/osmo_gsm_tester/log.py b/src/osmo_gsm_tester/log.py index f56d2c9..3e96999 100644 --- a/src/osmo_gsm_tester/log.py +++ b/src/osmo_gsm_tester/log.py @@ -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) diff --git a/src/osmo_gsm_tester/resource.py b/src/osmo_gsm_tester/resource.py index 5cfbeaf..b842d98 100644 --- a/src/osmo_gsm_tester/resource.py +++ b/src/osmo_gsm_tester/resource.py @@ -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): diff --git a/src/osmo_gsm_tester/suite.py b/src/osmo_gsm_tester/suite.py index 08965b5..74c8b28 100644 --- a/src/osmo_gsm_tester/suite.py +++ b/src/osmo_gsm_tester/suite.py @@ -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') diff --git a/src/osmo_gsm_tester/templates/osmo-bts-octphy.cfg.tmpl b/src/osmo_gsm_tester/templates/osmo-bts-octphy.cfg.tmpl index 90d6092..bf6adf9 100644 --- a/src/osmo_gsm_tester/templates/osmo-bts-octphy.cfg.tmpl +++ b/src/osmo_gsm_tester/templates/osmo-bts-octphy.cfg.tmpl @@ -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 diff --git a/src/osmo_gsm_tester/templates/osmo-nitb.cfg.tmpl b/src/osmo_gsm_tester/templates/osmo-nitb.cfg.tmpl index e7dc119..28cf61c 100644 --- a/src/osmo_gsm_tester/templates/osmo-nitb.cfg.tmpl +++ b/src/osmo_gsm_tester/templates/osmo-nitb.cfg.tmpl @@ -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} diff --git a/src/osmo_gsm_tester/util.py b/src/osmo_gsm_tester/util.py index 61d0f6e..e132e21 100644 --- a/src/osmo_gsm_tester/util.py +++ b/src/osmo_gsm_tester/util.py @@ -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 -- cgit v1.2.3