fix(quality): make the test doubles legal raises and hashes
The fake queue no longer raises an attribute that starts as None. The oversized kind records hashes instead of raising from __hash__, which also catches a hash that production code swallows. Hostile.__bool__ raises the TypeError a truth test may raise.
This commit is contained in:
@@ -31,6 +31,20 @@ def message(kind, job_id=JOB, **fields):
|
||||
return (kind, {"prompt_id": job_id, **fields})
|
||||
|
||||
|
||||
def hash_recording_kind():
|
||||
"""A str subclass for event kinds, and the list of hashes taken of it."""
|
||||
hashed = []
|
||||
|
||||
class OversizedKind(str):
|
||||
__eq__ = str.__eq__
|
||||
|
||||
def __hash__(self):
|
||||
hashed.append(len(self))
|
||||
return str.__hash__(self)
|
||||
|
||||
return OversizedKind, hashed
|
||||
|
||||
|
||||
def finish(messages, completed=True):
|
||||
return make_finish(SESSION, 0, EPOCH, Status("success", completed, messages), 500)
|
||||
|
||||
@@ -346,13 +360,10 @@ class ExecutionHistoryEventsTests(unittest.TestCase):
|
||||
self.assertLessEqual(len(encode_command(command)), 2048)
|
||||
|
||||
def test_oversized_unknown_kind_is_ignored_without_hashing(self):
|
||||
class OversizedKind(str):
|
||||
def __hash__(self):
|
||||
raise AssertionError("Oversized event kind must not be hashed")
|
||||
|
||||
kind_class, hashed = hash_recording_kind()
|
||||
command = finish(
|
||||
[
|
||||
message(OversizedKind("x" * 1_000_000)),
|
||||
message(kind_class("x" * 1_000_000)),
|
||||
message("execution_success", timestamp=300),
|
||||
]
|
||||
)
|
||||
@@ -361,19 +372,16 @@ class ExecutionHistoryEventsTests(unittest.TestCase):
|
||||
(result.outcome, result.reason), ("succeeded", "terminal_success")
|
||||
)
|
||||
self.assertLessEqual(len(encode_command(command)), 2048)
|
||||
self.assertEqual(hashed, [], "Oversized event kind must not be hashed")
|
||||
|
||||
def test_encoder_rejects_oversized_kind_without_hashing(self):
|
||||
class OversizedKind(str):
|
||||
def __hash__(self):
|
||||
raise AssertionError("Oversized event kind must not be hashed")
|
||||
|
||||
kind_class, hashed = hash_recording_kind()
|
||||
command = finish([message("execution_success")])
|
||||
event = LifecycleEvent(
|
||||
OversizedKind("x" * 1_000_000), JOB, None, None, None, None
|
||||
)
|
||||
event = LifecycleEvent(kind_class("x" * 1_000_000), JOB, None, None, None, None)
|
||||
with self.assertRaises(ValueError):
|
||||
encode_command(
|
||||
replace(
|
||||
command, evidence=TerminalEvidence((event,), False, False, False)
|
||||
)
|
||||
)
|
||||
self.assertEqual(hashed, [], "Oversized event kind must not be hashed")
|
||||
|
||||
@@ -17,7 +17,7 @@ class Hostile:
|
||||
raise AssertionError("host scalar coercion")
|
||||
|
||||
def __bool__(self):
|
||||
raise AssertionError("host truth test")
|
||||
raise TypeError("host truth test")
|
||||
|
||||
def __eq__(self, other):
|
||||
raise AssertionError("host equality")
|
||||
|
||||
@@ -347,7 +347,7 @@ class CaptureStoreTestCase(unittest.TestCase):
|
||||
with patch.object(CaptureStore, "_read", rewriting):
|
||||
try:
|
||||
cap = store.capture(self.root, "a.png", epoch=EPOCH, scope=SCOPE)
|
||||
except CaptureChanged:
|
||||
except capture_module.CaptureChanged:
|
||||
detected = True
|
||||
else:
|
||||
detected = False
|
||||
|
||||
@@ -13,19 +13,19 @@ class FakeQueue:
|
||||
def __init__(self):
|
||||
self.result = ((0, "job", {}, {}, [], {}), 0)
|
||||
self.calls = []
|
||||
self.failure = None
|
||||
self.failures = ()
|
||||
self.done_result = object()
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
self.calls.append(("get", args, kwargs))
|
||||
if self.failure:
|
||||
raise self.failure
|
||||
for failure in self.failures:
|
||||
raise failure
|
||||
return self.result
|
||||
|
||||
def task_done(self, *args, **kwargs):
|
||||
self.calls.append(("done", args, kwargs))
|
||||
if self.failure:
|
||||
raise self.failure
|
||||
for failure in self.failures:
|
||||
raise failure
|
||||
return self.done_result
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class QueueObserversTests(unittest.TestCase):
|
||||
self.assertIsNone(host.get())
|
||||
self.assertEqual(seen, [original])
|
||||
for error in (queue.Empty(), RuntimeError("host failure")):
|
||||
host.failure = error
|
||||
host.failures = (error,)
|
||||
with self.assertRaises(type(error)) as raised:
|
||||
host.get(timeout=sentinel)
|
||||
self.assertIs(raised.exception, error)
|
||||
@@ -59,7 +59,7 @@ class QueueObserversTests(unittest.TestCase):
|
||||
self.assertIs(host.task_done(0, sentinel, status=sentinel), host.done_result)
|
||||
self.assertEqual(seen, [((0, sentinel), {"status": sentinel})])
|
||||
error = ValueError("host failure")
|
||||
host.failure = error
|
||||
host.failures = (error,)
|
||||
with self.assertRaises(ValueError) as raised:
|
||||
host.task_done(1)
|
||||
self.assertIs(raised.exception, error)
|
||||
|
||||
Reference in New Issue
Block a user