def test_is_same_output(self): fd1 = sys.stderr.fileno() fd2 = os.dup(fd1) try: self.assertTrue(ConfigureOutputHandler._is_same_output(fd1, fd2)) finally: os.close(fd2) fd2, path = tempfile.mkstemp() try: self.assertFalse(ConfigureOutputHandler._is_same_output(fd1, fd2)) fd3 = os.dup(fd2) try: self.assertTrue(ConfigureOutputHandler._is_same_output(fd2, fd3)) finally: os.close(fd3) with open(path, 'a') as fh: fd3 = fh.fileno() self.assertTrue( ConfigureOutputHandler._is_same_output(fd2, fd3)) finally: os.close(fd2) os.remove(path)
def test_format(self): out = StringIO() err = StringIO() name = '%s.test_format' % self.__class__.__name__ logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) handler = ConfigureOutputHandler(out, err) handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s')) logger.addHandler(handler) logger.error('foo') logger.warning('bar') logger.info('baz') # DEBUG level is not printed out by this handler logger.debug('qux') self.assertEqual(out.getvalue(), 'baz\n') self.assertEqual(err.getvalue(), 'ERROR:foo\n' 'WARNING:bar\n')
def test_format(self): out = StringIO() err = StringIO() name = '%s.test_format' % self.__class__.__name__ logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) handler = ConfigureOutputHandler(out, err) handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s')) logger.addHandler(handler) logger.error('foo') logger.warning('bar') logger.info('baz') # DEBUG level is not printed out by this handler logger.debug('qux') self.assertEqual(out.getvalue(), 'baz\n') self.assertEqual( err.getvalue(), 'ERROR:foo\n' 'WARNING:bar\n' )
def test_separation(self): out = StringIO() err = StringIO() name = '%s.test_separation' % self.__class__.__name__ logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) logger.addHandler(ConfigureOutputHandler(out, err)) logger.error('foo') logger.warning('bar') logger.info('baz') # DEBUG level is not printed out by this handler logger.debug('qux') self.assertEqual(out.getvalue(), 'baz\n') self.assertEqual(err.getvalue(), 'foo\nbar\n')
def test_continuation(self): out = StringIO() name = '%s.test_continuation' % self.__class__.__name__ logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) handler = ConfigureOutputHandler(out, out) handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s')) logger.addHandler(handler) logger.info('foo') logger.info('checking bar... ') logger.info('yes') logger.info('qux') self.assertEqual( out.getvalue(), 'foo\n' 'checking bar... yes\n' 'qux\n' ) out.seek(0) out.truncate() logger.info('foo') logger.info('checking bar... ') logger.warning('hoge') logger.info('no') logger.info('qux') self.assertEqual( out.getvalue(), 'foo\n' 'checking bar... \n' 'WARNING:hoge\n' ' ... no\n' 'qux\n' ) out.seek(0) out.truncate() logger.info('foo') logger.info('checking bar... ') logger.warning('hoge') logger.warning('fuga') logger.info('no') logger.info('qux') self.assertEqual( out.getvalue(), 'foo\n' 'checking bar... \n' 'WARNING:hoge\n' 'WARNING:fuga\n' ' ... no\n' 'qux\n' ) out.seek(0) out.truncate() err = StringIO() logger.removeHandler(handler) handler = ConfigureOutputHandler(out, err) handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s')) logger.addHandler(handler) logger.info('foo') logger.info('checking bar... ') logger.warning('hoge') logger.warning('fuga') logger.info('no') logger.info('qux') self.assertEqual( out.getvalue(), 'foo\n' 'checking bar... no\n' 'qux\n' ) self.assertEqual( err.getvalue(), 'WARNING:hoge\n' 'WARNING:fuga\n' )
def test_queue_debug(self): out = StringIO() name = '%s.test_queue_debug' % self.__class__.__name__ logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) handler = ConfigureOutputHandler(out, out, maxlen=3) handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s')) logger.addHandler(handler) with handler.queue_debug(): logger.info('checking bar... ') logger.debug('do foo') logger.info('yes') logger.info('qux') self.assertEqual( out.getvalue(), 'checking bar... yes\n' 'qux\n' ) out.seek(0) out.truncate() with handler.queue_debug(): logger.info('checking bar... ') logger.debug('do foo') logger.info('no') logger.error('fail') self.assertEqual( out.getvalue(), 'checking bar... no\n' 'DEBUG:do foo\n' 'ERROR:fail\n' ) out.seek(0) out.truncate() with handler.queue_debug(): logger.info('checking bar... ') logger.debug('do foo') logger.debug('do bar') logger.debug('do baz') logger.info('no') logger.error('fail') self.assertEqual( out.getvalue(), 'checking bar... no\n' 'DEBUG:do foo\n' 'DEBUG:do bar\n' 'DEBUG:do baz\n' 'ERROR:fail\n' ) out.seek(0) out.truncate() with handler.queue_debug(): logger.info('checking bar... ') logger.debug('do foo') logger.debug('do bar') logger.debug('do baz') logger.debug('do qux') logger.debug('do hoge') logger.info('no') logger.error('fail') self.assertEqual( out.getvalue(), 'checking bar... no\n' 'DEBUG:<truncated - see config.log for full output>\n' 'DEBUG:do baz\n' 'DEBUG:do qux\n' 'DEBUG:do hoge\n' 'ERROR:fail\n' )
def __init__(self, config, environ=os.environ, argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr, logger=None): dict.__setitem__(self, '__builtins__', self.BUILTINS) self._environ = dict(environ) self._paths = [] self._all_paths = set() self._templates = set() # Associate SandboxDependsFunctions to DependsFunctions. self._depends = OrderedDict() self._seen = set() # Store the @imports added to a given function. self._imports = {} self._options = OrderedDict() # Store raw option (as per command line or environment) for each Option self._raw_options = OrderedDict() # Store options added with `imply_option`, and the reason they were # added (which can either have been given to `imply_option`, or # inferred. Their order matters, so use a list. self._implied_options = [] # Store all results from _prepare_function self._prepared_functions = set() # Queue of functions to execute, with their arguments self._execution_queue = [] # Store the `when`s associated to some options. self._conditions = {} # A list of conditions to apply as a default `when` for every *_impl() self._default_conditions = [] self._helper = CommandLineHelper(environ, argv) assert isinstance(config, dict) self._config = config # Tracks how many templates "deep" we are in the stack. self._template_depth = 0 logging.addLevelName(TRACE, 'TRACE') if logger is None: logger = moz_logger = logging.getLogger('moz.configure') logger.setLevel(logging.DEBUG) formatter = logging.Formatter('%(levelname)s: %(message)s') handler = ConfigureOutputHandler(stdout, stderr) handler.setFormatter(formatter) queue_debug = handler.queue_debug logger.addHandler(handler) else: assert isinstance(logger, logging.Logger) moz_logger = None @contextmanager def queue_debug(): yield self._logger = logger # Some callers will manage to log a bytestring with characters in it # that can't be converted to ascii. Make our log methods robust to this # by detecting the encoding that a producer is likely to have used. encoding = getpreferredencoding() def wrapped_log_method(logger, key): method = getattr(logger, key) def wrapped(*args, **kwargs): out_args = [ six.ensure_text(arg, encoding=encoding or 'utf-8') if isinstance(arg, six.binary_type) else arg for arg in args ] return method(*out_args, **kwargs) return wrapped log_namespace = { k: wrapped_log_method(logger, k) for k in ('debug', 'info', 'warning', 'error') } log_namespace['queue_debug'] = queue_debug self.log_impl = ReadOnlyNamespace(**log_namespace) self._help = None self._help_option = self.option_impl( '--help', help='print this message', category=HELP_OPTIONS_CATEGORY) self._seen.add(self._help_option) self._always = DependsFunction(self, lambda: True, []) self._never = DependsFunction(self, lambda: False, []) if self._value_for(self._help_option): self._help = HelpFormatter(argv[0]) self._help.add(self._help_option) elif moz_logger: handler = logging.FileHandler('config.log', mode='w', delay=True, encoding='utf-8') handler.setFormatter(formatter) logger.addHandler(handler)
def __init__(self, config, environ=os.environ, argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr, logger=None): dict.__setitem__(self, '__builtins__', self.BUILTINS) self._paths = [] self._all_paths = set() self._templates = set() # Associate SandboxDependsFunctions to DependsFunctions. self._depends = OrderedDict() self._seen = set() # Store the @imports added to a given function. self._imports = {} self._options = OrderedDict() # Store raw option (as per command line or environment) for each Option self._raw_options = OrderedDict() # Store options added with `imply_option`, and the reason they were # added (which can either have been given to `imply_option`, or # inferred. Their order matters, so use a list. self._implied_options = [] # Store all results from _prepare_function self._prepared_functions = set() # Queue of functions to execute, with their arguments self._execution_queue = [] # Store the `when`s associated to some options. self._conditions = {} # A list of conditions to apply as a default `when` for every *_impl() self._default_conditions = [] self._helper = CommandLineHelper(environ, argv) assert isinstance(config, dict) self._config = config if logger is None: logger = moz_logger = logging.getLogger('moz.configure') logger.setLevel(logging.DEBUG) formatter = logging.Formatter('%(levelname)s: %(message)s') handler = ConfigureOutputHandler(stdout, stderr) handler.setFormatter(formatter) queue_debug = handler.queue_debug logger.addHandler(handler) else: assert isinstance(logger, logging.Logger) moz_logger = None @contextmanager def queue_debug(): yield # Some callers will manage to log a bytestring with characters in it # that can't be converted to ascii. Make our log methods robust to this # by detecting the encoding that a producer is likely to have used. encoding = getpreferredencoding() def wrapped_log_method(logger, key): method = getattr(logger, key) if not encoding: return method def wrapped(*args, **kwargs): out_args = [ arg.decode(encoding) if isinstance(arg, str) else arg for arg in args ] return method(*out_args, **kwargs) return wrapped log_namespace = { k: wrapped_log_method(logger, k) for k in ('debug', 'info', 'warning', 'error') } log_namespace['queue_debug'] = queue_debug self.log_impl = ReadOnlyNamespace(**log_namespace) self._help = None self._help_option = self.option_impl('--help', help='print this message') self._seen.add(self._help_option) self._always = DependsFunction(self, lambda: True, []) self._never = DependsFunction(self, lambda: False, []) if self._value_for(self._help_option): self._help = HelpFormatter(argv[0]) self._help.add(self._help_option) elif moz_logger: handler = logging.FileHandler('config.log', mode='w', delay=True) handler.setFormatter(formatter) logger.addHandler(handler)
def __init__(self, config, environ=os.environ, argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr, logger=None): dict.__setitem__(self, '__builtins__', self.BUILTINS) self._paths = [] self._all_paths = set() self._templates = set() # Store the real function and its dependencies, behind each # DependsFunction generated from @depends. self._depends = {} self._seen = set() # Store the @imports added to a given function. self._imports = {} self._options = OrderedDict() # Store raw option (as per command line or environment) for each Option self._raw_options = OrderedDict() # Store options added with `imply_option`, and the reason they were # added (which can either have been given to `imply_option`, or # inferred. Their order matters, so use a list. self._implied_options = [] # Store all results from _prepare_function self._prepared_functions = set() # Queue of functions to execute, with their arguments self._execution_queue = [] self._helper = CommandLineHelper(environ, argv) assert isinstance(config, dict) self._config = config if logger is None: logger = moz_logger = logging.getLogger('moz.configure') logger.setLevel(logging.DEBUG) formatter = logging.Formatter('%(levelname)s: %(message)s') handler = ConfigureOutputHandler(stdout, stderr) handler.setFormatter(formatter) queue_debug = handler.queue_debug logger.addHandler(handler) else: assert isinstance(logger, logging.Logger) moz_logger = None @contextmanager def queue_debug(): yield log_namespace = { k: getattr(logger, k) for k in ('debug', 'info', 'warning', 'error') } log_namespace['queue_debug'] = queue_debug self.log_impl = ReadOnlyNamespace(**log_namespace) self._help = None self._help_option = self.option_impl('--help', help='print this message') self._seen.add(self._help_option) if self._value_for(self._help_option): self._help = HelpFormatter(argv[0]) self._help.add(self._help_option) elif moz_logger: handler = logging.FileHandler('config.log', mode='w', delay=True) handler.setFormatter(formatter) logger.addHandler(handler)
def test_queue_debug_reentrant(self): out = StringIO() name = '%s.test_queue_debug_reentrant' % self.__class__.__name__ logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) handler = ConfigureOutputHandler(out, out, maxlen=10) handler.setFormatter(logging.Formatter('%(levelname)s| %(message)s')) logger.addHandler(handler) try: with handler.queue_debug(): logger.info('outer info') logger.debug('outer debug') with handler.queue_debug(): logger.info('inner info') logger.debug('inner debug') e = Exception('inner exception') raise e except Exception as caught: self.assertIs(caught, e) self.assertEqual(out.getvalue(), 'outer info\n' 'inner info\n' 'DEBUG| outer debug\n' 'DEBUG| inner debug\n') out.seek(0) out.truncate() try: with handler.queue_debug(): logger.info('outer info') logger.debug('outer debug') with handler.queue_debug(): logger.info('inner info') logger.debug('inner debug') e = Exception('outer exception') raise e except Exception as caught: self.assertIs(caught, e) self.assertEqual(out.getvalue(), 'outer info\n' 'inner info\n' 'DEBUG| outer debug\n' 'DEBUG| inner debug\n') out.seek(0) out.truncate() with handler.queue_debug(): logger.info('outer info') logger.debug('outer debug') with handler.queue_debug(): logger.info('inner info') logger.debug('inner debug') logger.error('inner error') self.assertEqual(out.getvalue(), 'outer info\n' 'inner info\n' 'DEBUG| outer debug\n' 'DEBUG| inner debug\n' 'ERROR| inner error\n') out.seek(0) out.truncate() with handler.queue_debug(): logger.info('outer info') logger.debug('outer debug') with handler.queue_debug(): logger.info('inner info') logger.debug('inner debug') logger.error('outer error') self.assertEqual(out.getvalue(), 'outer info\n' 'inner info\n' 'DEBUG| outer debug\n' 'DEBUG| inner debug\n' 'ERROR| outer error\n')
def test_queue_debug(self): out = StringIO() name = '%s.test_queue_debug' % self.__class__.__name__ logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) handler = ConfigureOutputHandler(out, out, maxlen=3) handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s')) logger.addHandler(handler) with handler.queue_debug(): logger.info('checking bar... ') logger.debug('do foo') logger.info('yes') logger.info('qux') self.assertEqual( out.getvalue(), 'checking bar... yes\n' 'qux\n' ) out.seek(0) out.truncate() with handler.queue_debug(): logger.info('checking bar... ') logger.debug('do foo') logger.info('no') logger.error('fail') self.assertEqual( out.getvalue(), 'checking bar... no\n' 'DEBUG:do foo\n' 'ERROR:fail\n' ) out.seek(0) out.truncate() with handler.queue_debug(): logger.info('checking bar... ') logger.debug('do foo') logger.debug('do bar') logger.debug('do baz') logger.info('no') logger.error('fail') self.assertEqual( out.getvalue(), 'checking bar... no\n' 'DEBUG:do foo\n' 'DEBUG:do bar\n' 'DEBUG:do baz\n' 'ERROR:fail\n' ) out.seek(0) out.truncate() with handler.queue_debug(): logger.info('checking bar... ') logger.debug('do foo') logger.debug('do bar') logger.debug('do baz') logger.debug('do qux') logger.debug('do hoge') logger.info('no') logger.error('fail') self.assertEqual( out.getvalue(), 'checking bar... no\n' 'DEBUG:<truncated - see config.log for full output>\n' 'DEBUG:do baz\n' 'DEBUG:do qux\n' 'DEBUG:do hoge\n' 'ERROR:fail\n' ) out.seek(0) out.truncate() try: with handler.queue_debug(): logger.info('checking bar... ') logger.debug('do foo') logger.debug('do bar') logger.info('no') e = Exception('fail') raise e except Exception as caught: self.assertIs(caught, e) self.assertEqual( out.getvalue(), 'checking bar... no\n' 'DEBUG:do foo\n' 'DEBUG:do bar\n' )
def __init__(self, config, environ=os.environ, argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr, logger=None): dict.__setitem__(self, '__builtins__', self.BUILTINS) self._paths = [] self._templates = set() # Store the real function and its dependencies, behind each # DependsFunction generated from @depends. self._depends = {} self._seen = set() # Store the @imports added to a given function. self._imports = {} self._options = OrderedDict() # Store the raw values returned by @depends functions self._results = {} # Store values for each Option, as per returned by Option.get_value self._option_values = {} # Store raw option (as per command line or environment) for each Option self._raw_options = {} # Store options added with `imply_option`, and the reason they were # added (which can either have been given to `imply_option`, or # inferred. self._implied_options = {} # Store all results from _prepare_function self._prepared_functions = set() self._helper = CommandLineHelper(environ, argv) assert isinstance(config, dict) self._config = config if logger is None: logger = moz_logger = logging.getLogger('moz.configure') logger.setLevel(logging.DEBUG) formatter = logging.Formatter('%(levelname)s: %(message)s') handler = ConfigureOutputHandler(stdout, stderr) handler.setFormatter(formatter) queue_debug = handler.queue_debug logger.addHandler(handler) else: assert isinstance(logger, logging.Logger) moz_logger = None @contextmanager def queue_debug(): yield log_namespace = { k: getattr(logger, k) for k in ('debug', 'info', 'warning', 'error') } log_namespace['queue_debug'] = queue_debug self.log_impl = ReadOnlyNamespace(**log_namespace) self._help = None self._help_option = self.option_impl('--help', help='print this message') self._seen.add(self._help_option) # self._option_impl('--help') will have set this if --help was on the # command line. if self._option_values[self._help_option]: self._help = HelpFormatter(argv[0]) self._help.add(self._help_option) elif moz_logger: handler = logging.FileHandler('config.log', mode='w', delay=True) handler.setFormatter(formatter) logger.addHandler(handler)
def __init__(self, config, environ=os.environ, argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr, logger=None): dict.__setitem__(self, '__builtins__', self.BUILTINS) self._paths = [] self._all_paths = set() self._templates = set() # Store the real function and its dependencies, behind each # DependsFunction generated from @depends. self._depends = {} self._seen = set() # Store the @imports added to a given function. self._imports = {} self._options = OrderedDict() # Store raw option (as per command line or environment) for each Option self._raw_options = OrderedDict() # Store options added with `imply_option`, and the reason they were # added (which can either have been given to `imply_option`, or # inferred. Their order matters, so use a list. self._implied_options = [] # Store all results from _prepare_function self._prepared_functions = set() # Queue of functions to execute, with their arguments self._execution_queue = [] self._helper = CommandLineHelper(environ, argv) assert isinstance(config, dict) self._config = config if logger is None: logger = moz_logger = logging.getLogger('moz.configure') logger.setLevel(logging.DEBUG) formatter = logging.Formatter('%(levelname)s: %(message)s') handler = ConfigureOutputHandler(stdout, stderr) handler.setFormatter(formatter) queue_debug = handler.queue_debug logger.addHandler(handler) else: assert isinstance(logger, logging.Logger) moz_logger = None @contextmanager def queue_debug(): yield # Some callers will manage to log a bytestring with characters in it # that can't be converted to ascii. Make our log methods robust to this # by detecting the encoding that a producer is likely to have used. encoding = getpreferredencoding() def wrapped_log_method(logger, key): method = getattr(logger, key) if not encoding: return method def wrapped(*args, **kwargs): out_args = [ arg.decode(encoding) if isinstance(arg, str) else arg for arg in args ] return method(*out_args, **kwargs) return wrapped log_namespace = { k: wrapped_log_method(logger, k) for k in ('debug', 'info', 'warning', 'error') } log_namespace['queue_debug'] = queue_debug self.log_impl = ReadOnlyNamespace(**log_namespace) self._help = None self._help_option = self.option_impl('--help', help='print this message') self._seen.add(self._help_option) if self._value_for(self._help_option): self._help = HelpFormatter(argv[0]) self._help.add(self._help_option) elif moz_logger: handler = logging.FileHandler('config.log', mode='w', delay=True) handler.setFormatter(formatter) logger.addHandler(handler)