From 1a7a3f0e4318bccbd3ed177d5b07fa3618d06868 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Sat, 10 Jun 2017 01:18:27 +0200 Subject: fix and refactor logging: drop 'with', simplify With the recent fix of the junit report related issues, another issue arose: the 'with log.Origin' was changed to disallow __enter__ing an object twice to fix problems, now still code would fail because it tries to do 'with' on the same object twice. The only reason is to ensure that logging is associated with a given object. Instead of complicating even more, implement differently. Refactor logging to simplify use: drop the 'with Origin' style completely, and instead use the python stack to determine which objects are created by which, and which object to associate a log statement with. The new way: we rely on the convention that each class instance has a local 'self' referencing the object instance. If we need to find an origin as a new object's parent, or to associate a log message with, we traverse each stack frame, fetching the first local 'self' object that is a log.Origin class instance. How to use: Simply call log.log() anywhere, and it finds an Origin object to log for, from the stack. Alternatively call self.log() for any Origin() object to skip the lookup. Create classes as child class of log.Origin and make sure to call super().__init__(category, name). This constructor will magically find a parent Origin on the stack. When an exception happens, we first escalate the exception up through call scopes to where ever it is handled by log.log_exn(). This then finds an Origin object in the traceback's stack frames, no need to nest in 'with' scopes. Hence the 'with log.Origin' now "happens implicitly", we can write pure natural python code, no more hassles with scope ordering. Furthermore, any frame can place additional logging information in a frame by calling log.ctx(). This is automatically inserted in the ancestry associated with a log statement / exception. Change-Id: I5f9b53150f2bb6fa9d63ce27f0806f0ca6a45e90 --- src/osmo_gsm_tester/bts_sysmo.py | 84 ++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 42 deletions(-) (limited to 'src/osmo_gsm_tester/bts_sysmo.py') diff --git a/src/osmo_gsm_tester/bts_sysmo.py b/src/osmo_gsm_tester/bts_sysmo.py index 5f2b3cb..30fff0e 100644 --- a/src/osmo_gsm_tester/bts_sysmo.py +++ b/src/osmo_gsm_tester/bts_sysmo.py @@ -35,52 +35,50 @@ class SysmoBts(log.Origin): BTS_SYSMO_CFG = 'osmo-bts-sysmo.cfg' def __init__(self, suite_run, conf): + super().__init__(log.C_RUN, self.BTS_SYSMO_BIN) self.suite_run = suite_run self.conf = conf - self.set_name('osmo-bts-sysmo') - self.set_log_category(log.C_RUN) self.remote_env = {} self.remote_user = 'root' def start(self): - with self: - if self.bsc is None: - raise RuntimeError('BTS needs to be added to a BSC or NITB before it can be started') - self.log('Starting sysmoBTS to connect to', self.bsc) - self.run_dir = util.Dir(self.suite_run.trial.get_run_dir().new_dir(self.name())) - self.configure() - - self.inst = util.Dir(os.path.abspath(self.suite_run.trial.get_inst(SysmoBts.BTS_SYSMO_BIN))) - lib = self.inst.child('lib') - if not os.path.isdir(lib): - self.raise_exn('No lib/ in', self.inst) - if not self.inst.isfile('bin', SysmoBts.BTS_SYSMO_BIN): - self.raise_exn('No osmo-bts-sysmo binary in', self.inst) - - self.remote_dir = util.Dir(SysmoBts.REMOTE_DIR) - self.remote_inst = util.Dir(self.remote_dir.child(os.path.basename(str(self.inst)))) - - self.run_remote('rm-remote-dir', ('test', '!', '-d', SysmoBts.REMOTE_DIR, '||', 'rm', '-rf', SysmoBts.REMOTE_DIR)) - self.run_remote('mk-remote-dir', ('mkdir', '-p', SysmoBts.REMOTE_DIR)) - self.run_local('scp-inst-to-sysmobts', - ('scp', '-r', str(self.inst), '%s@%s:%s' % (self.remote_user, self.remote_addr(), str(self.remote_inst)))) - - remote_run_dir = self.remote_dir.child(SysmoBts.BTS_SYSMO_BIN) - self.run_remote('mk-remote-run-dir', ('mkdir', '-p', remote_run_dir)) - - remote_config_file = self.remote_dir.child(SysmoBts.BTS_SYSMO_CFG) - self.run_local('scp-cfg-to-sysmobts', - ('scp', '-r', self.config_file, '%s@%s:%s' % (self.remote_user, self.remote_addr(), remote_config_file))) - - self.run_remote('reload-dsp-firmware', ('/bin/sh', '-c', '"cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0 ; cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0"')) - - remote_lib = self.remote_inst.child('lib') - remote_binary = self.remote_inst.child('bin', 'osmo-bts-sysmo') - self.launch_remote('osmo-bts-sysmo', - ('LD_LIBRARY_PATH=%s' % remote_lib, - remote_binary, '-c', remote_config_file, '-r', '1', - '-i', self.bsc.addr()), - remote_cwd=remote_run_dir) + if self.bsc is None: + raise RuntimeError('BTS needs to be added to a BSC or NITB before it can be started') + log.log('Starting sysmoBTS to connect to', self.bsc) + self.run_dir = util.Dir(self.suite_run.trial.get_run_dir().new_dir(self.name())) + self.configure() + + self.inst = util.Dir(os.path.abspath(self.suite_run.trial.get_inst(SysmoBts.BTS_SYSMO_BIN))) + lib = self.inst.child('lib') + if not os.path.isdir(lib): + raise log.Error('No lib/ in', self.inst) + if not self.inst.isfile('bin', SysmoBts.BTS_SYSMO_BIN): + raise log.Error('No osmo-bts-sysmo binary in', self.inst) + + self.remote_dir = util.Dir(SysmoBts.REMOTE_DIR) + self.remote_inst = util.Dir(self.remote_dir.child(os.path.basename(str(self.inst)))) + + self.run_remote('rm-remote-dir', ('test', '!', '-d', SysmoBts.REMOTE_DIR, '||', 'rm', '-rf', SysmoBts.REMOTE_DIR)) + self.run_remote('mk-remote-dir', ('mkdir', '-p', SysmoBts.REMOTE_DIR)) + self.run_local('scp-inst-to-sysmobts', + ('scp', '-r', str(self.inst), '%s@%s:%s' % (self.remote_user, self.remote_addr(), str(self.remote_inst)))) + + remote_run_dir = self.remote_dir.child(SysmoBts.BTS_SYSMO_BIN) + self.run_remote('mk-remote-run-dir', ('mkdir', '-p', remote_run_dir)) + + remote_config_file = self.remote_dir.child(SysmoBts.BTS_SYSMO_CFG) + self.run_local('scp-cfg-to-sysmobts', + ('scp', '-r', self.config_file, '%s@%s:%s' % (self.remote_user, self.remote_addr(), remote_config_file))) + + self.run_remote('reload-dsp-firmware', ('/bin/sh', '-c', '"cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0 ; cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0"')) + + remote_lib = self.remote_inst.child('lib') + remote_binary = self.remote_inst.child('bin', 'osmo-bts-sysmo') + self.launch_remote('osmo-bts-sysmo', + ('LD_LIBRARY_PATH=%s' % remote_lib, + remote_binary, '-c', remote_config_file, '-r', '1', + '-i', self.bsc.addr()), + remote_cwd=remote_run_dir) def _process_remote(self, name, popen_args, remote_cwd=None): run_dir = self.run_dir.new_dir(name) @@ -92,7 +90,8 @@ class SysmoBts(log.Origin): proc.launch() proc.wait() if proc.result != 0: - proc.raise_exn('Exited in error') + log.ctx(proc) + raise log.Error('Exited in error') def launch_remote(self, name, popen_args, remote_cwd=None): proc = self._process_remote(name, popen_args, remote_cwd) @@ -105,7 +104,8 @@ class SysmoBts(log.Origin): proc.launch() proc.wait() if proc.result != 0: - proc.raise_exn('Exited in error') + log.ctx(proc) + raise log.Error('Exited in error') def remote_addr(self): return self.conf.get('addr') -- cgit v1.2.3