diff --git a/easybuild/framework/easyblock.py b/easybuild/framework/easyblock.py index df1866b6db..80db82bb06 100644 --- a/easybuild/framework/easyblock.py +++ b/easybuild/framework/easyblock.py @@ -40,6 +40,7 @@ * Maxime Boissonneault (Compute Canada) * Davide Vanzo (Vanderbilt University) * Caspar van Leeuwen (SURF) +* Jan Andre Reuter (Juelich Supercomputing Centre) """ import copy @@ -141,10 +142,11 @@ def extra_options(extra=None): # # INIT # - def __init__(self, ec): + def __init__(self, ec, logfile=None): """ Initialize the EasyBlock instance. :param ec: a parsed easyconfig file (EasyConfig instance) + :param logfile: pass logfile from other EasyBlock. If not passed, create logfile (optional) """ # keep track of original working directory, so we can go back there @@ -214,7 +216,8 @@ def __init__(self, ec): # logging self.log = None - self.logfile = None + self.logfile = logfile + self.external_logfile = logfile is not None self.logdebug = build_option('debug') self.postmsg = '' # allow a post message to be set, which can be shown as last output self.current_step = None @@ -303,11 +306,11 @@ def _init_log(self): if self.log is not None: return - self.logfile = get_log_filename(self.name, self.version, add_salt=True) - fancylogger.logToFile(self.logfile, max_bytes=0) + if self.logfile is None: + self.logfile = get_log_filename(self.name, self.version, add_salt=True) + fancylogger.logToFile(self.logfile, max_bytes=0) self.log = fancylogger.getLogger(name=self.__class__.__name__, fname=False) - self.log.info(this_is_easybuild()) this_module = inspect.getmodule(self) @@ -323,6 +326,9 @@ def close_log(self): """ Shutdown the logger. """ + # only close log if we created a logfile + if self.external_logfile: + return self.log.info("Closing log for application name %s version %s" % (self.name, self.version)) fancylogger.logToFile(self.logfile, enable=False) diff --git a/test/framework/easyblock.py b/test/framework/easyblock.py index 19218eca6a..25207ea2f6 100644 --- a/test/framework/easyblock.py +++ b/test/framework/easyblock.py @@ -28,6 +28,7 @@ @author: Jens Timmerman (Ghent University) @author: Kenneth Hoste (Ghent University) @author: Maxime Boissonneault (Compute Canada) +@author: Jan Andre Reuter (Juelich Supercomputing Centre) """ import os import re @@ -2895,6 +2896,47 @@ def run_sanity_check_step(sanity_check_paths, enhance_sanity_check): run_sanity_check_step({}, False) run_sanity_check_step({}, True) + def test_create_easyblock_without_logfile(self): + """ + Test creating an EasyBlock without a logfile. + This represents scenarios found in Bundle and QuantumESPRESSO, where an EasyBlock is + created within another EasyBlock. + """ + self.contents = '\n'.join([ + 'easyblock = "ConfigureMake"', + 'name = "pi"', + 'version = "3.14"', + 'homepage = "http://example.com"', + 'description = "test easyconfig"', + 'toolchain = SYSTEM', + ]) + self.writeEC() + # Ensure that the default case works as expected + eb = EasyBlock(EasyConfig(self.eb_file)) + self.assertNotEqual(eb.log, None) + self.assertNotEqual(eb.logfile, None) + # Get reference to the actual log instance and ensure that it works + # This is NOT eb.log, which represents a separate logger with a separate name. + file_log = fancylogger.getLogger(name=None) + self.assertNotEqual(getattr(file_log, 'logtofile_%s' % eb.logfile), False) + + # Now, create another EasyBlock by passing logfile from first EasyBlock. + eb_external_logfile = EasyBlock(EasyConfig(self.eb_file), logfile=eb.logfile) + self.assertNotEqual(eb_external_logfile.log, None) + self.assertTrue(eb_external_logfile.external_logfile) + self.assertEqual(eb_external_logfile.logfile, eb.logfile) + # Try to log something in it. + eb_external_logfile.log.info("Test message") + + # Try to close EasyBlock with external logfile. This should not affect the logger. + eb_external_logfile.close_log() + self.assertNotEqual(getattr(file_log, 'logtofile_%s' % eb.logfile), False) + # Then close the log from creating EasyBlock. This should work as expected. + eb.close_log() + self.assertEqual(getattr(file_log, 'logtofile_%s' % eb.logfile), False) + + os.remove(eb.logfile) + def suite(): """ return all the tests in this file """