Skip to content

Commit 118b4c3

Browse files
authored
test(symdb): add fork behaviour test (#15079)
## Description We add a test to the Symbol DB test to ensure that we have the expected fork behaviour. By design, we want only the main process and the first fork child to emit Symbol DB payloads.
1 parent 191f10e commit 118b4c3

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

ddtrace/internal/symbol_db/remoteconfig.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
log = get_logger(__name__)
2020

2121

22-
def _rc_callback(data: t.List[Payload], test_tracer=None):
22+
def _rc_callback(data: t.Sequence[Payload]):
2323
if get_ancestor_runtime_id() is not None and has_forked():
2424
log.debug("[PID %d] SymDB: Disabling Symbol DB in forked process", os.getpid())
2525
# We assume that forking is being used for spawning child worker

tests/internal/symbol_db/test_symbols.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,3 +286,37 @@ def get_scope(contexts, name):
286286
scope = get_scope(contexts, "tests.submod.stuff")
287287
assert scope["scope_type"] == ScopeType.MODULE
288288
assert scope["name"] == "tests.submod.stuff"
289+
290+
291+
@pytest.mark.subprocess(ddtrace_run=True, err=None)
292+
def test_symbols_fork_uploads():
293+
"""
294+
Test that we disable Symbol DB on processes that are not the main one nor
295+
the first fork child.
296+
"""
297+
import os
298+
299+
from ddtrace.internal import forksafe
300+
from ddtrace.internal.remoteconfig import ConfigMetadata
301+
from ddtrace.internal.remoteconfig import Payload
302+
from ddtrace.internal.runtime import get_ancestor_runtime_id
303+
from ddtrace.internal.symbol_db.remoteconfig import _rc_callback
304+
from ddtrace.internal.symbol_db.symbols import SymbolDatabaseUploader
305+
306+
SymbolDatabaseUploader.install()
307+
308+
pids = []
309+
rc_data = [Payload(ConfigMetadata("test", "symdb", "hash", 0, 0), "test", None)]
310+
311+
for _ in range(10):
312+
if not (pid := os.fork()):
313+
_rc_callback(rc_data)
314+
assert SymbolDatabaseUploader.is_installed() != (
315+
get_ancestor_runtime_id() is not None and forksafe.has_forked()
316+
)
317+
os._exit(0)
318+
319+
pids.append(pid)
320+
321+
for pid in pids:
322+
os.waitpid(pid, 0)

0 commit comments

Comments
 (0)