def test_fork(): _, _, exitcode, _ = call_program( "python", os.path.join(os.path.dirname(__file__), "fork_enable.py")) assert exitcode == 0 _, _, exitcode, _ = call_program( "python", os.path.join(os.path.dirname(__file__), "fork_disable.py")) assert exitcode == 0
def test_no_warnings(): env = os.environ.copy() # Have to disable sqlite3 as coverage uses it on process shutdown # which results in a trace being generated after the tracer shutdown # has been initiated which results in a deprecation warning. env["DD_TRACE_SQLITE3_ENABLED"] = "false" out, err, _, _ = call_program("ddtrace-run", sys.executable, "-Wall", "-c", "'import ddtrace'", env=env) assert out == b"", out # Wrapt is using features deprecated in Python 3.10 # See https://github.com/GrahamDumpleton/wrapt/issues/200 if sys.version_info < (3, 10, 0): assert err == b"", err else: # Assert that the only log lines in the output are import warnings lines = err.splitlines() assert len(lines) > 0, err for line in lines: assert line == ( b"<frozen importlib._bootstrap>:914: ImportWarning: " b"ImportHookFinder.find_spec() not found; falling back to find_module()" ), err
def test_fork(tmp_path, monkeypatch): filename = str(tmp_path / "pprof") monkeypatch.setenv("DD_PROFILING_API_TIMEOUT", "0.1") monkeypatch.setenv("DD_PROFILING_OUTPUT_PPROF", filename) monkeypatch.setenv("DD_PROFILING_CAPTURE_PCT", "100") stdout, stderr, exitcode, pid = call_program( "python", os.path.join(os.path.dirname(__file__), "simple_program_fork.py")) assert exitcode == 0 child_pid = stdout.decode().strip() utils.check_pprof_file(filename + "." + str(pid) + ".1") utils.check_pprof_file(filename + "." + str(child_pid) + ".1")
def test_call_script(monkeypatch): # Set a very short timeout to exit fast monkeypatch.setenv("DD_PROFILING_API_TIMEOUT", "0.1") monkeypatch.setenv("DD_PROFILING_ENABLED", "1") stdout, stderr, exitcode, pid = call_program( "ddtrace-run", os.path.join(os.path.dirname(__file__), "simple_program.py")) assert exitcode == 42 hello, interval, stacks = stdout.decode().strip().split("\n") assert hello == "hello world" assert float(interval) >= 0.01 assert int(stacks) >= 1
def test_no_warnings(): env = os.environ.copy() # Have to disable sqlite3 as coverage uses it on process shutdown # which results in a trace being generated after the tracer shutdown # has been initiated which results in a deprecation warning. env["DD_TRACE_SQLITE3_ENABLED"] = "false" out, err, status, pid = call_program("ddtrace-run", sys.executable, "-Wall", "-c", "'import ddtrace'", env=env) assert out == b"", out assert err == b"", err
def test_multiprocessing(method, tmp_path, monkeypatch): filename = str(tmp_path / "pprof") monkeypatch.setenv("DD_PROFILING_OUTPUT_PPROF", filename) monkeypatch.setenv("DD_PROFILING_ENABLED", "1") monkeypatch.setenv("DD_PROFILING_UPLOAD_INTERVAL", "0.1") stdout, stderr, exitcode, pid = call_program( "ddtrace-run", "python", os.path.join(os.path.dirname(__file__), "_test_multiprocessing.py"), method, ) assert exitcode == 0, (stdout, stderr) child_pid = stdout.decode().strip() utils.check_pprof_file(filename + "." + str(pid) + ".1") utils.check_pprof_file(filename + "." + str(child_pid) + ".1")
def test_call_script_pprof_output(tmp_path, monkeypatch): """This checks if the pprof output and atexit register work correctly. The script does not run for one minute, so if the `stop_on_exit` flag is broken, this test will fail. """ filename = str(tmp_path / "pprof") monkeypatch.setenv("DD_PROFILING_OUTPUT_PPROF", filename) monkeypatch.setenv("DD_PROFILING_CAPTURE_PCT", "1") monkeypatch.setenv("DD_PROFILING_ENABLED", "1") _, _, exitcode, pid = call_program( "ddtrace-run", os.path.join(os.path.dirname(__file__), "simple_program.py")) assert exitcode == 42 utils.check_pprof_file(filename + "." + str(pid) + ".1") return filename, pid
def _run(code, **kwargs): pyfile = tmpdir.join("test.py") pyfile.write(code) return call_program("ddtrace-run", sys.executable, str(pyfile), **kwargs)
def test_fork_gevent(monkeypatch): monkeypatch.setenv("DD_PROFILING_API_TIMEOUT", "0.1") stdout, stderr, exitcode, pid = call_program( "python", os.path.join(os.path.dirname(__file__), "gevent_fork.py")) assert exitcode == 0
def test_call_script_gevent(monkeypatch): monkeypatch.setenv("DD_PROFILING_API_TIMEOUT", "0.1") _, _, exitcode, pid = call_program( "python", os.path.join(os.path.dirname(__file__), "simple_program_gevent.py")) assert exitcode == 0
def test_fork(): stdout, stderr, exitcode, pid = call_program( "python", os.path.join(os.path.dirname(__file__), "recorder_fork.py")) assert exitcode == 0, (stdout, stderr)
def run_function_from_file(item, params=None): file, _, func = item.location marker = item.get_closest_marker("subprocess") file_index = 1 args = marker.kwargs.get("args", []) args.insert(0, None) args.insert(0, sys.executable) if marker.kwargs.get("ddtrace_run", False): file_index += 1 args.insert(0, "ddtrace-run") env = os.environ.copy() env.update(marker.kwargs.get("env", {})) if params is not None: env.update(params) expected_status = marker.kwargs.get("status", 0) expected_out = marker.kwargs.get("out", "") if expected_out is not None: expected_out = expected_out.encode("utf-8") expected_err = marker.kwargs.get("err", "") if expected_err is not None: expected_err = expected_err.encode("utf-8") with NamedTemporaryFile(mode="wb", suffix=".pyc") as fp: dump_code_to_file( compile(FunctionDefFinder(func).find(file), file, "exec"), fp.file) start = time.time() args[file_index] = fp.name out, err, status, _ = call_program(*args, env=env) end = time.time() excinfo = None if status != expected_status: excinfo = AssertionError( "Expected status %s, got %s.\n=== Captured STDERR ===\n%s=== End of captured STDERR ===" % (expected_status, status, err.decode("utf-8"))) elif expected_out is not None and out != expected_out: excinfo = AssertionError("STDOUT: Expected [%s] got [%s]" % (expected_out, out)) elif expected_err is not None and err != expected_err: excinfo = AssertionError("STDERR: Expected [%s] got [%s]" % (expected_err, err)) if PY2 and excinfo is not None: try: raise excinfo except Exception: excinfo = ExceptionInfo(sys.exc_info()) call_info_args = dict(result=None, excinfo=excinfo, start=start, stop=end, when="call") if not PY2: call_info_args["duration"] = end - start return TestReport.from_item_and_call(item, CallInfo(**call_info_args))