Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 5e3ca12

Browse files
authored
Create a mechanism for marking tests "logcontext clean" (#8399)
1 parent bd715e1 commit 5e3ca12

File tree

4 files changed

+41
-21
lines changed

4 files changed

+41
-21
lines changed

changelog.d/8399.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Create a mechanism for marking tests "logcontext clean".

synapse/logging/context.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ def get_thread_resource_usage() -> "Optional[resource._RUsage]":
6565
return None
6666

6767

68+
# a hook which can be set during testing to assert that we aren't abusing logcontexts.
69+
def logcontext_error(msg: str):
70+
logger.warning(msg)
71+
72+
6873
# get an id for the current thread.
6974
#
7075
# threading.get_ident doesn't actually return an OS-level tid, and annoyingly,
@@ -330,10 +335,9 @@ def __enter__(self) -> "LoggingContext":
330335
"""Enters this logging context into thread local storage"""
331336
old_context = set_current_context(self)
332337
if self.previous_context != old_context:
333-
logger.warning(
334-
"Expected previous context %r, found %r",
335-
self.previous_context,
336-
old_context,
338+
logcontext_error(
339+
"Expected previous context %r, found %r"
340+
% (self.previous_context, old_context,)
337341
)
338342
return self
339343

@@ -346,10 +350,10 @@ def __exit__(self, type, value, traceback) -> None:
346350
current = set_current_context(self.previous_context)
347351
if current is not self:
348352
if current is SENTINEL_CONTEXT:
349-
logger.warning("Expected logging context %s was lost", self)
353+
logcontext_error("Expected logging context %s was lost" % (self,))
350354
else:
351-
logger.warning(
352-
"Expected logging context %s but found %s", self, current
355+
logcontext_error(
356+
"Expected logging context %s but found %s" % (self, current)
353357
)
354358

355359
# the fact that we are here suggests that the caller thinks that everything
@@ -387,16 +391,16 @@ def start(self, rusage: "Optional[resource._RUsage]") -> None:
387391
support getrusuage.
388392
"""
389393
if get_thread_id() != self.main_thread:
390-
logger.warning("Started logcontext %s on different thread", self)
394+
logcontext_error("Started logcontext %s on different thread" % (self,))
391395
return
392396

393397
if self.finished:
394-
logger.warning("Re-starting finished log context %s", self)
398+
logcontext_error("Re-starting finished log context %s" % (self,))
395399

396400
# If we haven't already started record the thread resource usage so
397401
# far
398402
if self.usage_start:
399-
logger.warning("Re-starting already-active log context %s", self)
403+
logcontext_error("Re-starting already-active log context %s" % (self,))
400404
else:
401405
self.usage_start = rusage
402406

@@ -414,17 +418,17 @@ def stop(self, rusage: "Optional[resource._RUsage]") -> None:
414418

415419
try:
416420
if get_thread_id() != self.main_thread:
417-
logger.warning("Stopped logcontext %s on different thread", self)
421+
logcontext_error("Stopped logcontext %s on different thread" % (self,))
418422
return
419423

420424
if not rusage:
421425
return
422426

423427
# Record the cpu used since we started
424428
if not self.usage_start:
425-
logger.warning(
426-
"Called stop on logcontext %s without recording a start rusage",
427-
self,
429+
logcontext_error(
430+
"Called stop on logcontext %s without recording a start rusage"
431+
% (self,)
428432
)
429433
return
430434

@@ -584,14 +588,13 @@ def __exit__(self, type, value, traceback) -> None:
584588

585589
if context != self._new_context:
586590
if not context:
587-
logger.warning(
588-
"Expected logging context %s was lost", self._new_context
591+
logcontext_error(
592+
"Expected logging context %s was lost" % (self._new_context,)
589593
)
590594
else:
591-
logger.warning(
592-
"Expected logging context %s but found %s",
593-
self._new_context,
594-
context,
595+
logcontext_error(
596+
"Expected logging context %s but found %s"
597+
% (self._new_context, context,)
595598
)
596599

597600

tests/crypto/test_keyring.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
from tests import unittest
4343
from tests.test_utils import make_awaitable
44+
from tests.unittest import logcontext_clean
4445

4546

4647
class MockPerspectiveServer:
@@ -67,6 +68,7 @@ def sign_response(self, res):
6768
signedjson.sign.sign_json(res, self.server_name, self.key)
6869

6970

71+
@logcontext_clean
7072
class KeyringTestCase(unittest.HomeserverTestCase):
7173
def check_context(self, val, expected):
7274
self.assertEquals(getattr(current_context(), "request", None), expected)
@@ -309,6 +311,7 @@ async def get_keys2(keys_to_fetch):
309311
mock_fetcher2.get_keys.assert_called_once()
310312

311313

314+
@logcontext_clean
312315
class ServerKeyFetcherTestCase(unittest.HomeserverTestCase):
313316
def make_homeserver(self, reactor, clock):
314317
self.http_client = Mock()

tests/unittest.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import time
2424
from typing import Optional, Tuple, Type, TypeVar, Union
2525

26-
from mock import Mock
26+
from mock import Mock, patch
2727

2828
from canonicaljson import json
2929

@@ -169,6 +169,19 @@ def INFO(target):
169169
return target
170170

171171

172+
def logcontext_clean(target):
173+
"""A decorator which marks the TestCase or method as 'logcontext_clean'
174+
175+
... ie, any logcontext errors should cause a test failure
176+
"""
177+
178+
def logcontext_error(msg):
179+
raise AssertionError("logcontext error: %s" % (msg))
180+
181+
patcher = patch("synapse.logging.context.logcontext_error", new=logcontext_error)
182+
return patcher(target)
183+
184+
172185
class HomeserverTestCase(TestCase):
173186
"""
174187
A base TestCase that reduces boilerplate for HomeServer-using test cases.

0 commit comments

Comments
 (0)