Ausgabe der neuen DB Einträge
This commit is contained in:
parent
bad48e1627
commit
cfbbb9ee3d
2399 changed files with 843193 additions and 43 deletions
|
|
@ -0,0 +1,472 @@
|
|||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Test cases for L{twisted.logger._legacy}.
|
||||
"""
|
||||
|
||||
from time import time
|
||||
import logging as py_logging
|
||||
|
||||
from zope.interface.verify import verifyObject, BrokenMethodImplementation
|
||||
|
||||
from twisted.trial import unittest
|
||||
|
||||
from twisted.python import context
|
||||
from twisted.python import log as legacyLog
|
||||
from twisted.python.failure import Failure
|
||||
|
||||
from .._levels import LogLevel
|
||||
from .._observer import ILogObserver
|
||||
from .._format import formatEvent
|
||||
from .._legacy import LegacyLogObserverWrapper
|
||||
from .._legacy import publishToNewObserver
|
||||
|
||||
|
||||
|
||||
class LegacyLogObserverWrapperTests(unittest.TestCase):
|
||||
"""
|
||||
Tests for L{LegacyLogObserverWrapper}.
|
||||
"""
|
||||
|
||||
def test_interface(self):
|
||||
"""
|
||||
L{LegacyLogObserverWrapper} is an L{ILogObserver}.
|
||||
"""
|
||||
legacyObserver = lambda e: None
|
||||
observer = LegacyLogObserverWrapper(legacyObserver)
|
||||
try:
|
||||
verifyObject(ILogObserver, observer)
|
||||
except BrokenMethodImplementation as e:
|
||||
self.fail(e)
|
||||
|
||||
|
||||
def test_repr(self):
|
||||
"""
|
||||
L{LegacyLogObserverWrapper} returns the expected string.
|
||||
"""
|
||||
class LegacyObserver(object):
|
||||
def __repr__(self):
|
||||
return "<Legacy Observer>"
|
||||
|
||||
def __call__(self):
|
||||
return
|
||||
|
||||
observer = LegacyLogObserverWrapper(LegacyObserver())
|
||||
|
||||
self.assertEqual(
|
||||
repr(observer),
|
||||
"LegacyLogObserverWrapper(<Legacy Observer>)"
|
||||
)
|
||||
|
||||
|
||||
def observe(self, event):
|
||||
"""
|
||||
Send an event to a wrapped legacy observer and capture the event as
|
||||
seen by that observer.
|
||||
|
||||
@param event: an event
|
||||
@type event: L{dict}
|
||||
|
||||
@return: the event as observed by the legacy wrapper
|
||||
"""
|
||||
events = []
|
||||
|
||||
legacyObserver = lambda e: events.append(e)
|
||||
observer = LegacyLogObserverWrapper(legacyObserver)
|
||||
observer(event)
|
||||
self.assertEqual(len(events), 1)
|
||||
|
||||
return events[0]
|
||||
|
||||
|
||||
def forwardAndVerify(self, event):
|
||||
"""
|
||||
Send an event to a wrapped legacy observer and verify that its data is
|
||||
preserved.
|
||||
|
||||
@param event: an event
|
||||
@type event: L{dict}
|
||||
|
||||
@return: the event as observed by the legacy wrapper
|
||||
"""
|
||||
# Make sure keys that are expected by the logging system are present
|
||||
event.setdefault("log_time", time())
|
||||
event.setdefault("log_system", "-")
|
||||
event.setdefault("log_level", LogLevel.info)
|
||||
|
||||
# Send a copy: don't mutate me, bro
|
||||
observed = self.observe(dict(event))
|
||||
|
||||
# Don't expect modifications
|
||||
for key, value in event.items():
|
||||
self.assertIn(key, observed)
|
||||
|
||||
return observed
|
||||
|
||||
|
||||
def test_forward(self):
|
||||
"""
|
||||
Basic forwarding: event keys as observed by a legacy observer are the
|
||||
same.
|
||||
"""
|
||||
self.forwardAndVerify(dict(foo=1, bar=2))
|
||||
|
||||
|
||||
def test_time(self):
|
||||
"""
|
||||
The new-style C{"log_time"} key is copied to the old-style C{"time"}
|
||||
key.
|
||||
"""
|
||||
stamp = time()
|
||||
event = self.forwardAndVerify(dict(log_time=stamp))
|
||||
self.assertEqual(event["time"], stamp)
|
||||
|
||||
|
||||
def test_timeAlreadySet(self):
|
||||
"""
|
||||
The new-style C{"log_time"} key does not step on a pre-existing
|
||||
old-style C{"time"} key.
|
||||
"""
|
||||
stamp = time()
|
||||
event = self.forwardAndVerify(dict(log_time=stamp + 1, time=stamp))
|
||||
self.assertEqual(event["time"], stamp)
|
||||
|
||||
|
||||
def test_system(self):
|
||||
"""
|
||||
The new-style C{"log_system"} key is copied to the old-style
|
||||
C{"system"} key.
|
||||
"""
|
||||
event = self.forwardAndVerify(dict(log_system="foo"))
|
||||
self.assertEqual(event["system"], "foo")
|
||||
|
||||
|
||||
def test_systemAlreadySet(self):
|
||||
"""
|
||||
The new-style C{"log_system"} key does not step on a pre-existing
|
||||
old-style C{"system"} key.
|
||||
"""
|
||||
event = self.forwardAndVerify(dict(log_system="foo", system="bar"))
|
||||
self.assertEqual(event["system"], "bar")
|
||||
|
||||
|
||||
def test_noSystem(self):
|
||||
"""
|
||||
If the new-style C{"log_system"} key is absent, the old-style
|
||||
C{"system"} key is set to C{"-"}.
|
||||
"""
|
||||
# Don't use forwardAndVerify(), since that sets log_system.
|
||||
event = dict(log_time=time(), log_level=LogLevel.info)
|
||||
observed = self.observe(dict(event))
|
||||
self.assertEqual(observed["system"], "-")
|
||||
|
||||
|
||||
def test_levelNotChange(self):
|
||||
"""
|
||||
If explicitly set, the C{isError} key will be preserved when forwarding
|
||||
from a new-style logging emitter to a legacy logging observer,
|
||||
regardless of log level.
|
||||
"""
|
||||
self.forwardAndVerify(dict(log_level=LogLevel.info, isError=1))
|
||||
self.forwardAndVerify(dict(log_level=LogLevel.warn, isError=1))
|
||||
self.forwardAndVerify(dict(log_level=LogLevel.error, isError=0))
|
||||
self.forwardAndVerify(dict(log_level=LogLevel.critical, isError=0))
|
||||
|
||||
|
||||
def test_pythonLogLevelNotSet(self):
|
||||
"""
|
||||
The new-style C{"log_level"} key is not translated to the old-style
|
||||
C{"logLevel"} key.
|
||||
|
||||
Events are forwarded from the old module from to new module and are
|
||||
then seen by old-style observers.
|
||||
We don't want to add unexpected keys to old-style events.
|
||||
"""
|
||||
event = self.forwardAndVerify(dict(log_level=LogLevel.info))
|
||||
self.assertNotIn("logLevel", event)
|
||||
|
||||
|
||||
def test_stringPythonLogLevel(self):
|
||||
"""
|
||||
If a stdlib log level was provided as a string (eg. C{"WARNING"}) in
|
||||
the legacy "logLevel" key, it does not get converted to a number.
|
||||
The documentation suggested that numerical values should be used but
|
||||
this was not a requirement.
|
||||
"""
|
||||
event = self.forwardAndVerify(dict(
|
||||
logLevel="WARNING", # py_logging.WARNING is 30
|
||||
))
|
||||
self.assertEqual(event["logLevel"], "WARNING")
|
||||
|
||||
|
||||
def test_message(self):
|
||||
"""
|
||||
The old-style C{"message"} key is added, even if no new-style
|
||||
C{"log_format"} is given, as it is required, but may be empty.
|
||||
"""
|
||||
event = self.forwardAndVerify(dict())
|
||||
self.assertEqual(event["message"], ()) # "message" is a tuple
|
||||
|
||||
|
||||
def test_messageAlreadySet(self):
|
||||
"""
|
||||
The old-style C{"message"} key is not modified if it already exists.
|
||||
"""
|
||||
event = self.forwardAndVerify(dict(message=("foo", "bar")))
|
||||
self.assertEqual(event["message"], ("foo", "bar"))
|
||||
|
||||
|
||||
def test_format(self):
|
||||
"""
|
||||
Formatting is translated such that text is rendered correctly, even
|
||||
though old-style logging doesn't use PEP 3101 formatting.
|
||||
"""
|
||||
event = self.forwardAndVerify(
|
||||
dict(log_format="Hello, {who}!", who="world")
|
||||
)
|
||||
self.assertEqual(
|
||||
legacyLog.textFromEventDict(event),
|
||||
"Hello, world!"
|
||||
)
|
||||
|
||||
|
||||
def test_formatMessage(self):
|
||||
"""
|
||||
Using the message key, which is special in old-style, works for
|
||||
new-style formatting.
|
||||
"""
|
||||
event = self.forwardAndVerify(
|
||||
dict(log_format="Hello, {message}!", message="world")
|
||||
)
|
||||
self.assertEqual(
|
||||
legacyLog.textFromEventDict(event),
|
||||
"Hello, world!"
|
||||
)
|
||||
|
||||
|
||||
def test_formatAlreadySet(self):
|
||||
"""
|
||||
Formatting is not altered if the old-style C{"format"} key already
|
||||
exists.
|
||||
"""
|
||||
event = self.forwardAndVerify(
|
||||
dict(log_format="Hello!", format="Howdy!")
|
||||
)
|
||||
self.assertEqual(legacyLog.textFromEventDict(event), "Howdy!")
|
||||
|
||||
|
||||
def eventWithFailure(self, **values):
|
||||
"""
|
||||
Create a new-style event with a captured failure.
|
||||
|
||||
@param values: Additional values to include in the event.
|
||||
@type values: L{dict}
|
||||
|
||||
@return: the new event
|
||||
@rtype: L{dict}
|
||||
"""
|
||||
failure = Failure(RuntimeError("nyargh!"))
|
||||
return self.forwardAndVerify(dict(
|
||||
log_failure=failure,
|
||||
log_format="oopsie...",
|
||||
**values
|
||||
))
|
||||
|
||||
|
||||
def test_failure(self):
|
||||
"""
|
||||
Captured failures in the new style set the old-style C{"failure"},
|
||||
C{"isError"}, and C{"why"} keys.
|
||||
"""
|
||||
event = self.eventWithFailure()
|
||||
self.assertIs(event["failure"], event["log_failure"])
|
||||
self.assertTrue(event["isError"])
|
||||
self.assertEqual(event["why"], "oopsie...")
|
||||
|
||||
|
||||
def test_failureAlreadySet(self):
|
||||
"""
|
||||
Captured failures in the new style do not step on a pre-existing
|
||||
old-style C{"failure"} key.
|
||||
"""
|
||||
failure = Failure(RuntimeError("Weak salsa!"))
|
||||
event = self.eventWithFailure(failure=failure)
|
||||
self.assertIs(event["failure"], failure)
|
||||
|
||||
|
||||
def test_isErrorAlreadySet(self):
|
||||
"""
|
||||
Captured failures in the new style do not step on a pre-existing
|
||||
old-style C{"isError"} key.
|
||||
"""
|
||||
event = self.eventWithFailure(isError=0)
|
||||
self.assertEqual(event["isError"], 0)
|
||||
|
||||
|
||||
def test_whyAlreadySet(self):
|
||||
"""
|
||||
Captured failures in the new style do not step on a pre-existing
|
||||
old-style C{"failure"} key.
|
||||
"""
|
||||
event = self.eventWithFailure(why="blah")
|
||||
self.assertEqual(event["why"], "blah")
|
||||
|
||||
|
||||
|
||||
class PublishToNewObserverTests(unittest.TestCase):
|
||||
"""
|
||||
Tests for L{publishToNewObserver}.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.events = []
|
||||
self.observer = self.events.append
|
||||
|
||||
|
||||
def legacyEvent(self, *message, **values):
|
||||
"""
|
||||
Return a basic old-style event as would be created by L{legacyLog.msg}.
|
||||
|
||||
@param message: a message event value in the legacy event format
|
||||
@type message: L{tuple} of L{bytes}
|
||||
|
||||
@param values: additional event values in the legacy event format
|
||||
@type event: L{dict}
|
||||
|
||||
@return: a legacy event
|
||||
"""
|
||||
event = (context.get(legacyLog.ILogContext) or {}).copy()
|
||||
event.update(values)
|
||||
event["message"] = message
|
||||
event["time"] = time()
|
||||
if "isError" not in event:
|
||||
event["isError"] = 0
|
||||
return event
|
||||
|
||||
|
||||
def test_observed(self):
|
||||
"""
|
||||
The observer is called exactly once.
|
||||
"""
|
||||
publishToNewObserver(
|
||||
self.observer, self.legacyEvent(), legacyLog.textFromEventDict
|
||||
)
|
||||
self.assertEqual(len(self.events), 1)
|
||||
|
||||
|
||||
def test_time(self):
|
||||
"""
|
||||
The old-style C{"time"} key is copied to the new-style C{"log_time"}
|
||||
key.
|
||||
"""
|
||||
publishToNewObserver(
|
||||
self.observer, self.legacyEvent(), legacyLog.textFromEventDict
|
||||
)
|
||||
self.assertEqual(
|
||||
self.events[0]["log_time"], self.events[0]["time"]
|
||||
)
|
||||
|
||||
|
||||
def test_message(self):
|
||||
"""
|
||||
A published old-style event should format as text in the same way as
|
||||
the given C{textFromEventDict} callable would format it.
|
||||
"""
|
||||
def textFromEventDict(event):
|
||||
return "".join(reversed(" ".join(event["message"])))
|
||||
|
||||
event = self.legacyEvent("Hello,", "world!")
|
||||
text = textFromEventDict(event)
|
||||
|
||||
publishToNewObserver(self.observer, event, textFromEventDict)
|
||||
self.assertEqual(formatEvent(self.events[0]), text)
|
||||
|
||||
|
||||
def test_defaultLogLevel(self):
|
||||
"""
|
||||
Published event should have log level of L{LogLevel.info}.
|
||||
"""
|
||||
publishToNewObserver(
|
||||
self.observer, self.legacyEvent(), legacyLog.textFromEventDict
|
||||
)
|
||||
self.assertEqual(self.events[0]["log_level"], LogLevel.info)
|
||||
|
||||
|
||||
def test_isError(self):
|
||||
"""
|
||||
If C{"isError"} is set to C{1} (true) on the legacy event, the
|
||||
C{"log_level"} key should get set to L{LogLevel.critical}.
|
||||
"""
|
||||
publishToNewObserver(
|
||||
self.observer,
|
||||
self.legacyEvent(isError=1),
|
||||
legacyLog.textFromEventDict
|
||||
)
|
||||
self.assertEqual(self.events[0]["log_level"], LogLevel.critical)
|
||||
|
||||
|
||||
def test_stdlibLogLevel(self):
|
||||
"""
|
||||
If the old-style C{"logLevel"} key is set to a standard library logging
|
||||
level, using a predefined (L{int}) constant, the new-style
|
||||
C{"log_level"} key should get set to the corresponding log level.
|
||||
"""
|
||||
publishToNewObserver(
|
||||
self.observer,
|
||||
self.legacyEvent(logLevel=py_logging.WARNING),
|
||||
legacyLog.textFromEventDict
|
||||
)
|
||||
self.assertEqual(self.events[0]["log_level"], LogLevel.warn)
|
||||
|
||||
|
||||
def test_stdlibLogLevelWithString(self):
|
||||
"""
|
||||
If the old-style C{"logLevel"} key is set to a standard library logging
|
||||
level, using a string value, the new-style C{"log_level"} key should
|
||||
get set to the corresponding log level.
|
||||
"""
|
||||
publishToNewObserver(
|
||||
self.observer,
|
||||
self.legacyEvent(logLevel="WARNING"),
|
||||
legacyLog.textFromEventDict
|
||||
)
|
||||
self.assertEqual(self.events[0]["log_level"], LogLevel.warn)
|
||||
|
||||
|
||||
def test_stdlibLogLevelWithGarbage(self):
|
||||
"""
|
||||
If the old-style C{"logLevel"} key is set to a standard library logging
|
||||
level, using an unknown value, the new-style C{"log_level"} key should
|
||||
not get set.
|
||||
"""
|
||||
publishToNewObserver(
|
||||
self.observer,
|
||||
self.legacyEvent(logLevel="Foo!!!!!"),
|
||||
legacyLog.textFromEventDict
|
||||
)
|
||||
self.assertNotIn("log_level", self.events[0])
|
||||
|
||||
|
||||
def test_defaultNamespace(self):
|
||||
"""
|
||||
Published event should have a namespace of C{"log_legacy"} to indicate
|
||||
that it was forwarded from legacy logging.
|
||||
"""
|
||||
publishToNewObserver(
|
||||
self.observer, self.legacyEvent(), legacyLog.textFromEventDict
|
||||
)
|
||||
self.assertEqual(self.events[0]["log_namespace"], "log_legacy")
|
||||
|
||||
|
||||
def test_system(self):
|
||||
"""
|
||||
The old-style C{"system"} key is copied to the new-style
|
||||
C{"log_system"} key.
|
||||
"""
|
||||
publishToNewObserver(
|
||||
self.observer, self.legacyEvent(), legacyLog.textFromEventDict
|
||||
)
|
||||
self.assertEqual(
|
||||
self.events[0]["log_system"], self.events[0]["system"]
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue