def _test_memory_ignore(ignore): r = recorder.Recorder() # Start a stack collector so it allocates memory with stack.StackCollector(r): r = recorder.Recorder() c = memory.MemoryCollector(r, ignore_profiler=ignore, capture_pct=100) while not r.events[memory.MemorySampleEvent]: c.collect() _ = _alloc() events = r.events[memory.MemorySampleEvent] files = { frame.filename for event in events for trace in event.snapshot.traces for frame in trace.traceback } return files
def test_thread_name(): r = recorder.Recorder() exp = exporter.NullExporter() s = scheduler.Scheduler(r, [exp]) s.start() assert s._periodic.name == "ddtrace.profile.scheduler:Scheduler" s.stop()
def _build_default_collectors(): r = recorder.Recorder() return [ stack.StackCollector(r), memory.MemoryCollector(r), exceptions.UncaughtExceptionCollector(r), threading.LockCollector(r), ]
def test_filter(): r = recorder.Recorder() def filter_all(events): return [] r.add_event_filter(event.Event, filter_all) r.push_event(event.Event()) assert len(r.events[event.Event]) == 0
def test_filter_contents(): r = recorder.Recorder() def filter_one_on_two(events): return [event for i, event in enumerate(events) if i % 2 == 0] r.add_event_filter(event.Event, filter_one_on_two) r.push_events([event.Event(), event.Event(), event.Event()]) assert len(r.events[event.Event]) == 2
def test_reset(): r = recorder.Recorder() r.push_event(event.Event()) assert len(r.events[event.Event]) == 1 assert len(r.reset()[event.Event]) == 1 assert len(r.events[event.Event]) == 0 assert len(r.reset()[event.Event]) == 0 r.push_event(event.Event()) assert len(r.events[event.Event]) == 1 assert len(r.reset()[event.Event]) == 1
def test_no_override(): r = recorder.Recorder() c = exceptions.UncaughtExceptionCollector(r) c.start() sys.excepthook(ValueError, ValueError(), None) c.stop() sys.excepthook(ValueError, ValueError(), None) events = r.events[exceptions.UncaughtExceptionEvent] assert len(events) == 1 _check_event(events[0])
def test_dynamic_interval(): r = recorder.Recorder() c = collector.PeriodicCollector(recorder=r, interval=1) c.start() assert c.interval == 1 assert c._worker.interval == c.interval c.interval = 2 assert c.interval == 2 assert c._worker.interval == c.interval c.stop()
def test_patch(): r = recorder.Recorder() lock = threading.Lock collector = collector_threading.LockCollector(r) collector.start() assert lock == collector.original # wrapt makes this true assert lock == threading.Lock collector.stop() assert lock == threading.Lock assert collector.original == threading.Lock
def _test_collector_status(collector_class): r = recorder.Recorder() c = collector_class(r) assert c.status == collector.CollectorStatus.STOPPED with mock.patch("ddtrace.profile._compat.time_ns") as time_ns: time_ns.return_value = 123 c.start() assert c.status == collector.CollectorStatus.RUNNING c.stop() assert c.status == collector.CollectorStatus.STOPPED return r, c
def test_collect_truncate(): r = recorder.Recorder() c = stack.StackCollector(r, nframes=5) c.start() func1() while not r.events[stack.StackSampleEvent]: pass c.stop() e = r.events[stack.StackSampleEvent][0] assert e.nframes > c.nframes assert len(e.frames) == c.nframes
def test_new_interval(): r = recorder.Recorder() c = stack.StackCollector(r) new_interval = c._compute_new_interval(1000000) assert new_interval == 0.049 new_interval = c._compute_new_interval(2000000) assert new_interval == 0.098 c = stack.StackCollector(r, max_time_usage_pct=10) new_interval = c._compute_new_interval(200000) assert new_interval == 0.01 new_interval = c._compute_new_interval(1) assert new_interval == c.MIN_INTERVAL_TIME
def _test_collector_collect(collector, event_type, fn=None, **kwargs): r = recorder.Recorder() c = collector(r, **kwargs) c.start() thread_id = c._worker.ident while not r.events[event_type]: if fn is not None: _ = fn() # Sleep so gevent can switch to the other thread time.sleep(0) c.stop() assert len(r.events[event_type]) >= 1 return r, c, thread_id
def test_collect_once(): r = recorder.Recorder() s = stack.StackCollector(r) s._init() all_events = s._collect() assert len(all_events) == 2 e = all_events[0][0] assert e.thread_id > 0 # Thread name is None with gevent assert isinstance(e.thread_name, (str, type(None))) assert len(e.frames) > 1 assert e.frames[0][0].endswith(".py") assert e.frames[0][1] > 0 assert isinstance(e.frames[0][2], str)
def test_stress_threads(): NB_THREADS = 20 threads = [] for i in range(NB_THREADS): t = threading.Thread(target=_f0) # noqa: E149,F821 t.start() threads.append(t) s = stack.StackCollector(recorder=recorder.Recorder()) s._init() number = 10000 exectime = timeit.timeit(s.collect, number=number) print("%.3f ms per call" % (1000.0 * exectime / number)) for t in threads: t.join()
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:41" assert event.thread_id == _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__, 42, "test_lock_acquire_events") assert event.sampling_pct == 100
def test_with_override(): seen = {"seen": False} def myhook(exctype, value, traceback): seen["seen"] = True sys.excepthook = myhook r = recorder.Recorder() c = exceptions.UncaughtExceptionCollector(r) c.start() sys.excepthook(ValueError, ValueError(), None) c.stop() assert seen["seen"] seen["seen"] = False sys.excepthook(ValueError, ValueError(), None) assert seen["seen"] events = r.events[exceptions.UncaughtExceptionEvent] assert len(events) == 1 _check_event(events[0])
def test_exception_collection(): r = recorder.Recorder() c = stack.StackCollector(r) c.start() try: raise ValueError("hello") except Exception: sleep(1) c.stop() exception_events = r.events[stack.StackExceptionSampleEvent] assert len(exception_events) >= 1 e = exception_events[0] assert e.timestamp > 0 assert e.sampling_period > 0 if not TESTING_GEVENT: assert e.thread_id == _thread.get_ident() assert e.thread_name == "MainThread" assert e.frames == [(__file__, 205, "test_exception_collection")] assert e.nframes == 1 assert e.exc_type == ValueError
def test_thread_name(): r = recorder.Recorder() c = collector.PeriodicCollector(recorder=r, interval=1) c.start() assert c._worker.name == "ddtrace.profile.collector:PeriodicCollector" c.stop()
def _test_repr(collector_class, s): r = recorder.Recorder() assert repr(collector_class(r)) == s
def test_lock_acquire_release_speed_patched(benchmark, pct): r = recorder.Recorder() with collector_threading.LockCollector(r, capture_pct=pct): benchmark(_lock_acquire_release, threading.Lock())
def test_lock_create_speed_patched(benchmark): r = recorder.Recorder() with collector_threading.LockCollector(r): benchmark(threading.Lock)
def test_max_time_usage_over(): r = recorder.Recorder() with pytest.raises(ValueError): stack.StackCollector(r, max_time_usage_pct=200)
def test_memory_alloc_speed_patched(benchmark, pct): r = recorder.Recorder() with memory.MemoryCollector(r, capture_pct=pct): benchmark(_alloc)
def test_max_capture_over(): r = recorder.Recorder() with pytest.raises(ValueError): memory.MemoryCollector(r, capture_pct=200)
def test_collect(): r = recorder.Recorder() c = exceptions.UncaughtExceptionCollector(r) c.start() c.stop()
def test_exporter_failure(): r = recorder.Recorder() exp = _FailExporter() s = scheduler.Scheduler(r, [exp]) r.push_events([event.Event()] * 10) s.flush()
def test_push_events_empty(): r = recorder.Recorder() r.push_events([]) assert len(r.events[event.Event]) == 0