Skip to content

Commit

Permalink
Merge pull request #77 from etingof/tests-for-debug-mode
Browse files Browse the repository at this point in the history
Run unit tests with full debugging enabled
  • Loading branch information
etingof authored Sep 15, 2017
2 parents 218acc5 + e337ff6 commit bed9eed
Show file tree
Hide file tree
Showing 25 changed files with 459 additions and 242 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Revision 0.3.5, released XX-09-2017
chunk size encoding modes
- Fixed DER encoder to always produce primitive encoding
- Fixed crash at SequenceOf native decoder
- Fixed Real.prettyPrint() to fail gracefully on overflow
- Fixed a couple of crashes when debug mode is enabled
Revision 0.3.4, released 07-09-2017
-----------------------------------
Expand Down
2 changes: 1 addition & 1 deletion pyasn1/codec/ber/decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ def __call__(self, substrate, asn1Spec=None,
**options
)
if logger:
logger('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, value.prettyPrint(), substrate and debug.hexdump(substrate) or '<none>'))
logger('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, isinstance(value, base.Asn1Item) and value.prettyPrint() or value, substrate and debug.hexdump(substrate) or '<none>'))
state = stStop
break
if state is stTryAsExplicitTag:
Expand Down
2 changes: 1 addition & 1 deletion pyasn1/codec/ber/encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ def __call__(self, value, **options):
logger = None

if logger:
logger('encoder called in %sdef mode, chunk size %s for type %s, value:\n%s' % (not defMode and 'in' or '', maxChunkSize, value.prettyPrintType(), value.prettyPrint()))
logger('encoder called in %sdef mode, chunk size %s for type %s, value:\n%s' % (not options.get('defMode', True) and 'in' or '', options.get('maxChunkSize', 0), value.prettyPrintType(), value.prettyPrint()))

if self.fixedDefLengthMode is not None:
options.update(defMode=self.fixedDefLengthMode)
Expand Down
47 changes: 30 additions & 17 deletions pyasn1/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,31 @@ class Printer(object):
def __init__(self, logger=None, handler=None, formatter=None):
if logger is None:
logger = logging.getLogger('pyasn1')

logger.setLevel(logging.DEBUG)

if handler is None:
handler = logging.StreamHandler()

if formatter is None:
formatter = logging.Formatter('%(asctime)s %(name)s: %(message)s')

handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)

self.__logger = logger

def __call__(self, msg):
self.__logger.debug(msg)

def __str__(self):
return '<python built-in logging>'
return '<python logging>'


if hasattr(logging, 'NullHandler'):
NullHandler = logging.NullHandler

else:
# Python 2.6 and older
class NullHandler(logging.Handler):
Expand All @@ -55,36 +61,39 @@ def emit(self, record):


class Debug(object):
defaultPrinter = None
defaultPrinter = Printer()

def __init__(self, *flags, **options):
self._flags = flagNone
if options.get('printer') is not None:
self._printer = options.get('printer')
elif self.defaultPrinter is not None:
self._printer = self.defaultPrinter

if 'loggerName' in options:
# route our logs to parent logger
self._printer = Printer(
logger=logging.getLogger(options['loggerName']),
handler=NullHandler()
)

elif 'printer' in options:
self._printer = options.get('printer')

else:
self._printer = Printer()
self('running pyasn1 version %s' % __version__)
for f in flags:
inverse = f and f[0] in ('!', '~')
self._printer = self.defaultPrinter

self._printer('running pyasn1 %s, debug flags %s' % (__version__, ', '.join(flags)))

for flag in flags:
inverse = flag and flag[0] in ('!', '~')
if inverse:
f = f[1:]
flag = flag[1:]
try:
if inverse:
self._flags &= ~flagMap[f]
self._flags &= ~flagMap[flag]
else:
self._flags |= flagMap[f]
self._flags |= flagMap[flag]
except KeyError:
raise error.PyAsn1Error('bad debug flag %s' % f)
raise error.PyAsn1Error('bad debug flag %s' % flag)

self('debug category \'%s\' %s' % (f, inverse and 'disabled' or 'enabled'))
self._printer("debug category '%s' %s" % (flag, inverse and 'disabled' or 'enabled'))

def __str__(self):
return 'logger %s, flags %x' % (self._printer, self._flags)
Expand All @@ -102,9 +111,13 @@ def __rand__(self, flag):
logger = 0


def setLogger(l):
def setLogger(userLogger):
global logger
logger = l

if userLogger:
logger = userLogger
else:
logger = 0


def hexdump(octets):
Expand Down
6 changes: 5 additions & 1 deletion pyasn1/type/univ.py
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,11 @@ def prettyPrint(self, scope=0):
if self.isInf:
return self.prettyOut(self._value)
else:
return str(float(self))
try:
return str(float(self))

except OverflowError:
return '<overflow>'

@property
def isPlusInf(self):
Expand Down
22 changes: 22 additions & 0 deletions tests/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2017, Ilya Etingof <[email protected]>
# License: http://pyasn1.sf.net/license.html
#
import sys
try:
import unittest2 as unittest
except ImportError:
import unittest

from pyasn1 import debug


class BaseTestCase(unittest.TestCase):

def setUp(self):
debug.setLogger(debug.Debug('all', printer=lambda *x: None))

def tearDown(self):
debug.setLogger(None)
Loading

0 comments on commit bed9eed

Please sign in to comment.