/usr/lib/python3/dist-packages/logutils/testing.py is in python3-logutils 0.3.3-5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | #
# Copyright (C) 2010-2013 Vinay Sajip. See LICENSE.txt for details.
#
import logging
from logging.handlers import BufferingHandler
class TestHandler(BufferingHandler):
"""
This handler collects records in a buffer for later inspection by
your unit test code.
:param matcher: The :class:`~logutils.testing.Matcher` instance to
use for matching.
"""
def __init__(self, matcher):
# BufferingHandler takes a "capacity" argument
# so as to know when to flush. As we're overriding
# shouldFlush anyway, we can set a capacity of zero.
# You can call flush() manually to clear out the
# buffer.
BufferingHandler.__init__(self, 0)
self.formatted = []
self.matcher = matcher
def shouldFlush(self):
"""
Should the buffer be flushed?
This returns `False` - you'll need to flush manually, usually after
your unit test code checks the buffer contents against your
expectations.
"""
return False
def emit(self, record):
"""
Saves the `__dict__` of the record in the `buffer` attribute,
and the formatted records in the `formatted` attribute.
:param record: The record to emit.
"""
self.formatted.append(self.format(record))
self.buffer.append(record.__dict__)
def flush(self):
"""
Clears out the `buffer` and `formatted` attributes.
"""
BufferingHandler.flush(self)
self.formatted = []
def matches(self, **kwargs):
"""
Look for a saved dict whose keys/values match the supplied arguments.
Return `True` if found, else `False`.
:param kwargs: A set of keyword arguments whose names are LogRecord
attributes and whose values are what you want to
match in a stored LogRecord.
"""
result = False
for d in self.buffer:
if self.matcher.matches(d, **kwargs):
result = True
break
#if not result:
# print('*** matcher failed completely on %d records' % len(self.buffer))
return result
def matchall(self, kwarglist):
"""
Accept a list of keyword argument values and ensure that the handler's
buffer of stored records matches the list one-for-one.
Return `True` if exactly matched, else `False`.
:param kwarglist: A list of keyword-argument dictionaries, each of
which will be passed to :meth:`matches` with the
corresponding record from the buffer.
"""
if self.count != len(kwarglist):
result = False
else:
result = True
for d, kwargs in zip(self.buffer, kwarglist):
if not self.matcher.matches(d, **kwargs):
result = False
break
return result
@property
def count(self):
"""
The number of records in the buffer.
"""
return len(self.buffer)
class Matcher(object):
"""
This utility class matches a stored dictionary of
:class:`logging.LogRecord` attributes with keyword arguments
passed to its :meth:`~logutils.testing.Matcher.matches` method.
"""
_partial_matches = ('msg', 'message')
"""
A list of :class:`logging.LogRecord` attribute names which
will be checked for partial matches. If not in this list,
an exact match will be attempted.
"""
def matches(self, d, **kwargs):
"""
Try to match a single dict with the supplied arguments.
Keys whose values are strings and which are in self._partial_matches
will be checked for partial (i.e. substring) matches. You can extend
this scheme to (for example) do regular expression matching, etc.
Return `True` if found, else `False`.
:param kwargs: A set of keyword arguments whose names are LogRecord
attributes and whose values are what you want to
match in a stored LogRecord.
"""
result = True
for k in kwargs:
v = kwargs[k]
dv = d.get(k)
if not self.match_value(k, dv, v):
#print('*** matcher failed: %s, %r, %r' % (k, dv, v))
result = False
break
return result
def match_value(self, k, dv, v):
"""
Try to match a single stored value (dv) with a supplied value (v).
Return `True` if found, else `False`.
:param k: The key value (LogRecord attribute name).
:param dv: The stored value to match against.
:param v: The value to compare with the stored value.
"""
if type(v) != type(dv):
result = False
elif type(dv) is not str or k not in self._partial_matches:
result = (v == dv)
else:
result = dv.find(v) >= 0
#if not result:
# print('*** matcher failed on %s: %r vs. %r' % (k, dv, v))
return result
|