@@ -242,10 +242,8 @@ def __init__(self, test_class):
242242 self ._entities : dict [str , Any ] = {}
243243 self ._listeners : dict [str , EventListenerUtil ] = {}
244244 self ._session_lsids : dict [str , Mapping [str , Any ]] = {}
245- # The id of the (at most one, today) client entity created with
246- # observeTracingMessages. Spans carry no attribute identifying which
247- # client emitted them, so multi-client tracing correlation isn't
248- # supported; _create_entity fails loudly if a second one appears.
245+ # The one client entity created with observeTracingMessages. Spans carry
246+ # no attribute identifying their client, so a second one is rejected.
249247 self ._tracing_client_id : Optional [str ] = None
250248 self .test : UnifiedSpecTestMixinV1 = test_class
251249
@@ -341,9 +339,7 @@ async def _create_entity(self, entity_spec, uri=None):
341339 enable_payload = observe_tracing .get ("enableCommandPayload" , False )
342340 kwargs ["tracing" ] = {
343341 "enabled" : True ,
344- # Tests asserting db.query.text match the full, untruncated
345- # command, so an effectively-unlimited length avoids
346- # truncating and failing that assertion.
342+ # Tests match the full command, so never truncate.
347343 "query_text_max_length" : 1_000_000 if enable_payload else None ,
348344 }
349345
@@ -564,10 +560,8 @@ async def insert_initial_data(self, initial_data):
564560
565561 @classmethod
566562 def setUpClass (cls ) -> None :
567- # Only register a span exporter (and the shared SDK TracerProvider it
568- # depends on) for test files that actually use observeTracingMessages,
569- # to avoid needlessly accumulating span processors on the process-wide
570- # provider for the (vast majority of) unified-format suites that don't.
563+ # Only for test files that use observeTracingMessages: span processors
564+ # accumulate on the process-wide provider and can never be removed.
571565 cls ._tracing_exporter = None
572566 uses_tracing = any (
573567 "observeTracingMessages" in entity .get ("client" , {})
@@ -593,12 +587,8 @@ def setUpClass(cls) -> None:
593587 @classmethod
594588 def tearDownClass (cls ) -> None :
595589 cls .knobs .disable ()
596- # The exporter's span processor can never be removed from the shared process-wide
597- # TracerProvider (see _shared_test_provider), so without this, every span emitted by any
598- # client anywhere in the process for the rest of the test run keeps getting appended to this
599- # (otherwise dead) class's exporter: an unbounded memory leak across a full test run, and
600- # needless per-span export overhead for every other tracing-enabled test class that runs
601- # afterwards. shutdown() makes further export() calls into this exporter no-ops.
590+ # The span processor can never be removed from the shared process-wide
591+ # TracerProvider, so without this the exporter accumulates every span.
602592 if cls ._tracing_exporter is not None :
603593 cls ._tracing_exporter .shutdown ()
604594
@@ -639,9 +629,6 @@ def maybe_skip_test(self, spec):
639629 self .skipTest ("PyMongo does not support the symbol type" )
640630 if "timeoutms applied to entire download" in description :
641631 self .skipTest ("PyMongo's open_download_stream does not cap the stream's lifetime" )
642- # Removed API: PyMongo no longer exposes map_reduce/inline_map_reduce at
643- # all (mapReduce is deprecated server-side), so there's no code path left
644- # that could send this command; this operation can never be exercised.
645632 if class_name == "testoperationmapreduce" and description == "mapreduce" :
646633 self .skipTest (
647634 "PyMongo removed the map_reduce/inline_map_reduce Collection methods "
@@ -1535,9 +1522,8 @@ def format_logs(log_list):
15351522 self .match_evaluator .match_result (expected_msg , actual_msg )
15361523
15371524 async def check_tracing_messages (self , operations , spec ):
1538- # Like expectLogMessages/expectEvents, expectTracingMessages is a list of
1539- # per-client blocks (even though only one client with
1540- # observeTracingMessages is currently supported, see entity.py above).
1525+ # A list of per-client blocks, like expectLogMessages, though only one
1526+ # client with observeTracingMessages is supported.
15411527 exporter = self ._tracing_exporter
15421528 if exporter is None :
15431529 self .fail (
@@ -1548,23 +1534,17 @@ async def check_tracing_messages(self, operations, spec):
15481534 await self .run_operations (operations )
15491535 finished_spans = exporter .get_finished_spans ()
15501536
1551- # Reconstruct the parent/child span tree from the flat, finish-ordered
1552- # list the in-memory exporter records, keyed by each span's parent id.
1537+ # Rebuild the parent/child tree from the exporter's flat, finish-ordered list.
15531538 children_by_parent_id = defaultdict (list )
15541539 for span in finished_spans :
15551540 parent_id = span .parent .span_id if span .parent is not None else None
15561541 children_by_parent_id [parent_id ].append (span )
15571542
15581543 def check_span_list (expected_list , actual_list , ignore_extra_spans ):
15591544 if ignore_extra_spans :
1560- # Per the unified-test-format spec, "additional unexpected spans
1561- # are allowed". Unlike ignoreExtraEvents (which only tolerates
1562- # a trailing tail), spans from concurrent/out-of-band activity
1563- # (e.g. a testRunner-issued configureFailPoint command) can
1564- # finish interleaved anywhere among the expected ones, not just
1565- # at the end. Filter down to just the spans that line up (by
1566- # name, in order) with the expected list, dropping anything
1567- # else, instead of naively truncating the tail.
1545+ # Unlike ignoreExtraEvents, extra spans can finish interleaved
1546+ # anywhere rather than only at the end, so match by name in
1547+ # order instead of truncating the tail.
15681548 filtered = []
15691549 expected_iter = iter (expected_list )
15701550 current_expected = next (expected_iter , None )
0 commit comments