def test_thread_to_child_span_clear(tracer_and_collector): t, c = tracer_and_collector root = t.start_span("root", activate=True) thread_id = nogevent.thread_get_ident() assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == root c._thread_span_links.clear_threads(set()) assert c._thread_span_links.get_active_span_from_thread_id(thread_id) is None
def test_thread_to_span_thread_isolation(tracer_and_collector): t, c = tracer_and_collector root = t.start_span("root", activate=True) thread_id = nogevent.thread_get_ident() assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == root quit_thread = threading.Event() span_started = threading.Event() store = {} def start_span(): store["span2"] = t.start_span("thread2", activate=True) span_started.set() quit_thread.wait() th = threading.Thread(target=start_span) th.start() span_started.wait() if TESTING_GEVENT: # We track *real* threads, gevent is using only one in this case assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == store["span2"] assert c._thread_span_links.get_active_span_from_thread_id(th.ident) is None else: assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == root assert c._thread_span_links.get_active_span_from_thread_id(th.ident) == store["span2"] # Do not quit the thread before we test, otherwise the collector might clean up the thread from the list of spans quit_thread.set() th.join()
def test_thread_to_child_span_clear(tracer_and_collector): t, c = tracer_and_collector root = t.start_span("root") thread_id = nogevent.thread_get_ident() assert c._thread_span_links.get_active_leaf_spans_from_thread_id( thread_id) == {root} c._thread_span_links.clear_threads(set()) assert c._thread_span_links.get_active_leaf_spans_from_thread_id( thread_id) == set()
def test_thread_to_span_multiple(tracer_and_collector): t, c = tracer_and_collector root = t.start_span("root", activate=True) thread_id = nogevent.thread_get_ident() assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == root subspan = t.start_span("subtrace", child_of=root, activate=True) assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == subspan subspan.finish() assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == root root.finish() assert c._thread_span_links.get_active_span_from_thread_id(thread_id) is None
def test_thread_to_child_span_multiple_more_children(tracer_and_collector): t, c = tracer_and_collector root = t.start_span("root", activate=True) thread_id = nogevent.thread_get_ident() assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == root subspan = t.start_span("subtrace", child_of=root, activate=True) subsubspan = t.start_span("subsubtrace", child_of=subspan, activate=True) assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == subsubspan subsubspan2 = t.start_span("subsubtrace2", child_of=subspan, activate=True) assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == subsubspan2 # ⚠ subspan is not supposed to finish before its children, but the API authorizes it subspan.finish() assert c._thread_span_links.get_active_span_from_thread_id(thread_id) == subsubspan2
def test_thread_to_span_multiple(tracer_and_collector): t, c = tracer_and_collector root = t.start_span("root") thread_id = nogevent.thread_get_ident() assert c._thread_span_links.get_active_leaf_spans_from_thread_id( thread_id) == {root} subspan = t.start_span("subtrace", child_of=root) assert c._thread_span_links.get_active_leaf_spans_from_thread_id( thread_id) == {subspan} subspan.finish() assert c._thread_span_links.get_active_leaf_spans_from_thread_id( thread_id) == {root} root.finish() assert c._thread_span_links.get_active_leaf_spans_from_thread_id( thread_id) == set()
def test_lock_acquire_events(): r = recorder.Recorder() with collector_threading.LockCollector(r, capture_pct=100): lock = threading.Lock() lock.acquire() assert len(r.events[collector_threading.LockAcquireEvent]) == 1 assert len(r.events[collector_threading.LockReleaseEvent]) == 0 event = r.events[collector_threading.LockAcquireEvent][0] assert event.lock_name == "test_threading.py:64" assert event.thread_id == nogevent.thread_get_ident() assert event.wait_time_ns > 0 # It's called through pytest so I'm sure it's gonna be that long, right? assert len(event.frames) > 3 assert event.nframes > 3 assert event.frames[0] == (__file__, 65, "test_lock_acquire_events") assert event.sampling_pct == 100
def test_thread_to_child_span_multiple_more_children(tracer_and_collector): t, c = tracer_and_collector root = t.start_span("root") thread_id = nogevent.thread_get_ident() assert c._thread_span_links.get_active_leaf_spans_from_thread_id( thread_id) == {root} subspan = t.start_span("subtrace", child_of=root) subsubspan = t.start_span("subsubtrace", child_of=subspan) assert c._thread_span_links.get_active_leaf_spans_from_thread_id( thread_id) == {subsubspan} subsubspan2 = t.start_span("subsubtrace2", child_of=subspan) assert c._thread_span_links.get_active_leaf_spans_from_thread_id( thread_id) == {subsubspan, subsubspan2} # Рџа subspan is not supposed to finish before its children, but the API authorizes it # In that case, we would return also the root span as it's becoming a parent without children Ъци subspan.finish() assert c._thread_span_links.get_active_leaf_spans_from_thread_id( thread_id) == {root, subsubspan, subsubspan2}
def test_exception_collection(): r = recorder.Recorder() c = stack.StackCollector(r) with c: try: raise ValueError("hello") except Exception: nogevent.sleep(1) exception_events = r.events[stack.StackExceptionSampleEvent] assert len(exception_events) >= 1 e = exception_events[0] assert e.timestamp > 0 assert e.sampling_period > 0 assert e.thread_id == nogevent.thread_get_ident() assert e.thread_name == "MainThread" assert e.frames == [(__file__, 321, "test_exception_collection")] assert e.nframes == 1 assert e.exc_type == ValueError
def test_exception_collection_trace(tracer): r = recorder.Recorder() c = stack.StackCollector(r, tracer=tracer) with c: with tracer.trace("test123") as span: try: raise ValueError("hello") except Exception: nogevent.sleep(1) exception_events = r.events[stack.StackExceptionSampleEvent] assert len(exception_events) >= 1 e = exception_events[0] assert e.timestamp > 0 assert e.sampling_period > 0 assert e.thread_id == nogevent.thread_get_ident() assert e.thread_name == "MainThread" assert e.frames == [(__file__, 344, "test_exception_collection_trace")] assert e.nframes == 1 assert e.exc_type == ValueError assert e.span_id == span.span_id assert e.trace_id == span.trace_id
def _current_thread(): # type: (...) -> typing.Tuple[int, str] thread_id = nogevent.thread_get_ident() return thread_id, _threading.get_thread_name(thread_id)