123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- # Copyright (c) Twisted Matrix Laboratories.
- # See LICENSE for details.
- """
- Test cases for L{twisted.logger._observer}.
- """
- from zope.interface.verify import verifyObject, BrokenMethodImplementation
- from twisted.trial import unittest
- from .._logger import Logger
- from .._observer import ILogObserver
- from .._observer import LogPublisher
- class LogPublisherTests(unittest.TestCase):
- """
- Tests for L{LogPublisher}.
- """
- def test_interface(self):
- """
- L{LogPublisher} is an L{ILogObserver}.
- """
- publisher = LogPublisher()
- try:
- verifyObject(ILogObserver, publisher)
- except BrokenMethodImplementation as e:
- self.fail(e)
- def test_observers(self):
- """
- L{LogPublisher.observers} returns the observers.
- """
- o1 = lambda e: None
- o2 = lambda e: None
- publisher = LogPublisher(o1, o2)
- self.assertEqual(set((o1, o2)), set(publisher._observers))
- def test_addObserver(self):
- """
- L{LogPublisher.addObserver} adds an observer.
- """
- o1 = lambda e: None
- o2 = lambda e: None
- o3 = lambda e: None
- publisher = LogPublisher(o1, o2)
- publisher.addObserver(o3)
- self.assertEqual(set((o1, o2, o3)), set(publisher._observers))
- def test_addObserverNotCallable(self):
- """
- L{LogPublisher.addObserver} refuses to add an observer that's
- not callable.
- """
- publisher = LogPublisher()
- self.assertRaises(TypeError, publisher.addObserver, object())
- def test_removeObserver(self):
- """
- L{LogPublisher.removeObserver} removes an observer.
- """
- o1 = lambda e: None
- o2 = lambda e: None
- o3 = lambda e: None
- publisher = LogPublisher(o1, o2, o3)
- publisher.removeObserver(o2)
- self.assertEqual(set((o1, o3)), set(publisher._observers))
- def test_removeObserverNotRegistered(self):
- """
- L{LogPublisher.removeObserver} removes an observer that is not
- registered.
- """
- o1 = lambda e: None
- o2 = lambda e: None
- o3 = lambda e: None
- publisher = LogPublisher(o1, o2)
- publisher.removeObserver(o3)
- self.assertEqual(set((o1, o2)), set(publisher._observers))
- def test_fanOut(self):
- """
- L{LogPublisher} calls its observers.
- """
- event = dict(foo=1, bar=2)
- events1 = []
- events2 = []
- events3 = []
- o1 = lambda e: events1.append(e)
- o2 = lambda e: events2.append(e)
- o3 = lambda e: events3.append(e)
- publisher = LogPublisher(o1, o2, o3)
- publisher(event)
- self.assertIn(event, events1)
- self.assertIn(event, events2)
- self.assertIn(event, events3)
- def test_observerRaises(self):
- """
- Observer raises an exception during fan out: a failure is logged, but
- not re-raised. Life goes on.
- """
- event = dict(foo=1, bar=2)
- exception = RuntimeError("ARGH! EVIL DEATH!")
- events = []
- def observer(event):
- shouldRaise = not events
- events.append(event)
- if shouldRaise:
- raise exception
- collector = []
- publisher = LogPublisher(observer, collector.append)
- publisher(event)
- # Verify that the observer saw my event
- self.assertIn(event, events)
- # Verify that the observer raised my exception
- errors = [
- e["log_failure"] for e in collector
- if "log_failure" in e
- ]
- self.assertEqual(len(errors), 1)
- self.assertIs(errors[0].value, exception)
- # Make sure the exceptional observer does not receive its own error.
- self.assertEqual(len(events), 1)
- def test_observerRaisesAndLoggerHatesMe(self):
- """
- Observer raises an exception during fan out and the publisher's Logger
- pukes when the failure is reported. The exception does not propagate
- back to the caller.
- """
- event = dict(foo=1, bar=2)
- exception = RuntimeError("ARGH! EVIL DEATH!")
- def observer(event):
- raise RuntimeError("Sad panda")
- class GurkLogger(Logger):
- def failure(self, *args, **kwargs):
- raise exception
- publisher = LogPublisher(observer)
- publisher.log = GurkLogger()
- publisher(event)
- # Here, the lack of an exception thus far is a success, of sorts
- def test_trace(self):
- """
- Tracing keeps track of forwarding to observers.
- """
- event = dict(foo=1, bar=2, log_trace=[])
- traces = {}
- # Copy trace to a tuple; otherwise, both observers will store the same
- # mutable list, and we won't be able to see o1's view distinctly.
- o1 = lambda e: traces.setdefault(1, tuple(e["log_trace"]))
- o2 = lambda e: traces.setdefault(2, tuple(e["log_trace"]))
- publisher = LogPublisher(o1, o2)
- publisher(event)
- self.assertEqual(traces[1], ((publisher, o1),))
- self.assertEqual(traces[2], ((publisher, o1), (publisher, o2)))
|